{"_id":"@creditkarma/thrift-client","_rev":"174-46f23cd9e05b31e0bbe3b0423e3f9e13","name":"@creditkarma/thrift-client","description":"Thrift client library for NodeJS written in TypeScript.","dist-tags":{"latest":"1.0.4","next":"1.1.0-alpha.1","fix":"0.6.35"},"versions":{"0.0.12":{"name":"@creditkarma/thrift-client","version":"0.0.12","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build; rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && tsc","clean":"rm -rf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated; thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.12","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.12","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.12","_shasum":"e95e00db68df6d1a59c08bc0a3da0ae4e2054db6","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"e95e00db68df6d1a59c08bc0a3da0ae4e2054db6","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.12.tgz","integrity":"sha512-7w2M2TDFAQOwW1XobaR9ETgYDr+mc3qAEVOT8vW1GlsmZeZotofQ8/E/G6eZxD2pdibH0pE2nNDqBsznPYd7eA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGl0qoYVH8xxl0q7RAZxXzEAvF6u+1qrS6XLMUIyLVDbAiEA0gBOq+LE5jcjInur7ooKpMV7H7iYZwxHTFdhlvMV7Ac="}]},"maintainers":[{"name":"nnanceck","email":"nick.nance@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.12.tgz_1508172762993_0.9317566510289907"}},"0.0.13":{"name":"@creditkarma/thrift-client","version":"0.0.13","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build && rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && tsc","clean":"rm -rf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.13","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.13","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.13","_shasum":"0cbaadf9ef0d0084b97b79be1ce26673781bd9ce","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"0cbaadf9ef0d0084b97b79be1ce26673781bd9ce","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.13.tgz","integrity":"sha512-Vp0necr0x42YMqySwaYBF+3jaCrs8aJKujEsg6wyh+YM0/PWLu1lc6d6ZVvc9+uDDGaTGH/8I8fBxQujTKv8Rw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEYE38NzajNm2pZGgn0J5ecYoi059BQc2I6tlhlHVNFgAiEA1OGmYNsGY2nuY8mQq48dRaum1N+IiMd0jm+2x/pJ3Bo="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.13.tgz_1508174454858_0.25292532285675406"}},"0.0.14":{"name":"@creditkarma/thrift-client","version":"0.0.14","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build && rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rm -rf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.14","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.14","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.14","_shasum":"aec4b16b6d273d89c1f03adf7882d42272ce3787","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"aec4b16b6d273d89c1f03adf7882d42272ce3787","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.14.tgz","integrity":"sha512-Ak+IKrToZjQ5Wqn8anTNvrLka9TalzBYLJD40UsMUH7jp3O8/4+Kaz40MMl/uFwA43qMOc3+znJAVA2rwv/smw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDkZOPWt4Kipu3+92bGMvKkeScBb0IvbdNvhjIYKY2lMAiEA/KFmdjcQF8wRWJ5OksJZrT8nhi+4EE/QheB3YiTyi/4="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.14.tgz_1508177590028_0.4710878152400255"}},"0.0.15":{"name":"@creditkarma/thrift-client","version":"0.0.15","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build && rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rm -rf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.15","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.15","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.15","_shasum":"8af992af2416971abd7ff391e7edb44aba7fc8f2","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"8af992af2416971abd7ff391e7edb44aba7fc8f2","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.15.tgz","integrity":"sha512-IUcAKCQ0tO7/WYsCwKikikntoPW2NSpwVkJXfNCRGYtknY30vmiE7FvcYd2X1OWagxr0gMFvE4Bv1KUknPx9kQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDJGOUw1il0D0HAowuzp4PaaGVlkNobX5x4x+uMX6LRegIgIlk3czQe7DyJWtzX19wYBfZCEBKkCg00BAsd4l3X4Eg="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.15.tgz_1508180973067_0.7851062980480492"}},"0.0.16":{"name":"@creditkarma/thrift-client","version":"0.0.16","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build && rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rm -rf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"npm publish --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.16","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.16","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.16","_shasum":"78aa7530974b34974128be6f381ee7cc34581a88","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"78aa7530974b34974128be6f381ee7cc34581a88","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.16.tgz","integrity":"sha512-rL6H2FIDlBSvCJkDrPxPGUycLTf0WH4oIKAM7E9fB5NniEqiW2tsxWBgxBbuFY7sfZOe62+saNIZ0jMDLyQh6Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA/YTZYZaNqGLsu6brvPC21Qiq5Y2E5yWzP2sNgm+i7LAiEA+zPVxGOi3V/CH2CZZBH5mbw1Oerq5IuFhyfYczpGr8s="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.16.tgz_1508181246719_0.682538466528058"}},"0.0.17":{"name":"@creditkarma/thrift-client","version":"0.0.17","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"npm publish --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.17","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.17","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.17","_shasum":"38599343ca2a2fc01822096c55faf2c55b1035f1","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"38599343ca2a2fc01822096c55faf2c55b1035f1","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.17.tgz","integrity":"sha512-VK13yGTAO05O3W9s8hKIzi3IrthR4SYAXAvKy/lodRkwuqto2sMTOC46UO7jq2oDKgCK+EBRDsAdf3vMyu+dHw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCXW+zVyVXO96zkvPDlBKLjECyNl8Y1inazBGmLFJrlfwIgJRkHXXr2fTEzYmcOmCnESTBTJ9A39/OcPYW5Bypx1DE="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.17.tgz_1508181746125_0.5945009181741625"}},"0.0.18":{"name":"@creditkarma/thrift-client","version":"0.0.18","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"ls . && npm publish --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.18","@types/thrift":"^0.10.1","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.18","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.18","_shasum":"7184b0cf7cb2a82b00988fbf7d05b0c843c9063a","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"7184b0cf7cb2a82b00988fbf7d05b0c843c9063a","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.18.tgz","integrity":"sha512-ghy9JQnLL2HMekbftaEl9GWW/yDcvb/OF3+RJNXQblWU5+ApppFET77Qyx/iAhQitL/IzBRBWTF8IFpz9czDuQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGfuvhPZsIlXiuqF9mYU3cjH2wBhEShIx0SZ+ROf6CMzAiBlz5BVLfLsZpkcqRspgQ3QS4ib4ziaZYCL2zccCcYmmQ=="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.18.tgz_1508182498003_0.6894491575658321"}},"0.0.19":{"name":"@creditkarma/thrift-client","version":"0.0.19","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"ls -a . && npm publish --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.19","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.19","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.19","_shasum":"1ea3161a7b6df80c924d52f60913843d75e9db42","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"1ea3161a7b6df80c924d52f60913843d75e9db42","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.19.tgz","integrity":"sha512-hdIRofobjfuyw/1Cp/kI/cGaXnQrNUMGDCeiXR9edmnIIE8tYIcn26BL/Y6JyyLZqDuMeueVR7Po6oUGfp9bvg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChZ3IAMKA2QphWpjda55zidD6nOAHTP/r8doMV5+X4igIgVR3Q0vtndl4fwtVmNJpQisWE/5HtL4lakVRqJAsnbvw="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.19.tgz_1508183111888_0.8528444084804505"}},"0.0.20":{"name":"@creditkarma/thrift-client","version":"0.0.20","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"ls -a ./dist && npm publish . --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.20","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.20","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.20","_shasum":"0fb04dca114bd7bddda516e720542d65a77a153c","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"0fb04dca114bd7bddda516e720542d65a77a153c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.20.tgz","integrity":"sha512-/dL+omocs/2fBJM0PP99I1hQpjzlyib38tLRvorW1hchX92NashDcnqCbHNndcZt/cmeG/vby0SC7dKmbjtVHA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/Vo3KgR5/hEsLMAmc2K7hxdOt0LQUsb+f4ue6ysTTiQIgAyDSlG92AEC+mVpFymvk8uDGbKUYgqoHkghqjGli2xs="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.20.tgz_1508184058217_0.2460573804564774"}},"0.0.21":{"name":"@creditkarma/thrift-client","version":"0.0.21","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist"],"directories":{"example":"example"},"scripts":{"prepublish":"rimraf ./dist/tests","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"ls -a ./dist/main && npm publish . --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.21","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.21","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.21","_shasum":"c2f8a4acdae8e349e77f1f9917610cc690879ae6","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"c2f8a4acdae8e349e77f1f9917610cc690879ae6","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.21.tgz","integrity":"sha512-FuJ8OgNBBSDjm3O7Zbx4UXmP2KFS6sSY9zoRWX5unmRptUPc/qwiEKNSjr2iZ4uTUeGLxxMohtc15DXUpofgjA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA1XBcD/MKCrwbEbZjHlc0bm8/IYOss3jeFozW9GOAqMAiB740sKbbGMy90uKyZfSig6Yovzo+7nRtt1//85EqEglw=="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.21.tgz_1508185432661_0.11342007992789149"}},"0.0.22":{"name":"@creditkarma/thrift-client","version":"0.0.22","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist/main"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release":"ls -a ./dist/main && npm publish . --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.22","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.22","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.22","_shasum":"9749e4c7014a08d4bf85c5dcfa084015950b7f2c","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"9749e4c7014a08d4bf85c5dcfa084015950b7f2c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.22.tgz","integrity":"sha512-QxXADLGFHncm/jh+4jmxKTV+yY9SUZtyhdLwawh4ndxIa/aP4TyQCLPDZhowRiDySw65CTrheB/5evHdsm368g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCzsphHOJS8krZUZoZzIAbM4ntmaSITc3Fy+Y+NH3SmQIgN+BXnmEWnJfxlRBFejLrrk86gwnDRCUtVMqZww2rZOU="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.22.tgz_1508186063093_0.18074794532731175"}},"0.0.23":{"name":"@creditkarma/thrift-client","version":"0.0.23","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist/main"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'","release:publish":"ls -a ./dist/main && npm publish . --access public"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.23","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.23","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.23","_shasum":"b9e810dcfef075faf73a1f0f8383b1d7d68c185d","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b9e810dcfef075faf73a1f0f8383b1d7d68c185d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.23.tgz","integrity":"sha512-UH8F+9/TB7rs1JmLHmu3MOTvFmUa091ZrPQJxFMsG0cSbOO83AAkFyAtjUaxAQEuwVm3ISlxAyUYezOi4sx9mw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCs5H5F/BgHH48+52uYY6nUrVJ+kxz3wOz1qMJ2bQR0xwIgXsflp68FeBtVRxJ0IDGZIGNhIz0nG7k2Akeqp7DvbcQ="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.23.tgz_1508187049398_0.5316821073647588"}},"0.0.24":{"name":"@creditkarma/thrift-client","version":"0.0.24","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist/main"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run build -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.24","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.24","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.24","_shasum":"30e8c0a21076f72366aead79cd637afef6518162","_from":"packages/thrift-client","_resolved":"file:packages/thrift-client","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"30e8c0a21076f72366aead79cd637afef6518162","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.24.tgz","integrity":"sha512-1+tBX8ch+cXYMyFZP79B0wcTXl9BhtTrMUG1zrkQTAJAkpOhekhgQGM1PnTYLQ2fc0Ljjj1A9gDTTE2zlPzR6w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFCGuuAc+k7SKzdmZ7ukWVwaVR2cHtEklj9M1AMoJfhLAiBniiaJCwTAKzrv/krgSEBgKXuBBCT6/65fbE7ZtTLhzw=="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.24.tgz_1508187696382_0.041019971715286374"}},"0.0.27":{"name":"@creditkarma/thrift-client","version":"0.0.27","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist/main"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run compile -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.27","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.27","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.27","_shasum":"4ac87429ff39936dc78216e66aeb037c13a1002d","_from":"packages/thrift-client","_resolved":"file:packages/thrift-client","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"4ac87429ff39936dc78216e66aeb037c13a1002d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.27.tgz","integrity":"sha512-4yNclmaZA6+nwnJMU4mBiqE+UmlAuoTIYDU6KZO6NH/ul0rstLxaOvc1uXs3zrdCZ3lNZch43xS4aG1FtGAKiA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCJPc65whM6IWMq6AZJLQZVyFAtLKPfYxq/rn550OpeBgIgPF9KDLdtPR1qYg9qwzi+B4kPbc6dAV1R+jExKL+LbYI="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.27.tgz_1508189113763_0.8446747118141502"}},"0.0.28":{"name":"@creditkarma/thrift-client","version":"0.0.28","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist/main"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run compile -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.28","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.28","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.28","_shasum":"168bd746113266b610d8c2dcf91302a175d543f4","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"168bd746113266b610d8c2dcf91302a175d543f4","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.28.tgz","integrity":"sha512-qw18u9J+ySBV53zcSTBstfSAZDaoXJETWOSjA1Cxb7xuGaaLz6JgKocntCrDk57FsNpNb9pbf/r/Quyqv7YSzQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDja+SlANG39qOdkLzmha6VM/hOx6KdkbvJV7VzphCzAAiAYrHOuHS32UkI4xygsA4RAoA7Pj1YWwi06jQZJLjuvyA=="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.28.tgz_1508193375599_0.1229760309215635"}},"0.0.30":{"name":"@creditkarma/thrift-client","version":"0.0.30","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["./dist/main"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build && ls .","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run compile -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.30","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.30","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.30","_shasum":"993a55b5006aeacc33e9ca1e5293841a1c4c77cd","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"993a55b5006aeacc33e9ca1e5293841a1c4c77cd","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.30.tgz","integrity":"sha512-AN8+p1ca7s4nu/66/xmfb/hJOdFZJiMz9CTGQGg8gnwWaGXldlA44JHpam+GcbrG/zjhsRVgJmkCiPcn1mOznw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC3zgu46HdM5//GsW42OlkBB7Grg3Fc3dKycp8KdpZ38gIhAIDyc4DWly/rxTlxu+Wk91wmAc66fWovw8BKmiiXK42K"}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.30.tgz_1508194653635_0.8058831668458879"}},"0.0.31":{"name":"@creditkarma/thrift-client","version":"0.0.31","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && npm run compile","compile":"tsc","clean":"rimraf ./dist","watch":"npm run compile -- --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.31","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.31","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.1","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.31","_shasum":"8e1428cd452fee27dad1897942917552de7dcda3","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"8e1428cd452fee27dad1897942917552de7dcda3","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.31.tgz","integrity":"sha512-AwsblCsz71Ey7hfmFdXOzXu0583FvSsAmgL+KtlL+ovOFK66MYRg7Wo1NLgMpCwcEtj13ViLSeX8yjfRQt7SNw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDR8jIF8fdviHMIMLw8KTte8nbCt0LJvM6M6FjGscjOigIgPoVWOwQWRpj4KP2rC1L9ItWNdKpIeL533gz+mPDiyiA="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.31.tgz_1508197718766_0.5830338259693235"}},"0.0.32":{"name":"@creditkarma/thrift-client","version":"0.0.32","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && tsc","clean":"rimraf ./dist","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.32","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.3","axios":"^0.16.2","request":"^2.83.0","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.32","@creditkarma/thrift-typescript":"^0.0.8","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.32","_shasum":"b9898c056a910db1a30e6f3d277663bca283a7e4","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b9898c056a910db1a30e6f3d277663bca283a7e4","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.32.tgz","integrity":"sha512-h1g2COintZx6STHGGYlxUiA/EA7FaRcpRZpa5mFrp/e+CsxeDaucH9XOR/I/uWbgTmAcBOQMhJzVTl6mvGWDvw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCu5FHERbLRkE7LeZiiy7R0WRB9+hgOhOznaLse4vIOZQIhAPa8J6vntWx+U5YEtW+Y4s8uiEWdPYXBeXgT3adx3LHl"}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.32.tgz_1508258915035_0.09077542135491967"}},"0.0.34":{"name":"@creditkarma/thrift-client","version":"0.0.34","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && tsc","clean":"rimraf ./dist","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.34","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.3","axios":"^0.16.2","request":"^2.83.0","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.34","@creditkarma/thrift-typescript":"^0.0.13","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.34","_shasum":"9a385f9e61dafebec94992b46518da480af70efd","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"9a385f9e61dafebec94992b46518da480af70efd","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.34.tgz","integrity":"sha512-Yb2C86ciK1+/B69MZ2wkKtoZYp3ICVT2dcb5FBids/56dwDpm8LZZcWDWFG3yji+oMJJRdgIQ71wbXCqCpzKIA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCDIfz3pfGZCnJsmn+NhK38aas+NFieiR3axr7/w/BG8wIgd9wo9UgFDTFzMc7sRa0QmOqpvh3rqEbQpjWagQsMb2g="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.34.tgz_1508453861256_0.672690941253677"}},"0.0.35":{"name":"@creditkarma/thrift-client","version":"0.0.35","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && tsc","clean":"rimraf ./dist","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.35","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.4","axios":"^0.16.2","request":"^2.83.0","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.35","@creditkarma/thrift-typescript":"^0.0.13","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.35","_shasum":"700eef56d1f394c26af8c23fa04882d7f6168e0b","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"700eef56d1f394c26af8c23fa04882d7f6168e0b","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.35.tgz","integrity":"sha512-XkEK+ydnauiZMDyaDJsJ2Drl76bMFKqpnjx+PQuB70vr069e40gETWAbxH4GzjUQaLE2hDTYBD8otQrHv4qmJQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC5e2EJjaelBDbYK8+ZkrEiDGhHfTksALtIyDC0cyURAAIgd8iGB/7vyGiyRmA1PKkT6j85j53dfNDHDhihOjIJ2uU="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.35.tgz_1508954054082_0.4618960153311491"}},"0.0.36":{"name":"@creditkarma/thrift-client","version":"0.0.36","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"prepublish":"npm run build","prebuild":"npm run test:codegen","build":"npm run clean && npm run lint && tsc","clean":"rimraf ./dist","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.36","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","@types/request":"^2.0.3","@types/thrift":"^0.10.4","axios":"^0.16.2","request":"^2.83.0","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.36","@creditkarma/thrift-typescript":"^0.0.15","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0"},"_id":"@creditkarma/thrift-client@0.0.36","_shasum":"7b76dc5f18f89e75a5bc3a629ae21176c95ce518","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"7b76dc5f18f89e75a5bc3a629ae21176c95ce518","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.36.tgz","integrity":"sha512-23+MUS9C6ombOT5IEf6MAvPnhffW/II/eWXuYiiNuJKL0IPAlT0EdXRvnq2qW2pd+u/eFAcEbWJvoBn8HJzmKA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG1bdqlSsixLg4GgD4lB94bqq8gNpQju2A+4U0/OFLBLAiEAoJSkU3ctZ9Vr5GGOmJ9dKDlYGa9ogMwloLEik3/YGGg="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.36.tgz_1509661588346_0.8139067234005779"}},"0.0.37":{"name":"@creditkarma/thrift-client","version":"0.0.37","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"clean":"rimraf ./dist","prepublish":"npm run build","build":"npm run clean && npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run test:codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:codegen":"rimraf ./src/tests/generated && thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S ./dist/**/*.spec.js","lint":"tslint --fix './src/**/*.ts'"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.0.37","@types/node":"^8.0.31","@types/request":"^2.0.8","@types/thrift":"^0.10.4","axios":"^0.16.2","request":"^2.83.0","thrift":"^0.10.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.0.37","@creditkarma/thrift-typescript":"^0.0.16","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.1"},"_id":"@creditkarma/thrift-client@0.0.37","_shasum":"708298672dd79c4819daf0715386493a1cc6c0df","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"708298672dd79c4819daf0715386493a1cc6c0df","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.0.37.tgz","integrity":"sha512-KchvQKsrwP45h53PLOYqp584o3S9zvCjBTyrFGAie2iZkU81zhE5SZgTKw/67MgmTDI6l4lPNYWRWjRo3/v6fg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDZYLQHyjwid50ILGQktY8j7dYnJVdXTFvZW57tILaplgIgGwKOojjsmfd0oics2Bdm2eT/L/iCtN7rtibJ0QfYbHA="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.0.37.tgz_1511897473541_0.8780416939407587"}},"0.1.1":{"name":"@creditkarma/thrift-client","version":"0.1.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S ./dist/**/*.spec.js"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.1.1","@types/request":"^2.0.8","axios":"^0.16.2","request":"^2.83.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.1.1","@creditkarma/thrift-typescript":"^1.0.0","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.1"},"_id":"@creditkarma/thrift-client@0.1.1","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-nqpduUVC40Np4Aldz4pISeuqJIQlzxHgoGCXU/vMSeHuPufPkXdKU36CkpNhJjR39hgJRCG1K051wxMmjmaX3Q==","shasum":"08e9fbfb4f81022975f0b5345d810b09e5f624d3","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.1.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCMeKH22EQEo8a21be3xlOQhGzAsDZdivEQJ1jYw5WJxQIhAKA3vOrJYNFD9wZj+5SeU7jA4/Cz5gH2GKPlK5e2WdTN"}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.1.1.tgz_1512518553734_0.3823257330805063"}},"0.1.2":{"name":"@creditkarma/thrift-client","version":"0.1.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S ./dist/**/*.spec.js"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"dependencies":{"@creditkarma/thrift-server-core":"^0.1.2","@types/request":"^2.0.8","axios":"^0.16.2","request":"^2.83.0"},"devDependencies":{"@creditkarma/thrift-server-hapi":"^0.1.2","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/node-int64":"^0.4.29","@types/q":"^1.0.5","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.1"},"_id":"@creditkarma/thrift-client@0.1.2","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-sjbUbk1bv5wzFllnaht4AyQLW9bWzJg1IxKcKxv7JKzuqH/a1EtgZpf3LtFZHu55IJM7HmytSuI4FNk2oo8NwA==","shasum":"43aa37a7f61a7f17dfaf958dd2d9fbd14be3c169","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.1.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIALGR3gNTNedk3G3J/Lt9WRDqrOzdjscwQTnqEtY3VSjAiAOzx17GP0zHHXgyICFWV78By4DPqZ6LN362EIYLzAxFA=="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.1.2.tgz_1512773022424_0.7042785598896444"}},"0.1.3":{"name":"@creditkarma/thrift-client","version":"0.1.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.1.3","@types/request":"^2.0.8"},"dependencies":{"axios":"^0.16.2","request":"^2.83.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.1.3","@creditkarma/thrift-server-hapi":"^0.1.3","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.0.8","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.1"},"_id":"@creditkarma/thrift-client@0.1.3","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-HLzDdt6WiI2+yOzkA2c4jLC3kdGxp5eAgtGkoFUUmmMIUsuewwGRXVtvY0zt1e9R7SXRaY3uUr/QfzV6TyMW2w==","shasum":"084128c4c64555876249e316d961cc10b865a91e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.1.3.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpWZySQCTiAwBaOXy43kM2ft+CfXHIU6/OikRXmPmtGAIhAPrLKY30X7ByQvdTGqn/H3srbMTUtBRdNe0OUMloeiJ7"}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.1.3.tgz_1513031650851_0.6517474332358688"}},"0.2.0":{"name":"@creditkarma/thrift-client","version":"0.2.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.2.0","@types/request":"^2.0.8"},"dependencies":{"axios":"^0.16.2","request":"^2.83.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.2.0","@creditkarma/thrift-server-hapi":"^0.2.0","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.0.8","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.1"},"_id":"@creditkarma/thrift-client@0.2.0","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-8FHQtm5vuXEv1L4vbj4boiekP0xN6P/8wuxk86wcxAG9MW68/Z4jDA9BI8ohHxBT4ayMQ2KfIVpsolP0qYY1oQ==","shasum":"63b7f631f69f138845532a5938ebd0907ebd84f8","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.2.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG1hLy0DDCWwgo91dG9uFCsud6h87r5RILfRl5c/1Vg0AiBFf+X5NtqdSjhpC8P4uG8akhPqU7pN9Hu8PvZV5C4bQw=="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.2.0.tgz_1513666485010_0.8515421110205352"}},"0.3.3":{"name":"@creditkarma/thrift-client","version":"0.3.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.3.3","@types/request":"^2.0.8"},"dependencies":{"axios":"^0.16.2","request":"^2.83.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.3.3","@creditkarma/thrift-server-hapi":"^0.3.3","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.0.8","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.1"},"_id":"@creditkarma/thrift-client@0.3.3","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-XDWWYC6o2MmFvQna7PBb1fsp4zCjjQSoWiBO2S7sPzPhqK5GVsjc3b7sChzCv3FjTJbKOkmvKlRwWK+IkK+ulg==","shasum":"906390607f73589856a8061599c949e1cad62177","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.3.3.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZPMjUIGCLWXMhuTz1d31jxl/MgA0PLrVv+cfEI8djKgIhAOxZ8n2L0O+o+nwDOM79q+T7anvitca8uCdeGCRSv25y"}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.3.3.tgz_1514919670598_0.8471208296250552"}},"0.3.5":{"name":"@creditkarma/thrift-client","version":"0.3.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.3.5","@types/request":"^2.0.8","axios":"^0.16.2","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.3.5","@creditkarma/thrift-server-core":"^0.3.5","@creditkarma/thrift-server-hapi":"^0.3.5","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.0.8","axios":"^0.16.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.2"},"_id":"@creditkarma/thrift-client@0.3.5","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-I0E1ZAmAA9HoWdWN4rchKD/XRfB63n/P1rN7XAxK8YWwNtENh1rP195WoN5L0t/XZFmEB3IpfUXbdY0ztBvVZw==","shasum":"0326fc6225b6545a840d05ffd7ceea4bbeb2dc62","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.3.5.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBdt6Egpwt64cDK44GMC9h9afmdJbuc+iGVXwsEAD37tAiEAj9Vo+Z+eHOchADO0DWB0iSguygu0NBdZHgc6yjyCh8M="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.3.5.tgz_1515718724594_0.0607849252410233"}},"0.3.6":{"name":"@creditkarma/thrift-client","version":"0.3.6","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.3.6","@types/request":"^2.0.8","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.3.6","@creditkarma/thrift-server-core":"^0.3.6","@creditkarma/thrift-server-hapi":"^0.3.6","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.0.8","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.2"},"_id":"@creditkarma/thrift-client@0.3.6","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-hMtmgNEOxA3wk1TDL1fAQVDEQnBUSYzkJK1v2rJErF73txJN7XeirNO9tXddNWiUMwCvD59DIetimWhZJA1y9Q==","shasum":"16bc29d9b4ff00577c5ac444ebb5306ee3b8db62","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.3.6.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDluw1RAMYmfYgmMtfrOaeAXRrtCIvDXRaw+UE91wwdDQIgN1G/vhnlM0yWJ6wWmqHTua/o9UgZ+QGRU//R1LRZ8iE="}]},"maintainers":[{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.3.6.tgz_1515785099939_0.1901804725639522"}},"0.4.0":{"name":"@creditkarma/thrift-client","version":"0.4.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prepublish":"npm run build","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.0","@types/request":"^2.0.8","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.4.0","@creditkarma/thrift-server-core":"^0.4.0","@creditkarma/thrift-server-hapi":"^0.4.0","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.0.8","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.2"},"_id":"@creditkarma/thrift-client@0.4.0","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-PsmZY8Oac6Ee993RWvnTyHi1tpjR2Pn+GlZdLCUcmqARcx5/WmdrQ6k+ABuaf1Y47YzsI4PsFuUcu54QgFXeeQ==","shasum":"fe3c093cf1388313b76df72330ef452e7241fc1e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.4.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+Zziauoo2+hg14xJPz0HqqPzHnsd3QutBRL5vrWSwMAIgJkvEfXjnbO593vUDHLjZf/T4aWZUHLd5xBhb58fB40I="}]},"maintainers":[{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.4.0.tgz_1516907400640_0.10618431447073817"}},"0.4.1":{"name":"@creditkarma/thrift-client","version":"0.4.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.1","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.4.1","@creditkarma/thrift-server-core":"^0.4.1","@creditkarma/thrift-server-hapi":"^0.4.1","@creditkarma/thrift-typescript":"^1.0.2","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.6.2"},"_id":"@creditkarma/thrift-client@0.4.1","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-PioSSNeG0SM5Z0ERt6XPuqSU5TN+5MEYawOUsNYiNtbDH1M9qsoHbEsiQ+flSgq11S9Pl9Ai3ZIcJ1s+5twEug==","shasum":"2d8346af9fa3e6603a0954c8b91195df4586fe91","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.4.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBFiL6pAu4RUzv5dZD0+F1l2vhzc5woJU545U53Rgy+9AiEApbg2kJNwGQ2jPP++Rw1fftaWYOGTT9C8yw99/zteo+Q="}]},"maintainers":[{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.4.1.tgz_1517374323799_0.8974290578626096"}},"0.4.2":{"name":"@creditkarma/thrift-client","version":"0.4.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.2","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.4.2","@creditkarma/thrift-server-core":"^0.4.2","@creditkarma/thrift-server-hapi":"^0.4.2","@creditkarma/thrift-typescript":"^1.1.0","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"_id":"@creditkarma/thrift-client@0.4.2","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-ChprI+I/tSorLrVwyjmU8uZCZ4o3vpzjOqgqawnnxu7VDGLRDVqOnWOdqFP5McCCUOrxOk/JNAssNu+Yp9UHnQ==","shasum":"51efe64e704b787825c2c9a8f3ff4e47474726a0","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.4.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBaBpfz1Zz2yiSokcw6IlMuGusGmMZFrslzpuwgyZ4ZjAiEA+Mnr/drVmFYHqYBcBqnNSAjw+OYz43Dc+/32Yp8Mru8="}]},"maintainers":[{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.4.2.tgz_1517520264246_0.6704372509848326"}},"0.4.3":{"name":"@creditkarma/thrift-client","version":"0.4.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.3","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.4.3","@creditkarma/thrift-server-core":"^0.4.3","@creditkarma/thrift-server-hapi":"^0.4.3","@creditkarma/thrift-typescript":"^1.1.4","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"_id":"@creditkarma/thrift-client@0.4.3","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-v8HXfxQ2MKE9VcOpMgGeb8bUr0oCtAbABGmG551JYct/xnjxzRKLt/GNYQaeLFRV+x2GMNQQANAntioytcvw5w==","shasum":"c9e8fa4139f7f6d7fb41512fd24d02fa24f82e46","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.4.3.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDbUBLlX6zKDAGwNsjine1fY58yLqH6ZfbFNcfOjIut8AIgKT7TefOqCHivQxyQMLnomWxw29zMKZyAxvtFzud3CXg="}]},"maintainers":[{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client-0.4.3.tgz_1517549468337_0.8153836720157415"}},"0.5.0-0":{"name":"@creditkarma/thrift-client","version":"0.5.0-0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/dynamic-config":"^0.4.3","@creditkarma/thrift-server-core":"^0.4.3","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.5.0-0","@creditkarma/thrift-server-core":"^0.5.0-0","@creditkarma/thrift-server-hapi":"^0.5.0-0","@creditkarma/thrift-typescript":"next","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.7.x"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Running the Sample Application\n\n```sh\n$ npm install\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries defined most things as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createClient`\n\nUsing the `createClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n  RequestInstance,\n  RequestConnection,\n  IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n  hostName: 'localhost',\n  port: 3000,\n  path: '/',\n  transport: 'buffered',\n  protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: RequestConnection =\n  new RequestConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `RequestConnection` is a class that extends the `HttpConnection` abstract class. Later we will look closer at creating this class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to Request here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<CoreOptions>`. This type parameter refers to the type of the context, here the `CoreOptions` interface from the Request library.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n  hostName: 'localhost',\n  port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n  // Request contexts allow you to do tracing and auth\n  const context: CoreOptions = {\n    headers: {\n      'X-Trace-Id': 'my-trace-id'\n    }\n  }\n\n  // Client methods return a Promise of the expected result\n  thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n    res.send(result)\n  }, (err: any) => {\n    res.status(500).send(err)\n  })\n})\n\napp.listen(serverConfig.port, () => {\n  console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify responses, or you'll want to universally add certain headers to outgoing client requests. You can do these things with middleware.\n\nA middleware is an object that consists of a handler function, the type of middleware and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IIncomingMiddleware {\n  type: 'incoming'\n  methods: Array<string>\n  hander(data: Buffer): Promise<Buffer>\n}\n\ninterface IOutgoingMiddleware<Context> {\n  type: 'outgoing'\n  mthods: Array<string>\n  handler(context: Context): Promise<Context>\n}\n```\n\n#### Incoming Middleware\n\n`incoming` middleware acts on responses coming into the client. The middleware receives the response before the Thrift processor so the data is a raw `Buffer` object. The middleware returns a `Promise` of data that will continue down the middleware chain to the Thrift processor. If the `Promise` is rejected the chain is broken and the client method call is rejected.\n\n`incoming` is the default middleware, so if the `type` property is ommited the middleware will be assumed to be incoming.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  register: [{\n    type: 'incoming',\n    handler(data: Buffer): Promise<Buffer> {\n      if (validatePayload(data)) {\n        return Promise.resolve(data)\n      } else {\n        return Promise.reject(new Error('Payload of thrift response is invalid'))\n      }\n    },\n  }]\n})\n```\n\n#### Outgoing Middleware\n\n`outgoing` middleware acts on the outgoing request. The middleware handler function operates on the request `context`. The context is of type `CoreOptions` when using Request. Changes to the context are applied before any context is passed to a client method. Therefore the context passed to a client method will have priority over the middleware handler.\n\nHere, the `X-Fake-Token` will be added to every outgoing client method call:\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  register: [{\n    type: 'outgoing',\n    handler(context: CoreOptions): Promise<CoreOptions> {\n      return Promise.resolve(Object.assign({}, context, {\n        headers: {\n          'X-Fake-Token': 'fake-token',\n        },\n      }))\n    },\n  }]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: RequestConnection =\n  new RequestConnection(requestClient, clientConfig)\n\nconnection.register({\n  type: 'outgoing',\n  handler(context: CoreOptions): Promise<CoreOptions> {\n    return Promise.resolve(Object.assign({}, context, {\n      headers: {\n        'X-Fake-Token': 'fake-token',\n      },\n    }))\n  },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n## Creating Custom Connections\n\nWhile Thrift Client includes support Request using another Http client library should be easy. You need to extend the abstract HttpConnection class and implement the abstract write method.\n\nAs an example look at the RequestConnection:\n\n```typescript\nexport class RequestConnection extends HttpConnection<CoreOptions> {\n  private request: RequestAPI<Request, CoreOptions, OptionalUriUrl>\n\n  constructor(requestApi: RequestInstance, options: IHttpConnectionOptions) {\n    super(options)\n    this.request = requestApi.defaults({\n      // Encoding needs to be explicitly set to null or the response body will be a string\n      encoding: null,\n      url: `${this.protocol}://${this.hostName}:${this.port}${this.path}`,\n    })\n  }\n\n  public emptyContext(): CoreOptions {\n    return {}\n  }\n\n  public write(dataToWrite: Buffer, context: request.CoreOptions = {}): Promise<Buffer> {\n    // Merge user options with required options\n    const requestOptions: request.CoreOptions = deepMerge(context, {\n      body: dataToWrite,\n      headers: {\n        'content-length': dataToWrite.length,\n        'content-type': 'application/octet-stream',\n      },\n    })\n\n    return new Promise((resolve, reject) => {\n      this.request.post(requestOptions, (err: any, response: RequestResponse, body: Buffer) => {\n        if (err !== null) {\n          reject(err)\n        } else if (response.statusCode && (response.statusCode < 200 || response.statusCode > 299)) {\n          reject(new Error(body.toString()))\n        } else {\n          resolve(body)\n        }\n      })\n    })\n  }\n}\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.5.0-0","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-jwp28LlSm6pY8f8Y+8nsyhlWFV7nhfiq+4vTHkqwOfg9lVyhGDuRStWxc/dv+5BgAQ+f4qixGaOPmeXjQ823bw==","shasum":"ff6e5d20cf9294f47db901fcc1c592a592920a4b","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.5.0-0.tgz","fileCount":22,"unpackedSize":47442,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDayfIYUbBYeHx+8NO8h923lB0g7Io1uCEHPvxiu9/2DgIgL7oprt53G4AwuLNI/PUy1vFhGE8/HxnVnMEpubL/S/Q="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.5.0-0_1519174181609_0.6756328934583262"},"_hasShrinkwrap":false},"0.5.0-1":{"name":"@creditkarma/thrift-client","version":"0.5.0-1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.3","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.4.3","@creditkarma/thrift-server-core":"^0.5.0-1","@creditkarma/thrift-server-hapi":"^0.5.0-1","@creditkarma/thrift-typescript":"next","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"^2.7.x"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Running the Sample Application\n\n```sh\n$ npm install\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries defined most things as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createClient`\n\nUsing the `createClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n  RequestInstance,\n  RequestConnection,\n  IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n  hostName: 'localhost',\n  port: 3000,\n  path: '/',\n  transport: 'buffered',\n  protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: RequestConnection =\n  new RequestConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `RequestConnection` is a class that extends the `HttpConnection` abstract class. Later we will look closer at creating this class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to Request here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<CoreOptions>`. This type parameter refers to the type of the context, here the `CoreOptions` interface from the Request library.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n  hostName: 'localhost',\n  port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n  // Request contexts allow you to do tracing and auth\n  const context: CoreOptions = {\n    headers: {\n      'X-Trace-Id': 'my-trace-id'\n    }\n  }\n\n  // Client methods return a Promise of the expected result\n  thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n    res.send(result)\n  }, (err: any) => {\n    res.status(500).send(err)\n  })\n})\n\napp.listen(serverConfig.port, () => {\n  console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify responses, or you'll want to universally add certain headers to outgoing client requests. You can do these things with middleware.\n\nA middleware is an object that consists of a handler function, the type of middleware and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IIncomingMiddleware {\n  type: 'incoming'\n  methods: Array<string>\n  hander(data: Buffer): Promise<Buffer>\n}\n\ninterface IOutgoingMiddleware<Context> {\n  type: 'outgoing'\n  mthods: Array<string>\n  handler(context: Context): Promise<Context>\n}\n```\n\n#### Incoming Middleware\n\n`incoming` middleware acts on responses coming into the client. The middleware receives the response before the Thrift processor so the data is a raw `Buffer` object. The middleware returns a `Promise` of data that will continue down the middleware chain to the Thrift processor. If the `Promise` is rejected the chain is broken and the client method call is rejected.\n\n`incoming` is the default middleware, so if the `type` property is ommited the middleware will be assumed to be incoming.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  register: [{\n    type: 'incoming',\n    handler(data: Buffer): Promise<Buffer> {\n      if (validatePayload(data)) {\n        return Promise.resolve(data)\n      } else {\n        return Promise.reject(new Error('Payload of thrift response is invalid'))\n      }\n    },\n  }]\n})\n```\n\n#### Outgoing Middleware\n\n`outgoing` middleware acts on the outgoing request. The middleware handler function operates on the request `context`. The context is of type `CoreOptions` when using Request. Changes to the context are applied before any context is passed to a client method. Therefore the context passed to a client method will have priority over the middleware handler.\n\nHere, the `X-Fake-Token` will be added to every outgoing client method call:\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  register: [{\n    type: 'outgoing',\n    handler(context: CoreOptions): Promise<CoreOptions> {\n      return Promise.resolve(Object.assign({}, context, {\n        headers: {\n          'X-Fake-Token': 'fake-token',\n        },\n      }))\n    },\n  }]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: RequestConnection =\n  new RequestConnection(requestClient, clientConfig)\n\nconnection.register({\n  type: 'outgoing',\n  handler(context: CoreOptions): Promise<CoreOptions> {\n    return Promise.resolve(Object.assign({}, context, {\n      headers: {\n        'X-Fake-Token': 'fake-token',\n      },\n    }))\n  },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n## Creating Custom Connections\n\nWhile Thrift Client includes support Request using another Http client library should be easy. You need to extend the abstract HttpConnection class and implement the abstract write method.\n\nAs an example look at the RequestConnection:\n\n```typescript\nexport class RequestConnection extends HttpConnection<CoreOptions> {\n  private request: RequestAPI<Request, CoreOptions, OptionalUriUrl>\n\n  constructor(requestApi: RequestInstance, options: IHttpConnectionOptions) {\n    super(options)\n    this.request = requestApi.defaults({\n      // Encoding needs to be explicitly set to null or the response body will be a string\n      encoding: null,\n      url: `${this.protocol}://${this.hostName}:${this.port}${this.path}`,\n    })\n  }\n\n  public emptyContext(): CoreOptions {\n    return {}\n  }\n\n  public write(dataToWrite: Buffer, context: request.CoreOptions = {}): Promise<Buffer> {\n    // Merge user options with required options\n    const requestOptions: request.CoreOptions = deepMerge(context, {\n      body: dataToWrite,\n      headers: {\n        'content-length': dataToWrite.length,\n        'content-type': 'application/octet-stream',\n      },\n    })\n\n    return new Promise((resolve, reject) => {\n      this.request.post(requestOptions, (err: any, response: RequestResponse, body: Buffer) => {\n        if (err !== null) {\n          reject(err)\n        } else if (response.statusCode && (response.statusCode < 200 || response.statusCode > 299)) {\n          reject(new Error(body.toString()))\n        } else {\n          resolve(body)\n        }\n      })\n    })\n  }\n}\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.5.0-1","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-bp1jg0BljZFR7KP3z8PBTG0buzYd8OdDT4hCEwTrPC1smdoSboBJocXfDjOPHEHxOUNeByEPNNpiqam9MuRvdA==","shasum":"aaa6b0802dee4a71866df9c98385193e7ebc9f39","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.5.0-1.tgz","fileCount":22,"unpackedSize":47395,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCn/T1X+4xLmzF+laKFDWfUAGCwxsyLmYF8we1aGFY/8gIgHEG7ajyyhXg55jTJCraaS81HGvgwwxR8I9/qlAIKq3o="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.5.0-1_1519251525336_0.9328336682806062"},"_hasShrinkwrap":false},"0.5.0":{"name":"@creditkarma/thrift-client","version":"0.5.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.3","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.5.0","@creditkarma/thrift-server-express":"^0.5.0","@creditkarma/thrift-server-hapi":"^0.5.0","@creditkarma/thrift-typescript":"~1.1.4","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.11.2"},"_id":"@creditkarma/thrift-client@0.5.0","_shasum":"eda1c6a7777606c3baedab74c0f2311dc157e295","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"eda1c6a7777606c3baedab74c0f2311dc157e295","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.5.0.tgz","fileCount":25,"unpackedSize":53744,"integrity":"sha512-YPn7AiZzmb2nYXY/687X9VdKrvcvNDGRI3IRHgRw3XUs+hYNCVtmhGuW7UhOkOdgzUB4x7cSCwMx9HYQkQbdVQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGBxbb7Uz/z6l5Fbanu6yltq1+MYRU2AEUU1Yl0ER8fuAiBIKl+Dn/nDqZDip6biY6hU6ZfxHs42TjcBeMoi5HI79g=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.5.0_1520888279598_0.9448347877345515"},"_hasShrinkwrap":false},"0.5.1":{"name":"@creditkarma/thrift-client","version":"0.5.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.5.0","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.5.1","@creditkarma/thrift-server-express":"^0.5.1","@creditkarma/thrift-server-hapi":"^0.5.1","@creditkarma/thrift-typescript":"~1.1.4","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.11.2"},"_id":"@creditkarma/thrift-client@0.5.1","_shasum":"beb644448dda11ebe27799ae8875046bd52d7032","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"beb644448dda11ebe27799ae8875046bd52d7032","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.5.1.tgz","fileCount":25,"unpackedSize":54049,"integrity":"sha512-20qK4d2ESplx0MzO5J9j7W7p0UybdHOVNjV6EmC7rkieOdREylQUpoh3+2aiQCowe+sXXHTS/P+UmwV19npXWw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGTGJg5KtH9xyM6kurrUUixQL7zkuSQLDOlPLRlRDLWAAiABfaReHQw6Ho/wLyLdDTzL44zYfAOxg2uOge69MNygXA=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.5.1_1520893259173_0.74084374561904"},"_hasShrinkwrap":false},"0.6.0":{"name":"@creditkarma/thrift-client","version":"0.6.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.5.0","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.0","@creditkarma/thrift-server-express":"^0.6.0","@creditkarma/thrift-server-hapi":"^0.6.0","@creditkarma/thrift-typescript":"~1.1.4","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.11.2"},"_id":"@creditkarma/thrift-client@0.6.0","_shasum":"8ac32b41ebbab779f356a501fc79a35f89b59528","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"8ac32b41ebbab779f356a501fc79a35f89b59528","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.0.tgz","fileCount":25,"unpackedSize":54521,"integrity":"sha512-TSKfMhJCz9HL8SX1W53G9ZI3H8g+NjYqwVN0413qXBV6zZJga/K3GWsUCJHs3nb5EzCRPM4pVGHUbnYcJ56Q3A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAxmYwHzthrBZVHhY/tLdB63PmeESF5XJYHk3gS8v11lAiEA2OpiO3HjBGLyNfhrJGgzqUFo/xYQkUJBAM1mfK/NWb0="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.0_1520963038775_0.2549149451127519"},"_hasShrinkwrap":false},"0.6.1":{"name":"@creditkarma/thrift-client","version":"0.6.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.5.0","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.1","@creditkarma/thrift-server-express":"^0.6.1","@creditkarma/thrift-server-hapi":"^0.6.1","@creditkarma/thrift-typescript":"~1.1.4","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.11.2"},"_id":"@creditkarma/thrift-client@0.6.1","_shasum":"b3034f92a4dd835817f1f8304530eea4f7557562","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b3034f92a4dd835817f1f8304530eea4f7557562","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.1.tgz","fileCount":25,"unpackedSize":54743,"integrity":"sha512-WD2hOuR6a7KwKSlh5RaiIb7FU/FZIRnScxHwaeZ5ExZPfNxHTMri5mbH7RyREJvAVugeRAsrY3dbIR8jhPKmtw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCKofaJILBuHqBOnw2F5pOpTztPb9B/Elkmwpn2lD46HQIgJ5baqIVjKgusddRVgyBDWC8iDgI6+xwLVaNf1ItyUJA="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.1_1520964145217_0.43506344229954186"},"_hasShrinkwrap":false},"0.6.2":{"name":"@creditkarma/thrift-client","version":"0.6.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.2","@creditkarma/thrift-server-express":"^0.6.2","@creditkarma/thrift-server-hapi":"^0.6.2","@creditkarma/thrift-typescript":"~1.1.4","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.11.2"},"_id":"@creditkarma/thrift-client@0.6.2","_shasum":"0cfafbd6c5f45fa82f38ff9a33b98d425bd593ca","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"0cfafbd6c5f45fa82f38ff9a33b98d425bd593ca","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.2.tgz","fileCount":25,"unpackedSize":55046,"integrity":"sha512-uwbfJs5ELb8V67ws+mKZaytGxIyU3iFRqDNuULDlNqr0+216oUEuYIsIq1xjw2BxLBauBkKvt5nzqWwufGZkLA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICXnXvKLiotoNDLpSTp4oQjSrZyHuve1JyIEJcf6z9ghAiEAzYb8KoeF0zZ2Mjxg79frXVy9x/ouTFc7BTs2dKqnv7U="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.2_1520970949284_0.3683716021888954"},"_hasShrinkwrap":false},"0.6.3":{"name":"@creditkarma/thrift-client","version":"0.6.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.3","@creditkarma/thrift-server-express":"^0.6.3","@creditkarma/thrift-server-hapi":"^0.6.3","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.11.2"},"_id":"@creditkarma/thrift-client@0.6.3","_shasum":"16f2f7fd071ac9832cfd02dd1617d2ff0257c39d","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"16f2f7fd071ac9832cfd02dd1617d2ff0257c39d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.3.tgz","fileCount":25,"unpackedSize":55913,"integrity":"sha512-L1pZxhNdyAmSNbAAL2G9IZLpY2sdnu5MTDU88MmFFNy7V7ntNJLXR+5znSpXgTP1SEOIElf/6SnsVPyCoyCjnA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBS6uLCLHLpw58RGjBMBpgnjk6OmK1DNKOiobk3qar2GAiEA9ofDExBkDSwPC4Gtbp/S45IsPzKTfzj6twB3NSMN1Tg="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.3_1521479063412_0.6218183781542741"},"_hasShrinkwrap":false},"0.6.4":{"name":"@creditkarma/thrift-client","version":"0.6.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.4","@creditkarma/thrift-server-express":"^0.6.4","@creditkarma/thrift-server-hapi":"^0.6.4","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.4","_shasum":"464cd940e39f6350b6f8a8a205d2d7b899d38c4d","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"464cd940e39f6350b6f8a8a205d2d7b899d38c4d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.4.tgz","fileCount":25,"unpackedSize":55972,"integrity":"sha512-JLTTEfnYEtXdYBCdiD8HWJhrutxc72alsbZ321YM5SAaP1ckMX+EYO9Oj4jjhAyT9yRStXycBhbmGRP6HXIdcQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDe+wbOapiUYst4Q9BdvJpM0Zd7V4QuPEmnuWbCGUCm8QIgF0bDkzrc/l17/vGkM3ONxWxr163Oxav2UgaUh6dfEOE="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.4_1521572370770_0.2283481176544715"},"_hasShrinkwrap":false},"0.6.5-2":{"name":"@creditkarma/thrift-client","version":"0.6.5-2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.5-2","@creditkarma/thrift-server-express":"^0.6.5-2","@creditkarma/thrift-server-hapi":"^0.6.5-2","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'X-Trace-Id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'X-Fake-Token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `X-Fake-Token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.5-2","_shasum":"fefa1472f95b15fc8690d002f3ee41df35b4f7ea","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"fefa1472f95b15fc8690d002f3ee41df35b4f7ea","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.5-2.tgz","fileCount":25,"unpackedSize":56007,"integrity":"sha512-MyWBj8lwFmkjHnjkOCSImknhV0cPIOI5YTOL8zzqt/WbvSSwcq4rYn/YnwoBcIFYU73CEnFCaR7UBCiRYD//0A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEVqat2ZPgET+XpVK0n8WZJcZ/cKipA/TWD731/adpxHAiBgtntprXYnQlahZWbxjsZO/Xe7EN9gwHwKbFNGiGeOMQ=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.5-2_1521578394675_0.2714634581368913"},"_hasShrinkwrap":false},"0.6.5":{"name":"@creditkarma/thrift-client","version":"0.6.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.5","@creditkarma/thrift-server-express":"^0.6.5","@creditkarma/thrift-server-hapi":"^0.6.5","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.5","_shasum":"2710d732dbd195447fdb21c1bf807198a8fa9e02","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"2710d732dbd195447fdb21c1bf807198a8fa9e02","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.5.tgz","fileCount":25,"unpackedSize":57104,"integrity":"sha512-bK/6OrzHOWFnq82O4jKvRJa+tw6vtd8L65XE88ykR9Xoo+VzsT1lGUK0w2k+1S1chW99uSi8wf/OfTgo4qazSg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCckLeFJ/Hz+iSvAMa4peQZtJW20YMzw/Lzz6uy1Mwa2gIgVbUbCfaY2n805fvZbb7cWtyseWK75nuAQXSur0Hm6qM="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.5_1521653757111_0.33210158748612306"},"_hasShrinkwrap":false},"0.6.6-0":{"name":"@creditkarma/thrift-client","version":"0.6.6-0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.6-0","@creditkarma/thrift-server-express":"^0.6.6-0","@creditkarma/thrift-server-hapi":"^0.6.6-0","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.5.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"@types/request":"^2.47.0","async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'X-Trace-Id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'X-Fake-Token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `X-Fake-Token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.6-0","_shasum":"8bbc482dee31be46ffbf659e38c863abf651c686","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"8bbc482dee31be46ffbf659e38c863abf651c686","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.6-0.tgz","fileCount":25,"unpackedSize":57081,"integrity":"sha512-lW/ZdaFkTCGmfIQStM+PCMBZ+0lVOIcDWXgXoxFQekFsNSNI21AXTI3THqoNd0qHMDItQREEaPOF4oXG7Qes8A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCu0sqMN2VtDBOaCOBp8NKlMZL4/OJibzBd675ZK9SnkAIhAMuUPIc4tl2Ta4OUceR6+bFB7v5ePdfOP5fPZrBsFI7X"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.6-0_1521666327772_0.6370481714267735"},"_hasShrinkwrap":false},"0.6.6-1":{"name":"@creditkarma/thrift-client","version":"0.6.6-1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.6-1","@creditkarma/thrift-server-express":"^0.6.6-1","@creditkarma/thrift-server-hapi":"^0.6.6-1","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'X-Trace-Id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'X-Fake-Token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `X-Fake-Token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.6-1","_shasum":"5f35543bf56ffef9173d396f4b42b665e2405e4a","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"5f35543bf56ffef9173d396f4b42b665e2405e4a","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.6-1.tgz","fileCount":25,"unpackedSize":57112,"integrity":"sha512-LEgdGsTucs7iT6IUkjxXB6ZyBbb+o7nlAmp7uM728rzrlLvHlS1RGHS1197eYtFwQkFVRKcMmCA1zE3pcsRt3w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEIHvv7eEfNqAIOWIclCAkjiaBtz7/I2aZ59d+/s+07qAiEAnbXHw4eL48qfV4KR57y6pKoxsQwZ8C4jkDKGRQ1QE78="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.6-1_1522187931082_0.1607292333053736"},"_hasShrinkwrap":false},"0.6.6":{"name":"@creditkarma/thrift-client","version":"0.6.6","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.6","@creditkarma/thrift-server-express":"^0.6.6","@creditkarma/thrift-server-hapi":"^0.6.6","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.6","_shasum":"d2dd2e193c3d51fb324ef903eec873d71288430a","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"d2dd2e193c3d51fb324ef903eec873d71288430a","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.6.tgz","fileCount":25,"unpackedSize":57104,"integrity":"sha512-w+F9xbD3Y1Sj+7i293FdPn482kfdCS5Vg/hR4wd0dQZjaHBC/b4vhmbF9qvzuHfiPhtKMt3xi9j9IZCwdLwOWw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDqpX6QFl3q2bjZMISREeaW2dXBFn+ZaJ+TtU5wOL13VAIgBJV2PxFg4D8KHFpXwJ0a6s2EEIOPakZtC2qxb5DkGW4="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.6_1522257268425_0.7822978011975881"},"_hasShrinkwrap":false},"0.4.5":{"name":"@creditkarma/thrift-client","version":"0.4.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["Thrift","TypeScript","RPC"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"^0.4.5","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"^0.4.5","@creditkarma/thrift-server-core":"^0.4.5","@creditkarma/thrift-server-hapi":"^0.4.5","@creditkarma/thrift-typescript":"^1.1.4","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.7.x"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Running the Sample Application\n\n```sh\n$ npm install\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries defined most things as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createClient`\n\nUsing the `createClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n  RequestInstance,\n  RequestConnection,\n  IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n  hostName: 'localhost',\n  port: 3000,\n  path: '/',\n  transport: 'buffered',\n  protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: RequestConnection =\n  new RequestConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `RequestConnection` is a class that extends the `HttpConnection` abstract class. Later we will look closer at creating this class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to Request here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<CoreOptions>`. This type parameter refers to the type of the context, here the `CoreOptions` interface from the Request library.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n  hostName: 'localhost',\n  port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n  // Request contexts allow you to do tracing and auth\n  const context: CoreOptions = {\n    headers: {\n      'X-Trace-Id': 'my-trace-id'\n    }\n  }\n\n  // Client methods return a Promise of the expected result\n  thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n    res.send(result)\n  }, (err: any) => {\n    res.status(500).send(err)\n  })\n})\n\napp.listen(serverConfig.port, () => {\n  console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify responses, or you'll want to universally add certain headers to outgoing client requests. You can do these things with middleware.\n\nA middleware is an object that consists of a handler function, the type of middleware and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IIncomingMiddleware {\n  type: 'incoming'\n  methods: Array<string>\n  hander(data: Buffer): Promise<Buffer>\n}\n\ninterface IOutgoingMiddleware<Context> {\n  type: 'outgoing'\n  mthods: Array<string>\n  handler(context: Context): Promise<Context>\n}\n```\n\n#### Incoming Middleware\n\n`incoming` middleware acts on responses coming into the client. The middleware receives the response before the Thrift processor so the data is a raw `Buffer` object. The middleware returns a `Promise` of data that will continue down the middleware chain to the Thrift processor. If the `Promise` is rejected the chain is broken and the client method call is rejected.\n\n`incoming` is the default middleware, so if the `type` property is ommited the middleware will be assumed to be incoming.\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  register: [{\n    type: 'incoming',\n    handler(data: Buffer): Promise<Buffer> {\n      if (validatePayload(data)) {\n        return Promise.resolve(data)\n      } else {\n        return Promise.reject(new Error('Payload of thrift response is invalid'))\n      }\n    },\n  }]\n})\n```\n\n#### Outgoing Middleware\n\n`outgoing` middleware acts on the outgoing request. The middleware handler function operates on the request `context`. The context is of type `CoreOptions` when using Request. Changes to the context are applied before any context is passed to a client method. Therefore the context passed to a client method will have priority over the middleware handler.\n\nHere, the `X-Fake-Token` will be added to every outgoing client method call:\n\n```typescript\nimport {\n  createClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createClient(Calculator.Client, {\n  hostName: 'localhost',\n  port: 8080,\n  register: [{\n    type: 'outgoing',\n    handler(context: CoreOptions): Promise<CoreOptions> {\n      return Promise.resolve(Object.assign({}, context, {\n        headers: {\n          'X-Fake-Token': 'fake-token',\n        },\n      }))\n    },\n  }]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: RequestConnection =\n  new RequestConnection(requestClient, clientConfig)\n\nconnection.register({\n  type: 'outgoing',\n  handler(context: CoreOptions): Promise<CoreOptions> {\n    return Promise.resolve(Object.assign({}, context, {\n      headers: {\n        'X-Fake-Token': 'fake-token',\n      },\n    }))\n  },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n## Creating Custom Connections\n\nWhile Thrift Client includes support Request using another Http client library should be easy. You need to extend the abstract HttpConnection class and implement the abstract write method.\n\nAs an example look at the RequestConnection:\n\n```typescript\nexport class RequestConnection extends HttpConnection<CoreOptions> {\n  private request: RequestAPI<Request, CoreOptions, OptionalUriUrl>\n\n  constructor(requestApi: RequestInstance, options: IHttpConnectionOptions) {\n    super(options)\n    this.request = requestApi.defaults({\n      // Encoding needs to be explicitly set to null or the response body will be a string\n      encoding: null,\n      url: `${this.protocol}://${this.hostName}:${this.port}${this.path}`,\n    })\n  }\n\n  public emptyContext(): CoreOptions {\n    return {}\n  }\n\n  public write(dataToWrite: Buffer, context: request.CoreOptions = {}): Promise<Buffer> {\n    // Merge user options with required options\n    const requestOptions: request.CoreOptions = deepMerge(context, {\n      body: dataToWrite,\n      headers: {\n        'content-length': dataToWrite.length,\n        'content-type': 'application/octet-stream',\n      },\n    })\n\n    return new Promise((resolve, reject) => {\n      this.request.post(requestOptions, (err: any, response: RequestResponse, body: Buffer) => {\n        if (err !== null) {\n          reject(err)\n        } else if (response.statusCode && (response.statusCode < 200 || response.statusCode > 299)) {\n          reject(new Error(body.toString()))\n        } else {\n          resolve(body)\n        }\n      })\n    })\n  }\n}\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.4.5","_npmVersion":"5.4.2","_nodeVersion":"6.1.0","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"integrity":"sha512-s7Zx4rZ9p2C6WqwKXEJzMEull8Nns4RfQi9zP26TgcZP/vjGIPRHjIAw9tC5U2BrQfcKFromFNaUOjrlh8GWPA==","shasum":"b3dc5edef90ea5b566830f1cf29e3372560a721c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.4.5.tgz","fileCount":22,"unpackedSize":47369,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF5QKOx37Ts7DF+6Cbeq3hnsDGD+eRDVwFfog1qKFEowAiAgjvu7ZKiMn03gfB8WOpFOx+HL5j8MlnKhUFW8GIewQQ=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.4.5_1522343216666_0.29556612165863183"},"_hasShrinkwrap":false},"0.7.0-0":{"name":"@creditkarma/thrift-client","version":"0.7.0-0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --strictUnions true --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.7.0-0","@creditkarma/thrift-server-express":"^0.7.0-0","@creditkarma/thrift-server-hapi":"^0.7.0-0","@creditkarma/thrift-typescript":"2.0.0-5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'X-Trace-Id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'X-Fake-Token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `X-Fake-Token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.7.0-0","_shasum":"8e789849599603e4529d883c73a32818ca26b5d2","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"8e789849599603e4529d883c73a32818ca26b5d2","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.0-0.tgz","fileCount":25,"unpackedSize":56516,"integrity":"sha512-YFGcEp/QZoxk3OPCJTHuEDAO5kxI2f7ygvpAxjUXYPbmOmUZ6CiWKr8ltmY4SgXqi0WKtxDEydZ0dMSg4pJThw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCsMAxebaxjNdhDazrRGgRQHuKxUuR15CHQR0pUt5qd3QIhAOpFVMkknJ7EjCXZMyqIPz7oSWBT+CrM7XAxOuFrND+n"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.0-0_1522943089660_0.2659151292580386"},"_hasShrinkwrap":false},"0.7.0-1":{"name":"@creditkarma/thrift-client","version":"0.7.0-1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --strictUnions true --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"next","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.7.0-1","@creditkarma/thrift-server-express":"^0.7.0-1","@creditkarma/thrift-server-hapi":"^0.7.0-1","@creditkarma/thrift-typescript":"2.0.0-5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'X-Trace-Id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'X-Fake-Token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `X-Fake-Token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.7.0-1","_shasum":"df5a2311afbe1650b207de5de3ed02f991a5f5a6","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"df5a2311afbe1650b207de5de3ed02f991a5f5a6","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.0-1.tgz","fileCount":25,"unpackedSize":56515,"integrity":"sha512-wAOc6IHy8k+uWyRWBXWLEC6zGcBew8zeXXBUaaFkQ4kz80nePYeGOEQUKi7TBRbhGNcOVdY6XdTDqvNNScKCJw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCD/Q0VbQBzMHR16G99axhbZJFeGp0eskNMlE6CnvIQ8AIgBC9RSZZl49uEAM3DVF0LPE5VraHGeswAoR+I7mFWPkg="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.0-1_1522943882115_0.5270979383145487"},"_hasShrinkwrap":false},"0.7.0-2":{"name":"@creditkarma/thrift-client","version":"0.7.0-2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --strictUnions true --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"next","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.7.0-2","@creditkarma/thrift-server-express":"^0.7.0-2","@creditkarma/thrift-server-hapi":"^0.7.0-2","@creditkarma/thrift-typescript":"2.0.0-5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'X-Trace-Id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'X-Fake-Token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `X-Fake-Token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.7.0-2","_shasum":"a343f913cd026912238bfa040447ce0214b7dbf5","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"a343f913cd026912238bfa040447ce0214b7dbf5","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.0-2.tgz","fileCount":25,"unpackedSize":56507,"integrity":"sha512-6qfjQEGZiYLj6TKCmlaf3CXGpahipWJjwIHeY0hgRJhAmWWt25pCpkt/KzYWQ0PhIuVpKzO+AavHu8UgK8OQ5Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCTySDSF9IsLQTypWJcbAHK5UqLfz7ynelGrzsvuHIEUAIgFkf1E6Fy4PkYUMtNzGetesOmBC/mjbRsetM65MdPszU="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.0-2_1522950866206_0.374188916606383"},"_hasShrinkwrap":false},"0.6.7":{"name":"@creditkarma/thrift-client","version":"0.6.7","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.7","@creditkarma/thrift-server-express":"^0.6.7","@creditkarma/thrift-server-hapi":"^0.6.7","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.7","_shasum":"c94e037585c31c40c70a3d14e9b64a3c3fc2eed6","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"c94e037585c31c40c70a3d14e9b64a3c3fc2eed6","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.7.tgz","fileCount":25,"unpackedSize":56487,"integrity":"sha512-+sG1a9vIlZZBbGKMgXUo1I1yMmQOELFlKDGr52PLh61DC9ObK4jBsZcdmf/m2J/UJn9Ije67aJNsj2y5jnmjhg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEbpX4O1KYRhtx6W3vafJD0UEbWfdCzbHfBSURAMclxxAiEA9HP7qoadUW+f22aYYGdb4AASo8Oy+AMs9JEXA7JrlkA="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.7_1523379760918_0.09825600955297498"},"_hasShrinkwrap":false},"0.6.8":{"name":"@creditkarma/thrift-client","version":"0.6.8","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:only --","test:watch":"watch 'npm run test:only' ./dist","test:only":"lab --timeout 10000 --verbose -l -S -P spec dist/tests"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.8","@creditkarma/thrift-server-express":"^0.6.8","@creditkarma/thrift-server-hapi":"^0.6.8","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.8","_shasum":"e3e832235869db6c7d5cc185f1dd4acfbcb691bb","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"e3e832235869db6c7d5cc185f1dd4acfbcb691bb","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.8.tgz","fileCount":25,"unpackedSize":56609,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa1jPeCRA9TVsSAnZWagAAicoQAIgAdDWKN0PCpmTlrdg5\nw6OqWD2o1jlQ87ukTd/6csZj5IRHbWcaBqsFqL9ZxC13Z/t4mQfal2SNnaFR\ni6hf5w2gwXjXSevSWFUjDSrgXnNhXaX+mntJRoq9CVTNvxubmnlMRdhLer03\nRiAMqRrRgZwx9Dom9ffWdmZcQfQXiGbcE9KgcHJ0sNqSArYEyKIFm8b5xZKd\nM/duol7EkAYP6pVtDN+/hc45qPQTnvmDreEwELAHDxJdgf3sunF3FJDVaXg3\nYshDMYNQMPqBbBAtBwfIWY+bLLP8Of+7tUFF/ZbaaERcYvnKOt6M9lL1a2Ui\nVmlWu2/SkWxHsbMaTVGNWraOSra5HoE4dxavbxNVYH4tRxRqkR0eKiSAGP3u\nxElsN/dIx3cSPuJeH+7BEyTAcUyzwVjEHB7ris13UBd8AEIffCjsvCqECj89\nUIWUefIImJpOPIrDRo/Xml3iAyAN0CzKb6zLqohg1UC2fuHDAml8+JDes7WE\nemoy6Bg8Lj27uXc4JWvYdTkcH8LASwix4IQZGjdPYjJzBi6HCbe4PN9e2pnM\nHsNTocu6lZAAUeKB1ja3YqgWyFBAWlRb3abMgQFEFOOIm5eWisFZu4ZZxYav\nxIRCThLXq5FPqo3Q3gwBdxentIjgo+6Slo1whD+WPR6ug2o0qK80Te8GaM1P\nuF4S\r\n=Yk0+\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-UKOoXfReIRMNTQF98Pm+pcHtBWSPrruWOIoECTEfOhYM/ZPf0URsXrDpU6CfrIDKdFV5MoSMybIzPQAptdVD6Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDvjNbFl7iw2S1biYhoz9FwaO+RWniIu+vWenh95K6WUAIhAPYcVm3zLgyS9vbh0GALuwmKMOIvcULKnyFMhtF7j2i2"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.8_1523987420230_0.3076141383658233"},"_hasShrinkwrap":false},"0.6.9":{"name":"@creditkarma/thrift-client","version":"0.6.9","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests/integration --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.9","@creditkarma/thrift-server-express":"^0.6.9","@creditkarma/thrift-server-hapi":"^0.6.9","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.9","_shasum":"bd99139fafe223d901084a31c178f3c594ee87e3","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"bd99139fafe223d901084a31c178f3c594ee87e3","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.9.tgz","fileCount":25,"unpackedSize":56713,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa5htpCRA9TVsSAnZWagAArlIP/0VlulPVqK9w1Xkznno8\n8wzaVVyTpe1o/bf/TdNWLqOFHq2CzWCgoWPtIBFMI6dbTwnn8vkpW1tvHI7o\nEWTN70KBoQ+Z/W8OT0dv02B1Y4uNdNjAyzc8wgupZosW+ndjhqrHWQc2+4aH\nOcq7m6pa5459TWydpXMlYmqqSB+9w4/L1C1If/NSWuP7fka2iE1GUZxAW48h\nbzrbcd/6fGwIJPA9jLWHe30NwUtPeqytwSBDcpLhdjpIt93braG0AMPXny2H\ndOR0dqOGIdEkPj55i1Ao4k1V0tQos78EnPCzWlfvBk1f2/XAD4WZZUwYgb0J\ngE6FKFxzoaoAbofdvdBqpnKq4/utPOTmDHn3GKhylWT/h/9zOcvM9mWxjO96\nyngPsb1R8uFWBS4069+SEg1JiloDLYyBXl9C96+yafqgmZG/6WyY0lp0Gb53\nWxxvALlVdw6wjcC8CHKCbQOpCy39pp3qEdIAbjBPBw1x0g0yNy1fwBZols1U\nBuVt8wDo3J/GIDGnpXDRRE3UOVGyhl4j+ataMnT7x5lRbDgfueQFxaymF6Ay\nizInNOkqV8Vwf5ba+PWzF14HKYA7u5F0Sr3hnIDDRcuS+v0gX+6PJEIaoRwK\niudgZBTmZ3SuGggA02j4cmFWeV4yasT9KikWRAARwZjLf+1gAD1hHsOmd15H\nm29d\r\n=pDId\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-Cp9oLJwtNHryDTaD2k8qrgfZrnaCStPPomrKcbP6helbYcZgLiY2/GNsYayMEax5kSrzsc5HuxvEjPQF18UfPg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjZwoN6dmqDoGfD51MUQGJRzaQQmNXnC3ooIJmWDZQFAIgNt6VT5EU6EwDQLn32vdmBtcSsC/xlVYsjX94Z55vJUs="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.9_1525029735453_0.3352850719286653"},"_hasShrinkwrap":false},"0.7.0-3":{"name":"@creditkarma/thrift-client","version":"0.7.0-3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests/integration --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"next","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.7.0-3","@creditkarma/thrift-server-express":"^0.7.0-3","@creditkarma/thrift-server-hapi":"^0.7.0-3","@creditkarma/thrift-typescript":"2.0.0-11","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.7.0-3","_shasum":"d90f84cb88633ef239c4af38bc765e0c3b7cf046","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"d90f84cb88633ef239c4af38bc765e0c3b7cf046","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.0-3.tgz","fileCount":25,"unpackedSize":56714,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa7lcxCRA9TVsSAnZWagAANi0QAImq+k05j7V0HZ0lYAuH\nc9w2r9qGuD+0j4p4V+a/1fCqTYRDNssh3j4/M/a/F//4tA90V68VWQurs0fY\noIEP2t4wX88/RucmMQ9KbwNPoe5xCSd0S1kq9Awrx/i9KFQiOeijRgf04J6T\ngBWN/nxOvJGEk6CvEbrAFBHaxN9PCEU+cxDeoJVo+O5DbKqWno+H3bzOKcKY\nB99mrtSmKNoxIBsfGsMkurrNSlovJoxZBaurx3ENjTk7o/t/BAYQ31VHt4Ma\n+rb1VlCVkishkpTpYXmLVZOhnvCsvoGMx8dZqBYBch6jyKtH0posaslq0byW\nga2lDLThqTEYN5dX+vty+n0UoOjsqiFPS66ibLJvhg/kqRMe/YqqyXixrIPf\ngwOguyTHCcGtbYKGG3ETsx+eldl3ShUYPqGg25mnC6HsERmQd1DkXnqO8mqr\nhfUp+Nn7/sCkS5KFz+vU0pE/57LrE3SnCqbtsFAPJLz+LVodfrwYXgq3+lzu\n01/WalY8VLgWNhAn2tMILr9i1hk18B7qVlegEQiu/fYizbmkayPYX3247Tuv\nzrsWsg9jkP26/i+gBEuq7TSVALqVc+mIcErUBhuEyqxJ4+HWAxCOXpBM5sYL\n59He8TGX4ZwoyI3GcsTmsJToH6PZSpV0p9/R6wqk2UM2AkCpXpyBT8MGBYcF\nli5h\r\n=YD/Z\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-vueuWJpkNmeMTxpYs/Bw5RFFWbWTlfnHViDURY2eA+5RkNYGsFVORTIcW6EEhgH3twGNT1+SK0lKX5h+Tr6akw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICNjLend8QLmpm6h/xRhmuhvPxfPbTTJp1WVTKJxgKWeAiAzCyg/nDXi0+OMSItHPKDLvmUw3eCNpyDVw9MMeRSTWQ=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.0-3_1525569329151_0.7635266429975665"},"_hasShrinkwrap":false},"0.6.10":{"name":"@creditkarma/thrift-client","version":"0.6.10","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests/integration --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.5.2","@creditkarma/thrift-server-core":"^0.6.10","@creditkarma/thrift-server-express":"^0.6.10","@creditkarma/thrift-server-hapi":"^0.6.10","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"async-hook":"^1.7.1","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.10","_shasum":"b47b0912c19eb2f22e89323a8591cb3049fa9ee2","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b47b0912c19eb2f22e89323a8591cb3049fa9ee2","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.10.tgz","fileCount":25,"unpackedSize":56717,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa8ySWCRA9TVsSAnZWagAAHsIQAImY8rj/V1xDuXOxy1nf\nM6tFns/ErPuxTVxDeGA8Ts4Eiwzq15BQXeeVfsblN1oUvW9lxLvxnA1MTpf5\nJaKYSNfk30JTgkAUFSrAySqpZeDfo8NqHAur61ZlhJipYH2ekAHr0QP5Kj3Q\njcRP3CDFlhLW3jghqrrWy/095suoe0sgFkT6fOK9lUrr4a6u/K04t+TNftkR\n5SKxrg0UmPyklsxsINOgVBG9Xvymhz0iy3XlvXFxnH7+YAMNKzacOykqEtqd\nNVE3i3arXIZSTvVx8TgABuqnbgDgh1V+ySMAFsGyh+EdNsNTbcKroEYaLYDK\nYhxXeAZqCYJhcTO0SI7acNiFmiE8BpyU3ztK+VjfG/GOfHUDY6uXNMNe6qb7\nCydGhpjjI2c7PbVcSabLOdkD8rbTfNVH6vJj/dycW1VLjDQ/pSN+kVmUWjZV\nKIKG/TJNsURF0Ev7v3vLxN363xGbwNF1HIAqxblcRoUCDy2tf7kfPrWLQrAk\n+M1dxuFnTI1MYAY1Fg9gOF3nLFCE5l1Cml8oSqcdRMx/bIKHGtblBj36IJZZ\ngekJ/U40WwfNxlus9JuWQm10B794kYpGKqIKe56xYRxhnRXYieI72G1cEfg1\nINok/pNQeWZtYq6UaU+oi8kyP0Ffr4r7+JuzIU3FOf+KIMYvTX6XwldxvxZt\n/Ic8\r\n=7i7c\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-2rnGQu210ZN1TO0MXqhQrfrCiC1/WfzAexEsfEmVX/LXS0LhuP2BppPZgyFK1jHKbH14zQ3nf48dFXoKwVIleg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCH2ya8YivL09uhCnLqrwRkGOPFOwBxQxB4BWyLZ6WNNUCIQCsXc96nAIAWlw1mgd32D4spNDEv57vTtsTW9e8CyGOxQ=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.10_1525884054688_0.5932035419462736"},"_hasShrinkwrap":false},"0.6.11":{"name":"@creditkarma/thrift-client","version":"0.6.11","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests/integration --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.11","@creditkarma/thrift-server-express":"^0.6.11","@creditkarma/thrift-server-hapi":"^0.6.11","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.11","_shasum":"b6fd6783eff11472a022724aadbe354282251fa3","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b6fd6783eff11472a022724aadbe354282251fa3","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.11.tgz","fileCount":25,"unpackedSize":56689,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa84EdCRA9TVsSAnZWagAAeh8QAJoS1uYOqt8psbO6FAvJ\n9ZDVk1jXTIEeMycuN09VNQJsVDyWbRhLphs3yRYz0IA1RATqg+VrL2vQ/187\n5clXTlr5i07NieDX3KWUyQ2Hk8eCtqjobyoq1Ght8v5Brp60Sgfm7GdYfi8c\noi6SnF7HEScmTaH5trkckcG2q0pPsdMMUdB7seiALnNRGhIjJXj/aM9cn1x3\n8LCr9PyRIhey9VNhjMe9808oXfv8qFkmxlamcavt1Hg7+nFz8bXLSgKkEh+f\nONfeq9c/pyWLxRwaInTKZWd+N+Qx6+7OKYKKXc+IlW2LPTmbXaZSBko289MQ\nBgKpNY9yfBqk8ZgKMzm3cx/yAiKpO1or3BQt/6XnBwifrpNAiQtHwpxxJB68\nA2A5HGVKTHhw/x30VRvrfygmfspCXND0CWTEOiQdEzgfsukIJtGQzMrNZjeC\nGosHRfpT+0YgbVATUUMnV5otLCVnFKwjDvw3CSn7XWF8rHqMIXdxNpHf/YU7\n5qNYrux03wWEAC+oMfR7T17KfblzP2k0yEeqEif+W7drkix3RlC3JMyd0eRE\nIF4kdt7BpCuHZneD8510Tk2L49yr6ozr0bqkZwF4aq6kbVAPYc5IdH0vYZGs\naY0lTg2se5WgJnOJoQLmSlo5XvcXeitCm0Dbp3SFHERCdrHwYo2ndxiUN6O5\n/RL9\r\n=Cgzt\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-+jJFZd5nV7j7EHQ++WD/djCS1xLbDvSfzX0+rXP+UltNGauWsZmeTi7UE6n1vuUDjAs9/MzBe8caxGTQmUqPTA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCgZ6HSCZHca+kWqwP7IiXXFsv345ev38oodJvP+IQiRAIhANBf59PvHMN0wv0J+JwXTZLd+ei8f3uM2209M/SWuRYt"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.11_1525907739705_0.027874082819125068"},"_hasShrinkwrap":false},"0.6.12":{"name":"@creditkarma/thrift-client","version":"0.6.12","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated","lint":"tslint --fix './src/**/*.ts'","codegen":"thrift-typescript --target thrift-server --rootDir ./src/tests/integration --sourceDir ./thrift --outDir ./generated","prebuild":"npm run clean","build":"npm run lint && tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 180000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.12","@creditkarma/thrift-server-express":"^0.6.12","@creditkarma/thrift-server-hapi":"^0.6.12","@creditkarma/thrift-typescript":"~1.1.5","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.12","_shasum":"ef97d3d340c7d54843291c8a392406626b9c9a5c","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"ef97d3d340c7d54843291c8a392406626b9c9a5c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.12.tgz","fileCount":25,"unpackedSize":56690,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa9bS4CRA9TVsSAnZWagAA3hMP/0EryuECN/rT9E35St9+\nlQX7E15h+PSQ4b/AUYTUV4uyklALoi8Ta6Iu+fYVcUd/QF7HZcw9UVy2eHAV\nQH4yxnsF2eI9YlrRBzQzLzVGY4g+4GWWgflt1XTXgmA6ZpMsN0gYjCU7brof\nO7uxGDDhuzLN7JFb3cgfT/CUUOMVMzwY8tkm4f4FT73pOCMfkrm1BSOzh9WU\nfqysGOQHCXFNYvS2PR0P7kV7eMGlGJDCAaG0t2PAyaZRtSczmZ+ZELYyC/hK\nlimaJ1xEQLAYoBkr49cCZXE70pefJzmwGTG4SbqI2GVmP3JE5/iL1zGibPTi\nMTgM/xQ/HWtrrkZUn1M42Sm5/rHLFKlutRzSeOVGKiGrtGBwm/RhLlkn6wBz\nIL3zWlXVQRaV7f6Qj2Rld1XfLH/vBajeETUb6JJbnrtpvu7m2ibGUipRTGzt\nun9kQI11LeW18eGc8IGDbFpinygPX4b5Ul+0JM1K7toGD3KBNAbFY0bOcrRs\nYa3Jfr9MkC88sFhitoRt5HGSFRnzu0gwKkYJ2ZrEhw+YtArz1EyJ8f79w0Ck\nDg+y+XorHDpFa9mYVkGeySJ//hdtAjLj33AE1A9jZJX7v1AxZK9m8wiBoPG9\neVM6mHhN1jOIW29FtylSTmBX0JbXfVhtoN58QV7MSTQwwi0jYmPyHsiVwXfX\nQkDF\r\n=lrE3\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-16sZNQpuR6Ee1GbqeIULxvxVGOBxysU5HVMam3RlNTGD6ViK+T47QkNabkJOi1XCsvum6yVcJl5vZ2eBfxv6pg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDRxxGkkNoq0z0fiG3VFslXBagY1T4iDefbslpeF2xwiAIgYhpNZHSDC5hTpAB/l1j25AmejKYV5Bx8dQEK4JWjQj0="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.12_1526052022618_0.7256295284894481"},"_hasShrinkwrap":false},"0.6.13-0":{"name":"@creditkarma/thrift-client","version":"0.6.13-0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.13-0","@creditkarma/thrift-server-express":"^0.6.13-0","@creditkarma/thrift-server-hapi":"^0.6.13-0","@creditkarma/thrift-typescript":"~1.1.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating a Client\n\nThere are two ways to create clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that implements the `IThriftConnection` interface. You could create custom connections, for instance TCP, by implementing this interface.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.13-0","_shasum":"bc35ae0a461ae0c5ddeecfcf8ac2438fce6f546b","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"bc35ae0a461ae0c5ddeecfcf8ac2438fce6f546b","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.13-0.tgz","fileCount":55,"unpackedSize":97263,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+vsWCRA9TVsSAnZWagAAijcQAKMT1e7k8EXhw6oI8fg0\nQ/kBVA/np1CTQXOMmwk1Z5Sbil/J+YHXf0+lL87G51IYzMJ33vFZZ6llkT8l\nmuZ9kLiGiwb1SzwYFnwCdaM6soioxTbKzhzvG+arMLX2G7cZyKy42naXZzWl\nuKTJAAbpTSsdNZVfUbHELpoUdLWBSwq5TZRvAsJpRCjK1iM9WN72+BHdWFpn\nJDGxemF0Q02yB1GEFRZ0Por7r5Iv9k8jTIsP6m26eUAv0+5OBdul+3WAB128\n/+6me93uuyea6zu1oGRqAbkwRtiYK2eeupiE4YnVaN4uaEFVR4x5jeeKJUCO\nYeOG/4X9QGqtuSEv29BAsNtXHmVyYEWximFogC79CGue0yKfcolmnFISRXO7\noD3cOZwl6POnX0/wQBR0HLTTVpKPQio0ZXZ/qHQYcrAn3HBdnpRZjJDnCLij\nZVFJKcgjuCt6t3+PdDF6WQULSkoU5OPyVOxUy7MLidCELvt8xGgpwT7uhTSz\n4Xvi4pBZlqj96t6VQvonZmeQxhzCBmE0JktEbWoVv7ppk0aufn9ahaZWleA1\nFXFVEbfCz1CvwoUlUZ5A+O/dQiVofUsb99NEX2mQ17ZBcyVOTT1HcnM1kCDK\nYeMG+aCtLSwL30IGBtKt7oUPIpK1/ApfjQ0H+40oWeStKodIP/tljsrJtnlK\nZNGx\r\n=8HBH\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-+X7zJhd89MBvXutndvh2vWTMOJfEiJu0vdnvtQBAPW3zEx32pi5NCqsctDbFWX7emz9ggWD75wi1rmoWkpLC0g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFUhZDmqzF+uum0+FaeWq4BK7zJ47xUcriZH9uFws4siAiBHEhtol5O1BmqjZoXRSx9WOAmwLKRXIivjOedyzuCHFA=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.13-0_1526397716985_0.2945306664933567"},"_hasShrinkwrap":false},"0.6.13-1":{"name":"@creditkarma/thrift-client","version":"0.6.13-1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.13-1","@creditkarma/thrift-server-express":"^0.6.13-1","@creditkarma/thrift-server-hapi":"^0.6.13-1","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.13-1","_shasum":"b49be89ccafed92f43e3b2734f4dbcf4e33d4e73","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b49be89ccafed92f43e3b2734f4dbcf4e33d4e73","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.13-1.tgz","fileCount":55,"unpackedSize":103716,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+0D1CRA9TVsSAnZWagAACNQP/RfbLi3/IEHRl9IYwPUP\nOkLDBwu33OAkuIjUFoU7thPZTZ2SBNwv38x0DrAkDR08TDTwA1O8tIfLiEzV\nUo8M+wDO4zMJYhbdnKnjIU9+FWwp3KInPgL3yRFrPXRwcxZvEBx8KvpXdljc\ndiMQ/PEMNXYh64rcjRylhlEv73Wd1ykwnQHjhHq3bflmxWcL2M9epJdWpvMw\n6733d00cBxJOHnKWRc2ie62wv4BBCIYT7X775t9GF4wbpUfwxo6kFGIU5PSC\n0XD9Bfsnrzvv8DSkXikheu3sksytD/CEVI4Rv9U9wxtKVF45tFJObSKykMR0\nSP74W6oBJezanEOq5G8ooaVtGvXhdkV9AclSKFLUK29dabSsQp7PrrOItpOF\n6sddezy99U8Gr8FUGHPta/Fs76HiKf3Yd/imdMmPYBydWS3wiv0HEYlX8fOK\nkTo7Iiv76zAomQh6cTDKri8kxNbyUJxotjChXd/g+qa4VrF5hdyXYx1nFKBl\n2BNKpD4ofALEYzqc8BOjEA7+PnOb0NSviRA0O1ILUHt+3H0U5hqMelpok2WG\nY6EeqWziSqu8z0CwtD7IqW2l/0B2kk8nZptASQMwT3YoR+s6yCI2dR7uFXSf\nVxUrjU1BI/dCgSv+zMxiVA6vv08UbCVJrmVpX0DzC8ZFAyz9dXPiEuoapAbD\nEGd/\r\n=9w1s\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-Ra1WjfTyVkuyzt/7wVl5BSREA0l/7MN3/OmcYdTBIOTJwpXjuM6rrDm9fGZB/SkWDL6FSl8dcZsj4jFohx5BTw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBQGEFurH/PgZf2IppYFNioVFOShixyePnk2eL+qYy/oAiEAyy8WK6HYB/YsTJFKkn7NFYHMCcsKgtUwGqaQeTi5yX0="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.13-1_1526415605441_0.5202055568006292"},"_hasShrinkwrap":false},"0.6.13-2":{"name":"@creditkarma/thrift-client","version":"0.6.13-2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.13-2","@creditkarma/thrift-server-express":"^0.6.13-2","@creditkarma/thrift-server-hapi":"^0.6.13-2","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.13-2","_shasum":"65898426847025672bb0f9ac32f23379d4bddddb","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"65898426847025672bb0f9ac32f23379d4bddddb","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.13-2.tgz","fileCount":58,"unpackedSize":177515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+0PHCRA9TVsSAnZWagAA4v8P/0h/nDQ772TsLVTKST52\nFscOnssExZYfUnA6xeuQhXG2Dd20DRJjrFX5XsJ/qMG/c+C1i9IQbOa4QMKl\n4ZIlAsGGHm46wQYkpoThXquFqMg9hjwAbuH8iqFiLamKkt02Co/ZNpp6WsuT\noxkQHAcLHH67WgyjwKsCnSsJGq4GFKJPSl10hQK/xBCw56nZ2Kn5HpRfjrzI\ncL1F9hTfl9y4/4R9XlSFTzugO/DEXJ7cjtd9X4xByH2v05kYtuhyM7/btvGz\nRvxfdfo5znBKQEmMEATPXKx/9hZVEkrCHyXPiOXXRNjyj5vihN7l+DOvNgmH\naOTU/XGZNmNiRZ18zXy4goxZVHMtixswWEVzz9zPKzdz0UOIUE5loRRa8v7l\nvjB7hKBK8z+SNQn36PtbR96I2/Cyd0XEB3L5jA1KRhqY8A65hK32QWV+Cg7g\nLynah7Ws6zO6dHFtd+k/AynjbikfzvqA9IR73HqqgEkzyyYuuLfIX52xNXYG\ncGBjiroU0HmEMV8eS3ARWsFc0Mt4Gwa3L5wifkpPNIbUfbGir8fESdXdB1G2\nSdw1MfaHObawnNYpDXTA+ICv8/JJyjuyRaI5uzQzEEwhgHJgTAoEnqg7gmwR\nrkUHjZ2qSmxTDaXuFxICV7cwJmOSK2QMbS7je8RkR0EZnU+eNiRYXnX5wfQF\nfxBU\r\n=4Xum\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-44ZhtXAZ/iuyTWGmO5e1GGbOG3ZCe1cp9iQlIgzEAckHRYrlSbWgWIse02FITs3ejIBE/xo0YF1reWtV4GZojw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDDlwwDDIrg6EQWxS0dvYCVCB/IInNrKuEcMknNywQpuQIgMN7RIqj7TWfsKa0y8K07MfcKkeTmPS45PEm6W3EChj8="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.13-2_1526416326310_0.853938329919417"},"_hasShrinkwrap":false},"0.6.13":{"name":"@creditkarma/thrift-client","version":"0.6.13","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.13","@creditkarma/thrift-server-express":"^0.6.13","@creditkarma/thrift-server-hapi":"^0.6.13","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.13","_shasum":"d01cd6a56982767aee9af7d552dd58487eb2cc7c","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"d01cd6a56982767aee9af7d552dd58487eb2cc7c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.13.tgz","fileCount":58,"unpackedSize":177507,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+0wUCRA9TVsSAnZWagAABf0P/2wthGHWy992OKvPso9t\nPV65nPCX5fItOQ9v+uYWY1LC6+7EpU2VABqTs/etIh8dHaeOPYbA07VuB8pj\nKyZJhngTcIwb+F/8yhmYNkXLMhlzZD0WgtN/NFURyrD6yj3gjakPq5787jN9\n/E/dezanRjVV9SCJiGnkWnGIMsANCIRgoq/dqD0Q62TyVQPIpaxQwDoHkM35\nxN6lnDXwo4Rg1Muqre73L9PhEpuWsrZqv5uEucHkNa4voo2PpWIwI+wz55FH\nbz+zH4G/DmTU+No5xX98nPI3Ivf2QV8X+ZaSId8odYOY6VmXYOrkbN7PdCJY\nSCt4ZpdGA7EJbqyWalOZ63yFwEEcxVJLLmt9TMd7rT3Pr9wd67HU2JhK/uJZ\nKWGTX1WASgtBcWWhn7PQTqC521YS6iQmXc3JlJYqg+KwgHZFTmLnSph49FFp\n6wsrWWCl0tZG2UUfEL8FR+S5FmYbwBMSiyxbdmIwE7HVwdbLK/rP/2WqV/gM\n0pZMZlsFmGZT+E3L5hFLri99/bGRl4hG/ePvDWRDPotUz7190qKOpjJHw6r5\nC6h5PAmXW7a3yj+jLZOTAalF6dmB0eeBRSmDRhwY2cTpu2rONnT4cujTawCh\nrWiyF8ybn2uxvIKNjtxvRyNBDZjpaWZHvcUIcc35ZvQr1fJDY89hSxmfuYYy\nhLi6\r\n=lK5w\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-zaVB0Vv415XrsgrNt+tXm7rR5tNBynPNId9eyX+Z65Fx3TxoWBEoES2L0ZVyrnzm3XG0uR7N4PDF3J1nTOuWJw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBJercEmqcyXSlbc7KPCvTi7XnVh7RvgbMbnLvY1vFLlAiB3OxFkMUW4yz+71+8XmirCu5+Ba1n9Y41vtHsoMaUkdw=="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.13_1526418449797_0.49352897446480326"},"_hasShrinkwrap":false},"0.6.14-0":{"name":"@creditkarma/thrift-client","version":"0.6.14-0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.14-0","@creditkarma/thrift-server-express":"^0.6.14-0","@creditkarma/thrift-server-hapi":"^0.6.14-0","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.14-0","_shasum":"9aa994a7b2f23e93e42b10c459d6c734b36ea00f","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"9aa994a7b2f23e93e42b10c459d6c734b36ea00f","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.14-0.tgz","fileCount":58,"unpackedSize":181350,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/gw3CRA9TVsSAnZWagAA8kIP/iNKrYzI55F5obJUTBfB\ncgQxJBMeMXEwhBX1DwHfh/4+MTfvXcu7ZBe+paJD6/nxKu5vnwBqPH14V6UB\nKxHfXj2rbZcLO2yfdTNLXCxbPCH/Oyj6qm4sOUV0VfB1K1wrxvH35nMhvONS\nO0xW4aRTPMj0uPxegapB/r4RBG/pSWeAjmdoloL+bpgM2T2Z5aJcGG+MuvxA\ne6D8FXb/gQsH2AZt1RtJSUI5yU2pDe+3uKmmspcXK1xqQwuslBYmatf2K621\nHGlzyLrXyOhCs6KuTp5LTSjP/vdwk1YuphuLoaLN5eymb1mrD3UUC53ptema\n+TpXYn0eSvds1+hxgr22IWCV8jFzEE8MEpG0XXfRrUUyXZqNMJaHB7MgupTF\n8VYgZk81+WOAGoBQSljB/LovZ0O8/tLrHSNd6HuqS6xYl6nV4reabrtdW+xV\nPHwhG+1aP+/3TsRJ9wfoCNqAtyTFXgsSdiyTcEuTGCsKsDqFgfyJ5RaAkdUw\nX2trjUkDczawNzokESLZebVIvkdyNYnR8/yaxT6bV08Yk4rWRcvro+vTNOSe\nJI2Yj6ukcI4idu5jw+LhLTp53nFnzXXncBSMIj7Miur5Bgm71Cw0OzNs9r8M\n1l16T7MZNiupBUOlEFcl037I8YdUXq7y6xMqGvqLiydcr4+LJP82u0ySN/lw\nZNVT\r\n=VwBc\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-JuPz3KoX8o9KDJUq+vwROEFgDB5t2u7/5igowf1BHBGL8u1rvIxTDV+iCirmcs7Zw/i7I0k/VWgdM4EWdHt5ng==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDaREhTZzqO/09EyH8WfQLJPLjcLi/qjN6Kv0yDdXaEUAIgKePH+FZd4Kz5rs4Xw/IahBuS0YzEwB/qw0LR8mc9ob4="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.14-0_1526598710447_0.7371110027640508"},"_hasShrinkwrap":false},"0.6.14-1":{"name":"@creditkarma/thrift-client","version":"0.6.14-1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.14-1","@creditkarma/thrift-server-express":"^0.6.14-1","@creditkarma/thrift-server-hapi":"^0.6.14-1","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.14-1","_shasum":"0118b9dac0390c83f50815481b402fd8ed8c2ddb","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"0118b9dac0390c83f50815481b402fd8ed8c2ddb","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.14-1.tgz","fileCount":58,"unpackedSize":181397,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/g/eCRA9TVsSAnZWagAALc8P/2WWjIsFtg3FtI0brysk\nVzWvnuYDfKeRtmnjx/Oyz8EgYPgpE00sJUDwFPNwbybOiA3uOA6wiFIJXHyF\n2w6Gzd6N/f40Ffs7+MAtKcycuew/52D7kLN2bkTMYoyhK2FaE7j1NCui8g1A\nDWPh4hWrjG/k/jX71kNIPvlxW0OHnI+lFkCWWn8wFtwX/4K9UeFf7IXpetoq\naV0CQ6XPXrq+w19rJwoLHiN27QNJLBzOlraQkDEa7i/BnEqOcNPT80xaqRHR\n+hJuGXh9lbT6ST7ZIygf6x2RQsbL8mEF5fWFJC5Gb/Uzmi33l4K6R9nbEkdp\nSpWZuNnqoDtkpzeClaOedZ3/j4S6oUjTI0tFdiFopOAx1sqzGvw017+bTyCc\nIJRmaSXYhhoVPnqWGfpHL6ZfutjMg4z6dBxKVsmiOha2l9z4iIFU8WH2lyTi\nB0SiMCBECaIjJV0dW94X5rqmrBnQ6/a1+FdGD4PtO4Xpp6ZMGOk3lewBXlv6\nSYXTCrxnXEpElzxT0g9cwWpEavzrf0DW9qhgEMYrWngX4kgEsjbF7FxGMuHL\nGxiRJuX7omf+uGg2rMS1I5+kx9dJRUUQGkJwSS6DJw0XwIisQLwEk0kzK9jm\nrMppMcGMIYwzYmZT4aMKv06rNHH8++ooegvvqP4AdRoUI1nJlDoz/QsmE4en\ny4BO\r\n=Y1xr\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-sGHN4FTp7seDuhupRvjicHFtqQ/H2VBERnCIP/YmcVi9f+h4FDWXmfp5olfUcQR4XpVf4ajYSkxmuBtexF+kIg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICTiIjIMLydqxx2Xu581NiTszJII/giWdQOiMzQrCLu7AiEAmhAI9rLDNJCvtIF3YGvdd1FrP6fSYWqTyPzQ6J524ZY="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.14-1_1526599646069_0.5848842087129682"},"_hasShrinkwrap":false},"0.6.14":{"name":"@creditkarma/thrift-client","version":"0.6.14","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.14","@creditkarma/thrift-server-express":"^0.6.14","@creditkarma/thrift-server-hapi":"^0.6.14","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.14","_shasum":"f72b03f745f23071e4c38bdb888820892dee16d9","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"f72b03f745f23071e4c38bdb888820892dee16d9","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.14.tgz","fileCount":58,"unpackedSize":181389,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/hRYCRA9TVsSAnZWagAAZsgP/jWLLatyo2woU/MLHSaQ\neN2A438IEwEyA3qfz54bsYqNFbjuYLdPx479LbZmeeu58/QT8nozXQEff7ZT\nZDuZMGCo+zvStmscY+n2yuxZ8ICACeKtAR0h+DQpOufOudXY5uVlENGcAgIf\nnTjy/247KaG4SHzZl/+rbjYSavw+32OhS7CBiurrE2Zg/BC9wu8QjGucdy6N\nLu2f7OlsnpCMu/PamspnMYNzPxrKwHqLFa78ghA8F6XmEZd+q4idFiSTR9J6\nkVIQmBDSDrCShri/aUJhb1LOhrp93wNk3dkf6/+mHhNbcCIn47n6CPw5bO3+\nF7GoSAUAocE7Uldsu7lwusTPtg5A37mH7xu0W+LgJY9TdJmZLdymUibETTmc\nVw5lFv0dSlqS96PLUO9gDGybCUvIhZSVCfoJ77r6WjENk+RaFOJpGyEudDIW\nKuJ7FF+utWYRgOT087tLMDpDvL0WTYsFnj8Ka3GwU4zQBCWsA2TdKgT82BZA\n2nWpEut7aXW25IMukN2zgciXaK18zodOrwrM2lL4mjW6PGtSMclRTR8Q9uAT\nFxzk/eHdlen2KkGmlLV3eYm/6TmSBNp9RnGLGMsuKhDcItRsxCi0c+qAOfNa\nOl5xdTrLEiLdWq+iBhH4HcxBWPa0R2DL9m4Jv8d7FJp+lS0DC0YIdOWpKPgP\ngjeo\r\n=Q3jb\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-DKflY73+prERRSw2y0ZuM/WJxzFVKdJKeUOleeWOEGpbZy/noOTdrmNeAGY+xnHx/30oIJGkL0BwonyAGIlz2g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCp10V49nTqn0+vv55Hoq/92vuZANV5IgA6mjNz06BkNAIhAPrZboilThyxbiMsNbxjAZnrup3zR/RTXybUOvGYAPmk"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.14_1526600789380_0.2669914393099213"},"_hasShrinkwrap":false},"0.6.15":{"name":"@creditkarma/thrift-client","version":"0.6.15","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.15","@creditkarma/thrift-server-express":"^0.6.15","@creditkarma/thrift-server-hapi":"^0.6.15","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.15","_shasum":"2f588c501e3134c513ea5c5f2e9f55b56c4c83b5","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"2f588c501e3134c513ea5c5f2e9f55b56c4c83b5","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.15.tgz","fileCount":58,"unpackedSize":181619,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/116CRA9TVsSAnZWagAAiuIQAI5NbaN8vX/SujSmV6Sx\nMh0+AXKyuGzcknGN57OF4sjK8Ia3nN4xTBGLkuEtXIU508cO0RxQ/PCqjfaV\niQ00x6WrMBnvQ7cJG6+UfNMv1AwTtUz7wg8crV4ChDSa905TA++rySDLy21U\nV2SFG7dDoO7qojkbk3vAqTjmDLazQYZTW57w14Q+uyVlbPi6VlvQsdmfcE+n\ndvzCejX2hpvjqLk3l76SBibr1T/Y/5McfJINEQKKa07fJkEb/nR/4d7FdIKr\nahNKYpmJVlbRImOwVxzT2wfKqJdaSNOTDej19Zy4CZCAhcBu/JGY683sAbFd\nAlOpbVU/fypNsB6Wy123lu/MMZxbvfN2WOXt/44pNkYRP41IufyUauYCtBAX\n4Z4Xz5Cj4kbEXR2skStfaBpL5nK1af0Orz7gcyFNmoze8tXawlnIpO4IZ3Qg\nLGFLu3DD0U7fJhRKUIBOYwOg3o72ZKTntWkFCKfg9dC73tP4CD4BU3vZa4fZ\n5W9xtfw3XOEFcyoRKLg1xUHp6Yfubf4CI4rj5DYaqIWY1XdKo5GLM5Ce5yZ9\nTSO+jbgljQKeIDZD2SuXrz/DRuvMeanMfggIoPzHFqs/d7OYeDUkrQP4fyg2\nZBYd9cDiu+2YT3/bpiq1Gm3u9YdbeQ6jEVH6dWg8fHkax7TPR5s3Zj9L0MEL\nLcS8\r\n=Av9O\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-ZrKEpeeHQAxktr2gBL/C7f7xzRthRg0EIgE28oGarBTREpyBzyNMK/Dk6yMJUJhJQobq8F5iAsJRtbEStmP1+Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA7IxlqLI9uX8kD1yKSBAksB0jAFc7hQOlWUm4VooGrJAiEA2rShbrS3A575bj9b5sS2PRcwcSecFtMumPeqHkESIU0="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.15_1526685047525_0.4917875862054635"},"_hasShrinkwrap":false},"0.6.16":{"name":"@creditkarma/thrift-client","version":"0.6.16","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.16","@creditkarma/thrift-server-express":"^0.6.16","@creditkarma/thrift-server-hapi":"^0.6.16","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.16","_shasum":"0dec980f6125eac5ae5a81057f606cd0d6f7afb4","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"0dec980f6125eac5ae5a81057f606cd0d6f7afb4","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.16.tgz","fileCount":58,"unpackedSize":182310,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbBhtwCRA9TVsSAnZWagAAS/gP+wc66yTeaVjeBardJ+BB\n6pyjWE0ecfX0u9r5JWlJS3d7DKDP2Ux6QyYi5RnLVGxI9sZiOijV+s7PHVfl\nZ0p6UpWeQStfX1Vc7JeVE9n6eq6G0alubBFWl4Tc7zzyKcLxp9Gd4B23MsJB\n/sTCpRnKKpC5xAR3WUZ++4FaA6xp2HJyg29L2ASm5QVIGZLQG4A+gE68Jxpx\nNGfBsBVfCVaCJ2mFbQpRsE76wIi1T2OoadgUPy0GK3VWPoxSVygqdKzhHmG2\nqbryrtYx+9Ap10JpUU8gbu2nd9usD5IG84zBeg5IkM9ujS/TrZNcSIaeTfTR\nMtUbX9QO/Wm7upFOzKEgXYDXEboRQbin1Uyo+mfSVU8JsItLbRmGSu73HA+c\n+0l7Lyu5rOIDu+q4yvEKevPiJ/F7paOJSs/vn05DHP5gT4wCWGScfj92idiq\ntTBET248vMjz3TLA/2y7y1EUho3qabfgiJlJ2FEcaZe+kQsND80BEOYN9OL7\n/0DxrAqP63UxBl1Gtt6TRMblf/k9FXupcFIqb6UM2ZVmVHHGGqYaKgM51TgA\n5J5vwQkVCqRmcvYcAdF/XWJ0WR0VBHznBDhXqB1qz2P4ziXqPQgmPu5qI2E9\nCcX6XpVasLan1q1ZHKp6liQzCgdVFkOi8FQceyYi0QSeAYPQVjbhRW6OaJVk\nc/aj\r\n=ah15\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-o2OssXvXB1DfE/OFPdUWeSf9Q3zzxfl87b1KIk/f7WG+GxSH53IG1bjcH9PzJNl9+CCRTMpG3P473+1KhqjofA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDPunNq/QiN/VlH/spqEepKL07xTOIktdvuGNO0J/7QDwIgBvWNEzIwzUUsoXMPr+7GysbvDelYYGbxPDMnInCotrE="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.16_1527126895370_0.96859848352125"},"_hasShrinkwrap":false},"0.6.17":{"name":"@creditkarma/thrift-client","version":"0.6.17","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.17","@creditkarma/thrift-server-express":"^0.6.17","@creditkarma/thrift-server-hapi":"^0.6.17","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.17","_shasum":"cc1a67b804f469531a71779208184a135676d9eb","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"cc1a67b804f469531a71779208184a135676d9eb","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.17.tgz","fileCount":58,"unpackedSize":182310,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbBwBrCRA9TVsSAnZWagAAajIP/03p3yhjRFcX9RVG+vjV\nlc6loe9fH2U9LBXHX+lxBmBdoZMdY96jb1EiaC7WsRAQzpegoB8nGf8ytEsY\nmtMC56WyAZgfWJIRsiS/j7gvecGD0/qEAFd+StMu/aKtHrWKhOh1OnimILim\nfvz64hoFjHxZxcuLaqovIL7fvZkxDePtm8cBcNc7yq89kKj5gj0TYr8FWA1e\nH3U1CIKzX/B9Y+yNwlK5oSWI46hAYHGCvqJbTHS1yxC7/odnk7Y92RVMSolD\nRYHcPgtUkAGOyRcPExsuj2+6reYmnaDMG34CMXbZBYC/XRI+RYzb7/A+xiv/\nPIw/DyTIBt2quyeuudtgc3oSdieTwNTHJ5kcsDWXX2x9c57kcHnB+2A7v+nx\ni2xOqyZVEq2R8U+0ch0xh8InbkEMbEZRUwyfEZuHofVn/HTh+WGVBz/Huv8/\nVaH3zpKG0P/CqOVmtQbaB/ncjosVj8/PH4zY5m+s/IGPP8MAhWiypakzu8Tq\n0ijvaFY9UtwkvhtIDFfLQF/c+inwkG3m8ASyKIepeUGnJ/UrT1PZhbgDP57B\nEiyYrGcZopr2T7GG1Kxi+E4sVnpvXrXqwsnOeJHzUm7HmipZX/AQZ7AJyZ33\nKy4xYqOyZVeX3w3vmset40+QSgerQc56NZd5/d4HX/ypUISu1U1r7wHqSnft\nOmSS\r\n=eIYp\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-SwX1O1+OpE0KIw1A2V7gV3tAA/+aWfx1DK+L9PbviM4UiT/iGBZTD0SM8hE0+C67Sqh3nqaA/iMAAHxFv/i3ug==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCSF1V7dUpew2nEL5j/nUmOwHkSdClXmRcxTGuP29VNUgIhAPx3VQaRv7jt0F60a9PbeyvZ4tepzslstMHgjWS+5C6e"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.17_1527185504207_0.4893347949296596"},"_hasShrinkwrap":false},"0.6.18":{"name":"@creditkarma/thrift-client","version":"0.6.18","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.18","@creditkarma/thrift-server-express":"^0.6.18","@creditkarma/thrift-server-hapi":"^0.6.18","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.7.0","typescript":"2.8.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.18","_shasum":"ce820757d7b59623295dd72445809b8cd6227366","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"ce820757d7b59623295dd72445809b8cd6227366","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.18.tgz","fileCount":58,"unpackedSize":182310,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbB6T3CRA9TVsSAnZWagAAyVEP/j0kEqLiZ5xRiYViymYd\nHpf24lN/vlcrADwIybQPLUfkinsMlRL0Arkx9+GsQyVDy83z+vECBl2DoBxN\nEL2TsqONlJdF9WH0uLUTJOsObM+3WnQtk6pFD4CFjIGB4iN76PbLVAfzw//x\ngO2//A3oH4IsHShP5n251Mojh6ONJeZ0yPfVCZ1SvNdCxDzcrTPNggKXBH5j\nKDcQCIW4jYmKqW7brDBDse2ZNkTlkzJoHLvelqG5FfOuZtT0wT5D2+C3KkB0\no4zZWdvSH7+nzkkB+WwwKhLl0Glv4PPFtzsCh/xaDnIKRysZeLaUXfSgRPlr\nFwio/Y1rgttczMiIHH5inxvFQcmm+zoIRrZRDaWYL8jEFRUTBgaHEauh4KQX\nWVYdJ/OyOojfLoFvE5GACbe1Oq8oPHmYeehKvX1s5OWfJUVX5aM14b4VPlBW\nNRNlhAfyvXfGrMiJj0AwMIj7+WetyEf7yYgTYYgD63kuxyNAYty6Zx3/iTWq\nSDfOYIa52/cxcoMcRqBrSmQZtQoPJymkf7Vyd2JAPTM3O/CPiK3c6hVJ7U7/\nwWIX8OITo0LVJkZa4Vd6s9pUw9VaLehT0Cwd9gtpv302V6d9XTjPOWVBrivJ\nBkCOfVBxgoPsnsBVFcPB+dTrH45hrB+UjAM/YrewjN9UKE4DP3F1M2PX/V4n\ntDkc\r\n=x1o6\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-IRTQD5Hv46Zoam+4067rulLoEVZnQuGx4EcIVHwuc6SbgVXArlFFu8p3ny2POY1d6r0TkEcf8DCvwDo6cR6r6A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFUThGO1r4ob0jcsj1jXBDmsyX+lEPkZQuIqFaGkAktQIgXis/8808Lc+ksJ7GWHvhJ2PRCey4SdEiaRH8smw3x7E="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.18_1527227638759_0.051416160245177256"},"_hasShrinkwrap":false},"0.7.0-4":{"name":"@creditkarma/thrift-client","version":"0.7.0-4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"next","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.7.0-4","@creditkarma/thrift-server-express":"^0.7.0-4","@creditkarma/thrift-server-hapi":"^0.7.0-4","@creditkarma/thrift-typescript":"2.0.0-13","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.7.0-4","_shasum":"7c188ea0768103894657117da5bff9725fdbd79b","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"7c188ea0768103894657117da5bff9725fdbd79b","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.0-4.tgz","fileCount":58,"unpackedSize":200720,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbEYbkCRA9TVsSAnZWagAATI4P/ivDIZ6LXwJgTgz/rMfl\npczoz6ufYHFugAb9KNEijFxb7mHtLKczNj8zRNaQGashbv1Qk1kf9pQvqjr7\nzcPpo2ZJ8f0mIJ0gUCC9WPmHb4Yz8pdI4VC119ZI3S0VtvqoAkrG2eGXaE/E\nq79ZaN6CmMnmgaOBBzhhNMtpWh5wMpBXlJiNPBScpuSqWVW2NUU7au+vKFh0\nvvqo52F6gfz3VvFr7y8wNjv5MRUyV/ZYEZarBTg8et49aOHpIskjpMVpv1Eh\nTgODz7RVph9rX0m0F0jaCL+XZP2Sn2HsRh1+UDXoVu6Ibco5hibuBfY0u8cv\nVme8S9SuchVIj1yl4lLvvhOvLabANvBcOXGgaJEky+HvbCJ49C+JDFgSHhm0\nvkZZ81rCQpn6d0QQw2IUrFchrcQeIk7ZW9tHeu3DBmF7UiuYkR1z6uqV9LeS\nDaBYGLhI53QRA7eUjf51zCBrjniFrgPCaWgt08TB1st8jJnL2jH1TVlMCeH2\nABZsaGxY6hVAtHHl4XSgV+gMVEil2WcGy6Go6AEVxlBF6i5PHQe2HvZ1k2Fo\nNlVmMhhKnku2RZJDhZoCKUk7j7JHK+0t0TtorKZK9VAZ/N0dxJr6r1Jv88Jf\n/XdmJvSqcWNf93CcgQh5NtjZDbeVt4wkiXz2hbXWjCZWZYYNIlxKzgWEgH1K\nytQd\r\n=NXJx\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-8X+YSZyB0RrsiS+090fu6jWGuJmPacXSnD0fCnUFfZ7H5zSSaCaiupECeugj1iXDRfCdjXo5XhEKOp6mYXbx2g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDLItcaSbeBF6lmcPNR7INpgvCSUZKV10VLhldYsnq9QwIgF0h90tfqBdUtR08JZsd9jMjceBL7ACn1xcNnc4vg3UA="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.0-4_1527875299980_0.646634303107309"},"_hasShrinkwrap":false},"0.6.19":{"name":"@creditkarma/thrift-client","version":"0.6.19","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.19","@creditkarma/thrift-server-express":"^0.6.19","@creditkarma/thrift-server-hapi":"^0.6.19","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.6.19","_shasum":"b9927e43421d90d1e6148461a2c251736ac86b90","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"b9927e43421d90d1e6148461a2c251736ac86b90","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.19.tgz","fileCount":58,"unpackedSize":182482,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbFYYYCRA9TVsSAnZWagAA0n8P/1c/ixsnZOU5faZWa8Jp\nAb4XRqG6RGCvQDtAdTC7GAebw2BJnlK3T8gb/v86bo9Hm+/8RaAX8bjUv99h\nXvqMgIJT/wpiL2ArJd2qE3yhlgj9bYza+VZUpW+60/iyE8zu5k6MKEtUvn6p\nxuKclOT3i1OGhiDE7hX+GmVBED3QtquN6apVqJiBQ77vLiUFFhSeon3qLZwb\ncy9qns2fcuX8gR1S8Xobov4PmMSxELj9JBf72ddKW9csdU6Hc38rMLocywlW\nT96fgAKSjDm/apwxQRc3CIju5A8mJWVnVudWth34BgiIKi2aa5/Zgs8upgeJ\nKXPJ3+++j+YlSiw56MNu9qLPy11cAEW/aHaUWDrmKOjfKl24LftivYsv3NiP\nA0rOgAx603y7+Ey3RacJvLhC+2YDoqt2xXnSkNK1oHwzfr8c5Mb6rPonof/Z\nSHYH3Hda9z2hy81xQ+ZsZY0wv+P66R8zXkzcpY9uPL0Q76sMQcfXLsAEZYXN\nA7NSyYfxTvV2JeBriWazTqt6KcoJTFFh2H0dqdhcpcQl9xoMxbpPlx+Yo91x\ncBOKLAqwuRnVVN5ucpBAdM60d0ERBGWvx7H47ujhTJK4sRRXyYnLAhEdVk02\nYjqdrR5MJc8sc3F+PiRhWatsrYu/UTmP0t2uTivW9ixQDuPqbWy1wEtLCS8M\nSoYa\r\n=6cdb\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-O7Na2oUUH3B79Cdr+JNAsAz/3RQal7zD/YOh9m7AjdrWnLF32Eikllw+R4cJ6/aIcgzEDZGQXzYIp4nuEo+1Og==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC0VyvSYilsZIGkw4kF2xC9szJZM4VpHOWB/Nt+R//7rAIhAJz5npCZPy/aDWmtowF6sn90X7Adxbgt680T63zv0CA5"}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.19_1528137239463_0.8581849859684976"},"_hasShrinkwrap":false},"0.7.0":{"name":"@creditkarma/thrift-client","version":"0.7.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.7.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.7.0","@creditkarma/thrift-server-express":"^0.7.0","@creditkarma/thrift-server-hapi":"^0.7.0","@creditkarma/thrift-typescript":"^2.0.0","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.7.0","_shasum":"f5aa4d54f300f36978911f8f80038c4fc35d42ea","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"nnanceck","email":"nick.nance@creditkarma.com"},"dist":{"shasum":"f5aa4d54f300f36978911f8f80038c4fc35d42ea","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.0.tgz","fileCount":58,"unpackedSize":203829,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbFaJCCRA9TVsSAnZWagAA/2EQAJZCauSucdnioxTDSQvU\nXq3ckAFb7bP3iHIP1TXpehuYHAeeRc0hpbj2KvfGxsIXwoKtx1MbrvZK0T1M\ngK/htxABrTIWQPAqKnoftC97BgGMYMXigsLhTW49tQPNThJ3BxIn48nlCdAr\nwaaeAM6G0FuqFz6c2FF1ddHi67wJQEZtKzFwptRZu/BVBdOelj45zuoBa7Zk\nhV4RzEFqa/VGijtEVQoAMw1Grkr6uKSnvv3SckoJ3l/urXCVMZdINnwLzRGZ\nmppTUbUcJQ4QgnzHdJn8BxDWiwQXomiMwd2RW5LYM1vZRV4SVlF1bkRytApu\n14n4nS3tokWtoaq9id0jVnXjOwItTgA55cdODcqpGt+KqR+zr/d1iBlrU2X2\nkiVJGxdD036W5oSdDpE1uWGvGf1D6wO+inA8T3VSJPQ2e+0ensFqTlu/wsYI\naaRq7htLZ7oFxngHGi+pX7nnbRdUmspj3Fm3Jkf6lqDdw6yb9By65Z7mJCFx\naP8Wol09Gzc0jN97W+0hQb6FVI/DeVMvHoyX0nA6h+OnpU6/RKLeMxKRMtNv\nrfxRLV5iXai8dDFTBo+j6ZTEVHzRJTyGd6OgBJAil8sicHWqbsqJRS4+xznp\nEBWtGAIahx9EkaUyKtmCFYONY8EAqdAd7Gpe+OJQ5sWoEH6xGbSdqjdDENFN\nxMGP\r\n=CtC9\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-Wpf2Hh99LyKa5X4hLgkRzKFUkaEKaWRMAG9mdsGkju9U63RfyPTzoafF1eGgoUbrLeZupdVXOzfyzNUpagrEmw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGSP8h54kl9lyAN9OYzFtiIPBMe1mtppUvpbWzC4G/ywAiEAtfeiEtQwl5vX205LcY/6pBlGIT9wQii/DBVsQKd0RsQ="}]},"maintainers":[{"email":"alec.ferguson@creditkarma.com","name":"alec-ferguson-ck"},{"email":"ian.harshman@creditkarma.com","name":"iharshman"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.0_1528144449490_0.7981732481078891"},"_hasShrinkwrap":false},"0.6.21":{"name":"@creditkarma/thrift-client","version":"0.6.21","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.21","@creditkarma/thrift-server-express":"^0.6.21","@creditkarma/thrift-server-hapi":"^0.6.21","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.21","_npmVersion":"5.6.0","_nodeVersion":"8.10.0","_npmUser":{"name":"ouranosskia","email":"UGAPiro@gmail.com"},"dist":{"integrity":"sha512-x6FBDoH/lY3a2IvoHhIXcIRRXfkesewD6mEHIMXzv2cHBb4SBeigmlZJcNm7WcWnt2J4OWubv9UNVw5JNLJJ0w==","shasum":"ee046b3c425833ee0f6abca81c407f4ed773ab18","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.21.tgz","fileCount":58,"unpackedSize":182940,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbI/RvCRA9TVsSAnZWagAALFUQAILhfLyOtD0LMbkJ7epZ\nTXaDp91Y5NYFcVWeB3Vvx0hwDBbWk/Kld6ZlGl22e2zMiGUzYx2wU27Is5MX\nVWUvwSjqAF9KKvMd8PnT1vIVcJJclIpxDSwG9p0IhCzN6k3GPEig4Yr7RjXt\njdbR4CIKYNHajhmyGeuwCwFFPRNQYfZ8n3uWINDAUjYDPVlmNH4QIk4u25fP\nU6VZhyeFd5OoXgO3aIJijEm++2sT1AA2m50E+in9iRsMrVA+THX66zkgdpsr\nZJMI533hFeTjwln3A1bylDk/4vVsHSTuq6MZRIcvLht7WyQtiklJWSnK3ATk\nRBn4NWw7qO9qxBVKAtsN47UDDEWXYG9MQPXTnMTeKPtLHGGCFBqS8wJN17FA\nscH2MVSz90D78stbO8LYkcxk8yfhl/Xv04XvjnGFEQuEf6NxgdRgjl0ZpdSm\nRWv0021moJhSAiTUYr65MyXWWLowsr6kOHJxphbb23DQfXuuu8PJMAjG6ZMT\nYi8UBgsZWDfvQns+91BkFAA6BZxZgG5j5+VPPDxaF9lZQ0f43epH5abYwrpc\nL1zQix4MH0JtuQHWRfTuMN4Q46c2X25ERC7cia8vQn9NKhMAISdl7n+U1PdB\nA22Vy+7X9kGCw6ZJLbD2rlfcjB8BDrKrAQc5BV75xYeB+/7Oh7EvX5pmr0HS\naTI4\r\n=dG1N\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDBWt//uf7HTsDqEuDHsS5ChwwP96JsQFbiPx1nuzWCkAiAuxEADv7Ul2GZOIkc4etRlVQQkoKRe3ndpD8wYowVkEA=="}]},"maintainers":[{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.21_1529082990935_0.5588001062515258"},"_hasShrinkwrap":false},"0.7.3":{"name":"@creditkarma/thrift-client","version":"0.7.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.7.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.7.3","@creditkarma/thrift-server-express":"^0.7.3","@creditkarma/thrift-server-hapi":"^0.7.3","@creditkarma/thrift-typescript":"^2.0.0","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"_id":"@creditkarma/thrift-client@0.7.3","_shasum":"dd47acdea8df6cd02350a8d5bd6b0b49d8d3b664","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"dd47acdea8df6cd02350a8d5bd6b0b49d8d3b664","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.7.3.tgz","fileCount":58,"unpackedSize":203345,"integrity":"sha512-966FazVumuL7v+g6OnqEoM6GqnRY5h/OzvDXIXMaC3DyRGGQN3IL58+JPhOD8aaf4HZQnXhTf0G6Sko4bW5YNw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpn2bXj4jUd6SPOy+Nla7Ibv7IabGwlvhYfh8esSMUswIhAMjyoNljqRCrUGk1z0BgF7MlK1O9cqIKugjKGq5vegHd"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.7.3_1531162085742_0.6408671211527137"},"_hasShrinkwrap":false},"0.8.0-1":{"name":"@creditkarma/thrift-client","version":"0.8.0-1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.7.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.8.0-1","@creditkarma/thrift-server-express":"^0.8.0-1","@creditkarma/thrift-server-hapi":"^0.8.0-1","@creditkarma/thrift-typescript":"^2.0.0","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.13.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.0-1","_shasum":"816354beb5baedb21c523a4e5c52cf033c046612","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"816354beb5baedb21c523a4e5c52cf033c046612","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.0-1.tgz","integrity":"sha512-+pTf+CQJJvzZVUk6UCy6a3X9zbzBZm/YWCg4RLL2+IK4KtdJT4gyCefxTlU299ltLJTY+6mDgMDgOOAHbm+NSg==","fileCount":55,"unpackedSize":200712,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbdaXHCRA9TVsSAnZWagAAOKIP/RuQM3ZjnGG99+XyEHg/\n9W+F2r54SQtDl8g6/WWCpADLTZsgZ6sMP+L7urIQcWjC5mwZm9adIBnsHhxN\niKtRFVOfTqs+UVpPrsgzU0BDBJ5hCC31rp65z+U4v2fgS9hoIhn+kn5WSRH+\n/hpjhcrwUsACt1d3nWDV7aD8pEYFxeu1QNjkcKXJ4H3HOpIUgZVapd4D9Fe5\nfCkkKmNWtEdQTYxqGpo17GHKdWKhxhLNvksWM9aYBkfHhbTSLnXIctyjx4gA\ncQNF9gnPuzLqJg5N3aPLmUO7p0k0Ao7ce7Kjhq612H6zqzKJp2Lm1b9KaErk\n+Zc3ugDaMPp62QiGTqJstspAdqUWQLSpdV5+xMCJC68negUXhdyKGInQ8S2H\n01Mc0hweJZ34p/xfFBiXXGdNA+nsuVgE8d7UAbd5ws9koxxtGXnVjwTFm/0c\nhgIrXIA1bbs2qbM/7FcUNLUaJKpXnuGU64i5jpgdQgBO+SiuTWP3ioXZe2Dw\nGEXF95ZOAST88MY4WXUisCE0Xor+/N8XIgDsJn+qStBl4QCOzG8/dl3LPe6C\nirm0oHsiwahxMR2ek77z9vWH2wV2KloZ7QAILw1J6l9IbO8g6jx94smAE1Tk\n03U5PTIPasfr28z3x4rfudYI8iJUJIkxN1hwuAle44voxUJuCoLIUvWCHwZ3\npLC9\r\n=4Ra/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHQOOYkZ3kFrsXLBSLrEPLJ3N4FotfGWDbly8Mhh3cdgAiEAtBlQakXXFyXd9l9rhkS+6KJCjyLKFJCrCBLSqhDhFZg="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.0-1_1534436807012_0.20694421475447888"},"_hasShrinkwrap":false},"0.8.1":{"name":"@creditkarma/thrift-client","version":"0.8.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.7.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.8.1","@creditkarma/thrift-server-express":"^0.8.1","@creditkarma/thrift-server-hapi":"^0.8.1","@creditkarma/thrift-typescript":"^2.0.0","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.13.0"},"_id":"@creditkarma/thrift-client@0.8.1","_shasum":"3072c234fc7e71d1db1878b9cf17c5d60c602913","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"3072c234fc7e71d1db1878b9cf17c5d60c602913","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.1.tgz","integrity":"sha512-YgoTY7uaYewKqgZSDpzuImf0vFmpkaBnjENkxlTwGLteMpicbxEwrPsFJZlw7JZdRqgdyMeT7E4/kRW1uybIEg==","fileCount":55,"unpackedSize":201632,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbdfKdCRA9TVsSAnZWagAANxAP/jic5OE5MDKK917g3/4I\nfU4py5zXTu+rqt3r5cVGnoDMtQ4XppEEopdtWhk2Ihzt5fvEdctur3TLHdtl\ncDzCjP2Cb6OYWJ0WFWhYsj4ZdTjXoerDN8k9BhdaQLWtAopfEllPdkzc41ps\nVvgzo3260+MeXqe9tnXPSFHxq0Pw/9vAKxMDBOqgPchNx2CnuuMmAcnPKSVF\nUdIY8CPxiAmReIJdXdFZ2pR//ifdjLnZF3Ol4vbdhP8M8XJqTgMZ6LFuOSOH\nOoMTu98Jg0py7RBcGe7DAQFAPb2nG2H0xCA+vq656N3BH7wuTSxtZ+uurro7\n5+yRJ+ZLPbTCdWvBazRPyh+SVRPsDYHWeFrgGhqhZIRCvJmWXyEUZ2LgPz/n\n5qxBaOuVlUSAWYmaAeNbS4weZ1fd8/GHp4lTBbNZAPfeJnO4GSWVK+2wE+EF\nYv9xFYK1ejp8kOe/nUF/oZCoLnuAg5aY5G+NgpzRkl91Hlx/oxfr0t9ThUps\nmUQy40fnKgCt3pi+lGEyOk9zKnKP/FhVz7p8UVvW+JoCl0FTMnxYIboU2lMI\n9auayF+ei9Qy2tK8XNUCExX5j2XqXjrVuXkzlflE94AzBvEWtA9lV8glpqVa\nD/hZVUCfSiRN6WfvQlWmmusu+iWXFBUyIJAxRAWaF99QhOVb//46OFLyA1az\nCZyk\r\n=E1UB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEBeOZavusTXYsLYQoIyVGXwAi371xvpmjWIg1UgFa6qAiEApxPTJE9YeiiY3+kReJUbBafr4z96l8DQA1do17+zNKw="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.1_1534456476311_0.08817607339294664"},"_hasShrinkwrap":false},"0.8.2":{"name":"@creditkarma/thrift-client","version":"0.8.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.2","@creditkarma/thrift-server-express":"^0.8.2","@creditkarma/thrift-server-hapi":"^0.8.2","@creditkarma/thrift-typescript":"^2.0.0","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"_id":"@creditkarma/thrift-client@0.8.2","_shasum":"bdd08d80341207f92c9d3b8bd6979fa2f2849cf5","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"bdd08d80341207f92c9d3b8bd6979fa2f2849cf5","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.2.tgz","integrity":"sha512-FeynptXbp+MApZJSFp4/OHdA75hUHgCXZle6+/tbqTzig7zdHWqOls96SAzgpUk0b9V3iNrwi5VASA9LF0eSKA==","fileCount":55,"unpackedSize":201673,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfdleCRA9TVsSAnZWagAAMU4P/3HC4N20TlPiwQqWV6pY\ns6fduCSwLbvC5Dz2NHJ3pmQhR2mwCL0PFWwHFil8TJmHnDSJpgk+2JKzg31z\ns7m9vGlnhMeLT9uFnWPwO8qMDsiFJU4kGW0grU77kuVh7KZRdnSC1aLtJGDN\nm8DK0p4SLRIAHAOZc3foDzmDnnBToav0jRSNHVdO0myzT5WMBTbJHeqiGeYv\nS2kwzcV61K1IaCtpF2m6fqdHC+w7ArC7d/lFVNtEPFJDTmdGbv70wZy9XIrk\n7qtVHrUG/cmB7B/4L1JtyaCkTWliGBEXYvHvZOL3yodfKzb5pda4JW20DBhm\nE51maabJyDpjedgK2a1y0C9vQEzUG9qNHwTp2Lj9dbOv45/j6CytBMiq3p2t\n7PshRTCzSFz1c61qOAUnl+OpP//RJGYxNpmDuAFq/toDloqWn3UXnGU1FV7Y\nD4fg7SvyWJsnYBAWUvQjJjkloMhS7kyfSzQWv0ooJ9jJqL57gNTbyIKXReBZ\nhpC/Mg4SZzQkPA9sLTaHm1IzX+rW7oEHBgVlvrY/7XuKU/f9LKmawPP8JCfo\nOVeNyaCVRRKLx3NhEDhRgQ/KARp0dpaBND2OdBlIYXINVKfuOnpAnhNbN3ed\nEIj+G8kWlhncbouZFnLqz4gAcEXs4CU0ZcTnv4fhVET2JrZoJGKsD5FZCd6g\n9dC1\r\n=Md/y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOgaf4crijt1T1d0CGEoOPTzkJa42zaiU411z82amsegIgYca/Vn3q+ejHFNi5nxHORFG1Jk5U+j4zxu5KFqEAd7E="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.2_1534974301875_0.01272355973993955"},"_hasShrinkwrap":false},"0.9.0-alpha.2":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","files":["dist/main","dist/ttwitter"],"directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@types/request":"^2.47.1","request":"^2.88.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.9.0-alpha.2","@creditkarma/thrift-server-express":"^0.9.0-alpha.2","@creditkarma/thrift-server-hapi":"^0.9.0-alpha.2","@creditkarma/thrift-typescript":"^2.0.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.4","@types/express":"^4.16.0","@types/hapi":"^17.0.18","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.0.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-ydaYpixVUCa+lcba6FN6Pb1I5VvbbuTTmqoQECjxPl5xcduTNYhfArIlXhvPVg1hfJ4NtdfsYbU9mY6XDgwaxA==","shasum":"e516737c30fb6bd2c686259e7238272c940cefa1","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.2.tgz","fileCount":55,"unpackedSize":201754,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbhXV2CRA9TVsSAnZWagAAZfkP/jePzIPAnR7e1mD02fc2\nMwRT2xMGTwbyoMHfObHouQEIEYYWr4uDbSTbuQlVBEsaBDlHgNiQODGNy23S\na/Hi05WzhATy+g7uoa9/b/+fqHiP8UuBvTjmE855QF+JGgrvFbnVqA+W2gH/\nHlzt+JGkcH4/9sVS/XFqQ5IwrNEp/98yN1HNn+1+YIPvp58WJhzO8zRddwkA\nGFMwdBuB+1aHCn2xt7UILfBZsJC/jbD3jUpAHyTt646MtY/CYEPggUhe3lb/\n7uP2RZ/G1QQtd36vZ+ZmLA+21A+r3HyJLUnNCHRHVz8z9chrGsiJOm/jJhPe\n52cdfkNSbS1WDB0eVdUue9qhIDa4AMkJ7tNTMeCeYhQKBmd9DuQ7CeC2ksTQ\nTZgTrIBsgtSPWdqPaHglPd0VFB5yM6CrcXuUr2O2cQ+n85ZQY2s+l7d2QIEF\nukF7F2kpLW6kRq1ruSe051hbGjINGVlwRVU8EZOXle1YW69bo7HqshEP1+vy\nNM4UK/olSVRy50Wjx4UCSbBsCUbPeu4Ce6CJsVzITpVv3ucf40CaH+kdmd3M\ng2B3pdfO9cPM5UMz4quOoMwK0bCn69DiFXH4z+VRwP1YoNwanRuf3MEizrVT\nhdwHmIWhmaXEgOGXlLmgtFKcs3c8qSyJAsUO9/dU5fus3a+XRAxdbfVr2Ti5\n2gfX\r\n=UpHP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDhvLRh/rE5U+5QUhCBtv9JRPQHDpdpDC1shYYS8Udy8AiEA7d4WycZek/T5LVj82jdyzaNldK6rKqDCvYeWM04Cfgc="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.2_1535473014114_0.8410572631182358"},"_hasShrinkwrap":false},"0.6.22":{"name":"@creditkarma/thrift-client","version":"0.6.22","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.22","@creditkarma/thrift-server-express":"^0.6.22","@creditkarma/thrift-server-hapi":"^0.6.22","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.22","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-+sE36P88SYrXoL2qE7TfZ+H/HyT9dsm0uvEsMzLmnFG8dmwAYuDMHG2nhWl7SAbRoQBody0pwfvexnm8yBjk3w==","shasum":"7b2904d9e9300199fdd9efd35d568163aa5b9afe","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.22.tgz","fileCount":58,"unpackedSize":183299,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbiDvACRA9TVsSAnZWagAA74YP/RmOC5szFHPepbSIdlev\nzHIZuf8tSu6f7ulc6yfznSCridhGf0CTV+oDVbb1YVH15Xwdn2V35ycuxgB3\nanERD37CssZo8uyJnV3U6XPh/fECvMygVLhpR28/OELcPWlNJn+mx0CdQy3l\nMW5YBSs7LVV7vy/Rd7vZa/7us27mN2Zx+gZnmPPcMbmHEbJIkWnCuXEUFLmB\nKSOPszdVumMM3A33yqya5kofcSN1+refcB2eV523WktD6CT64dASX2zYgGJD\naFAsBdh738u7AdJ4hiBvd/ietPYsdqEDgCQvl//7ssqZIGlVuHYe4LKZ3pUj\nDxV2BkWSzteIB12zGI6cOlYjIapI0zJDYMv+DWB47tpnULzn8oMLfni/Ryq+\nq/6aQA+un6IQpQOX2lC2lZWABjMu37fj3AdHiqlTF9MnHqVQAbnV9BtRGJZC\nKoDw9KqGIX1odCv0wGb93O0MQD4yyrq3rkIGE1GcVx0kHDplmXwPB+E4WE7C\nzjRdCgX48vi5P+BtRPMvXsu4BtbLV7xwo5DUv2SoOLBm94HboFKd5yh8oJve\nFjulo5lO/INUzvWArHUapejJRdPEYxckpvoC33v1eBX/t+UfFfD7RlASvXQg\nCOevR/lSiLOnPE1swE+OKmFxratOj0vXsNLQ7sQ77fyWemE8eWQsyTJJpsl4\ndjqg\r\n=Bzh9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBevuKViA3hoRVNcilEoAw+2otr6dvm1EL3Fd79dsYunAiB9jg0vpdcBGWYzVTeY0tfPCaN4segtvlUTWt2T/KhfhA=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.22_1535654847229_0.7892882537902723"},"_hasShrinkwrap":false},"0.6.23":{"name":"@creditkarma/thrift-client","version":"0.6.23","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.23","@creditkarma/thrift-server-express":"^0.6.23","@creditkarma/thrift-server-hapi":"^0.6.23","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.23","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-qPcI0wArnHUosxPuKDL2nlHb9YDNh0QAW3zCVqf+Dk1L28RvGSk7GEZjWLWUDit4ig/tRBsmGK0qicH6WQNq0g==","shasum":"f75f67a2575fefd8de55244e03fd9da40a8cc409","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.23.tgz","fileCount":58,"unpackedSize":183299,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbiFM0CRA9TVsSAnZWagAAaJMP/j8J6ojs4Wjbpp0lAzRO\n2meGNM3oL8Bhoiqf0yCqDIrtXK5fmpYCx52O8WV4mDv2ChWKZ0Vl9qREf4MB\nzLLjRRnXk+tbbzffdMUjnZCSmXDUIGzRUF3pyu6AFzjfxhaZV11KIIWy3H+a\nek2hmhMSPUSb02AKA//7azm7CCcHLQ0/pou96V6FNSHXYSpBtMmrDRI0GM31\nQmwkBSpMXu3+nZLtKM0JfD8fqN4lKMkuHy7XfhJTgzkrpufY3wdBIkzMC3Rj\nHLYu5Y43GymE1JgncuhFJvK2kzbOLi0iUJ5tmWlOcNfrpA4eb4tyu7wVjzvE\n5K87Ho5UgRl4LL4WXlL3wJefNgAwLOmsELqwXUuuYhN1h7xseVYF9ftb2nR0\n+DEE+qKEoKVWCmZTjdDQm+ZUxsLYukKi8k2vPSB9fv1jamRuHvNx7Wc+RhsS\nMw+nmYLtSYTDkaFvv/y7p9JpHCPwbjCf3QV9VGpmoVEcZnvSBRcUahmRr8A7\nQIMLRs1S8o7/g2pooCqqTPQiXQbxDcbyS4pV2OpSLScUmy2tmvUmLDKTdKen\nEGa5EVLkhAHV3m3JLTnnDPOVJ/kgULDkEA2E3kPUTrydLWldizuECx6P2Pqc\nExDIv0jGh5HjwaAoAOXtjVNSxg4wue7Pry5X+JGeSZGCaoeoOevj2GvJ7EHj\noXvE\r\n=cmgf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDBLfNJAnuRVUhcJ+fbTfghdWw9PhJWOf0VQt9ow45tKAIgV6L7lcXu2iVFCDSOZeXwo8WWkTb3JF+aergAfAawBfc="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.23_1535660851415_0.15419914252772005"},"_hasShrinkwrap":false},"0.8.3-alpha.0":{"name":"@creditkarma/thrift-client","version":"0.8.3-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.3-alpha.0","@creditkarma/thrift-server-express":"^0.8.3-alpha.0","@creditkarma/thrift-server-hapi":"^0.8.3-alpha.0","@creditkarma/thrift-typescript":"^2.1.0-1","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.3-alpha.0","_shasum":"48a33c9068a74d1decebebe3faccc6f47f821401","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"48a33c9068a74d1decebebe3faccc6f47f821401","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.3-alpha.0.tgz","integrity":"sha512-JIAJiImxHeUf5m+bY3XIdq55CRNePEkGGRFDleC8C2/g03zS7NUdbqQu0iw0YDASrTXK8vQuiJhTj+rXlGMrbA==","fileCount":55,"unpackedSize":205135,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbjtMmCRA9TVsSAnZWagAA7gEP/RsbO4R5bo6xlfkoAnQz\nIh1yLSms4AmhzbE0uQCE0ZeW+3xSgAUdZbiYiVY4oJs9tvwZulHq/J4PopZj\nih/UL1/NC1UGQcGHYnQjAmBptsw8FDdXNzd8M3Rk0MjRz0fa+G9QzzexZOdy\n5Fkl5nvuUMDaG8kwnhE3aovTNZstG4OxGU5yF31Rj/2bwedxY2OGaUoMjzIz\n1iDW6vlWnni4D8w8LreCjY/g8XQod1McDcjJ8nXhOo/PaJilkw1O4yAM8Pxp\nU4Kh+C+GGwtcbVp64n+N/8P8aP74jQzOzpk59O3lyxo03te/T94fL4/MZjM9\ni3gHcnFea82Vx5CtcLKfTfTVr3kF+GKnoPI6+kgug3YJqMT91yImO6uXNdx4\nofCvPCMmWOCBG7AO3IHiflWPd0PKXBXGS6btz7Yq9xSKmQpB+73E7U5rLKMG\nEpq5ZbRHV/QGWrOW82WWCk0mLWnHp2Z2C6h0m+oorIHNFT7FnXYcT4ThVYgp\nxbivxAmLvN2jw/OuWDncrr2V2M41Dv6p/5Jwle0azzc29tIWfoEoYMAtP5Ob\ng5l6sstVRHR6J0NMsbZcSFzrVNqinzlUf7n7MmH6fjj5jwGkJa9srFamNgE+\na8nDpjEyE94M2YpGfSdOvudJ8ZN/Ywq3E53Kpve0X/CfK//XHvgrtjzRllYm\noVBW\r\n=IxOp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBNUq/TKBnOBgIeMAsPt96Fr8TDfyKWgBM5imxjlXekGAiBYFuAE4ghk9aDljmA7xKvr6bnMz6U9R1xqBXPN6f8Vsg=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.3-alpha.0_1536086821715_0.2129701170100995"},"_hasShrinkwrap":false},"0.8.3-alpha.1":{"name":"@creditkarma/thrift-client","version":"0.8.3-alpha.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@creditkarma/thrift-typescript":"^2.1.0-1","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.3-alpha.1","@creditkarma/thrift-server-express":"^0.8.3-alpha.1","@creditkarma/thrift-server-hapi":"^0.8.3-alpha.1","@creditkarma/thrift-typescript":"^2.1.0-1","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.3-alpha.1","_shasum":"0f5a4b1b2d5ae5ae11e895dcf804e30e80f2c2c0","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"0f5a4b1b2d5ae5ae11e895dcf804e30e80f2c2c0","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.3-alpha.1.tgz","integrity":"sha512-rBMuozbi7gJVUdFKpm8Ow39RJC6X0fHXefPbEvB0OrhdjdIsIOU9dplrjBXWjynkghdqU8ADFtIRR/AktcS8Qw==","fileCount":55,"unpackedSize":205185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbjumQCRA9TVsSAnZWagAAfvUP/RIM9R3q7Erog5kzBFhS\nTmyjpjKGu+uoQOlrbOghAMvA0Dk+HTDZjOEKVqGSxcB4KCR1xQFGWopf1ZQ6\nLf9ZwdtIhhZ8E7ltCD2fSB68Voj3+p9epTF1wHHULGQiYtcJYTfOzi7rhvHM\nKweGQOijJkmzb21YDfYULKCVyBSVwqGyAjPZcdaw/86G+Fkadcr+N4Z1z73/\nxx9g5gaSjRRmTfqmQEvUMnHj++DPX+4JR+TUrTKptJA72qp+wMMksf1QYMMQ\nauGRZihIIxrMWL/QjzrepAKy7kZlAh3BLU9/G7fMjui4CV4BIOqRDxt452By\nXn3o5xNPSMts5NDWXBEb0FLbT67hROqfIu+lgOa7PaK/lovl8z+hvuxPDIP8\n+UiHld3/sJwJjsl3ndzPXXL0nCdi1A2XfoOnLqIkg4dKkrbGg8W9yBidDBxr\nu1OFb7eo7XiNVX2ZpzrvvEZrXwFSSI2qnX9nUa0aUZaxj+v3kU3nHMDPry8y\nPWJBJPP3RuAJvIejmkiXAr34Or2oeOETHiSqHXeUtR77uavhtGyC9GIzLHGT\nIQM5sAb/PjYjMueF5kchgzKs07vOpAxUk6cQDgdIGG0R5xWGS2DClc8OJAUY\niOIuP6fAliaNmwY247Rt37+cP+2ZBoqPGK9MXamhr69ZBmlv2cvIZMhMvjlU\nlhkG\r\n=4fCb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChyMIO3z/0XTZzzSmN32D9nh2gWs0o6/jRnIAx9Q9h/AIgGnaXeIRUC9LqNEeF+J7EiKn4m6QbYb75uV1Oai1xv+Q="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.3-alpha.1_1536092560182_0.00613559053664714"},"_hasShrinkwrap":false},"0.8.3-alpha.2":{"name":"@creditkarma/thrift-client","version":"0.8.3-alpha.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@creditkarma/thrift-typescript":"^2.1.0-2","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.3-alpha.2","@creditkarma/thrift-server-express":"^0.8.3-alpha.2","@creditkarma/thrift-server-hapi":"^0.8.3-alpha.2","@creditkarma/thrift-typescript":"^2.1.0-2","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.3-alpha.2","_shasum":"8a7ee809fe4b5ec2da65904308dd71a9aa7ec450","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"8a7ee809fe4b5ec2da65904308dd71a9aa7ec450","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.3-alpha.2.tgz","integrity":"sha512-qMVEJiqQBa0V6r1TV9dWXgHPfwQdFu7XnMwRDHIhAEZU8NvJHu28lVRXpaROXHAWIyRfTDuR3YQ6ALY0r+2rpQ==","fileCount":55,"unpackedSize":205185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkCe7CRA9TVsSAnZWagAA8gEP/15LnVK+V4XlSDof7Qp5\n0CffzJ7/rNSADysA5q3msXaS7vRS+HtJ9MWevNrdWHPLaD/AZHo2sabMDcIG\nhah38otY4bcMSp1g2/jviEVT5D4k2sYLvvnnLcBAFOAOjjyHsC0hEkU9bANr\nNQcxUIKgEva4nqFq1STnPEhgx5iAIX2szhe438h87Ymps1BelJ44DuocqTjf\ngJoBG5DjvARiFAXnX+muwkvo7jhyla1nXqVf8odl2a7QqvS4KCeizGgneQQF\nbXigSw5NZ+iJnPF/k+3Ck5QK9xgkWEmuJD/OVvZBmDibOoMQ3eOfl2KzIT9C\nabwfsjRu8dYH+ImHVp0C5Y0UpI0aKcpNLvDA0aIvTRptOuAviu8RBUWhjp9+\nz5Tff0XoG94iWc9rhBU0mOEiDf5vEpPPcV8E+1Bz5K1C+ph5DdAcn0XAJ3dw\nP4W40bBqidqFFiBEHe3xr31CtkPocMgnFuGjlYSg7cciG90mCy1bWNnR5ry+\nzk/jw1NyThURSDqxEd6qPSQiXRpgSIFpUe0SZv9gWsnR8f7rRQVvYoM0+1Fu\nj8njA5g9sG98/NHKFEEm0W0e4+j/opHuroj9M4dK6OlivkaCtGy0AVSGZ3Gw\n9xf1nRrzMZKfaFcyM6TqVQnA0OgDdvt8xckqiPZzapLJebHArcEX22Ch/zlO\nZdYL\r\n=//mV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCMxWRKq3ReCFfCN0ccN2m9ipi6bBw8CDiH6aKktEIjWwIhAIO6O8EC5LP5JMjiSbCa8w0ESHKNvSTVzkhe9cNiFIP5"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.3-alpha.2_1536174010641_0.290599299369213"},"_hasShrinkwrap":false},"0.8.3-alpha.3":{"name":"@creditkarma/thrift-client","version":"0.8.3-alpha.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@creditkarma/thrift-typescript":"^2.1.0-2","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.3-alpha.3","@creditkarma/thrift-server-express":"^0.8.3-alpha.3","@creditkarma/thrift-server-hapi":"^0.8.3-alpha.3","@creditkarma/thrift-typescript":"^2.1.0-2","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.3-alpha.3","_shasum":"dfe56a4a2908ee32db325d66a7cf1f96fdaf0351","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"dfe56a4a2908ee32db325d66a7cf1f96fdaf0351","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.3-alpha.3.tgz","integrity":"sha512-AIStPDHyMOdZ9mcK/taNVNbfRtR3ErStC6ilyH2xWacVw4KLsU33WMYmudIy8VtY5xtIB/ceslma2AcPmdr86g==","fileCount":55,"unpackedSize":205185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkEp8CRA9TVsSAnZWagAAzYsP/38nqk/d1heN4UZU1+pP\nbPwIS227B+2AmowP8pGLHbVXMmPJp7OUkSY0RxuEAylttaPx+RT7bPyHFphD\ne8pJSyHYO3IncxpokeoiQ4hUHnbNYj6D1G+AyWqpYKX9M3seuScnJ4HLQ/IS\nAvjWg/5jagHXwqEuGMfvbwxFk1Y82Ivigar10h0ISfnfvf1C6KjWkCQW+Reh\nUOInVGTXnt31XvtcUIIt+8ucp4xpO8m0lv33q6p+3jhMTRbFMhSduahKl6qG\n3z4+4WXI/6kzEJmNrt7WH7fWAUYzn6ruMkwh9ZnmNHh28acel3JfJ3Iyf/W2\ni76WZgbk5+TNiqQxUtJBAfqEGD0nCsHJfMBWTLPaNJDFPwLD9dpW1HmuES9X\n69fUb4dqnr4Alz5LLJ/YIHFApEMD+7G82EHz0ZQ9Ng987jrSq93SkCgbDKfR\ncovAaIOnDEZSEf7cZzYuHy9dk81qlzJLB247zad6pUqvd5IBgxBiC5/x8HJS\nrF/OgvhALpmWuJPoSERmjSeuLsxiouU7ozetN8HGc/GrjG3lCOQRqGgX1HSS\n4x/IWhPTjFUgpnz4tEoSLd7IlUUZC0cH0R/UCl8OUH6QJcF+S84A7J9zBxO/\ns5jBmmczf+0jyGTcPQVm9BMDc1UbOhWUnPKQedPpl5Az8phusMEtCbiINb3V\nGQ6n\r\n=xErl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAkcZnGA21bvzOHkQzzP/uKDPTYPcOrQLTG8xs6Ns7dwIhAPO+0yFtJ8+OtShEnB4Pqqyu+K2QdNlU5fLWcICB0i/j"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.3-alpha.3_1536182907793_0.3621561590279869"},"_hasShrinkwrap":false},"0.8.3-alpha.4":{"name":"@creditkarma/thrift-client","version":"0.8.3-alpha.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@creditkarma/thrift-typescript":"^2.1.0-2","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.3-alpha.4","@creditkarma/thrift-server-express":"^0.8.3-alpha.4","@creditkarma/thrift-server-hapi":"^0.8.3-alpha.4","@creditkarma/thrift-typescript":"^2.1.0-2","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.3-alpha.4","_shasum":"413cc9a4fd214a9e81d055601fe2288ade425d7c","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"413cc9a4fd214a9e81d055601fe2288ade425d7c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.3-alpha.4.tgz","integrity":"sha512-at1BBIhCW6zUp8F6pHmrdefXbwC9t9GTVzwDOUrspWfcF5S3A8ig52oGvBLpXBqH+kzrwH0qic6mK/M0re8qKw==","fileCount":55,"unpackedSize":205185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkYALCRA9TVsSAnZWagAA3ikP/AzADiFRREcbSPfNErIa\nGaEt+Pv1pQAP7l1T/d0Gk8O+vIqd7qv6LLwUnmd6VTw9YTcf6VkXojwmFUHh\nemPxDM25AzEV/mf3ub+G0+xVAuAb3P4gTLZco6v5MjD+hhm9oTj/LLZ42Bh/\nEoS/TSomvkccUoYOyjV8XVtxx/6Y4imM1V2LASxzevwrMjP1nxXKRuqP+m4R\nJM8BMQgTlSFswh6LfeX//h5ZdmyvCrSoHXo9vks0b/OklwVogqCFtrr3vgbr\nVEdk1ajkaYwSYtKwt0IniDY4Cr5Soi/iepufLZisNnkJkeLJZgreniLkJsRb\npmYYdWDa8ZOSbXGYuXGBeLgTFpG7E+Jhy04mSg32jmav+d1hVgg3Tmf6/z2g\nVnB5VZoEGMRuH+UK9hJwiaptzqTzGorhGdiG3uP6zucyw+rn06tSe8QMaIBF\nD0onkL5Yo7d7dRUX+9pyi47foMUWrz1JYZqkGd56fQVowf0Q/qcpoHHRbyGg\nCqPImDlcRhg+m9dF72txHUkOg/LgFyud5c7iOo9XLCqSbv4AahWjtcbJnTWv\nzfKuiMsBPyYvdZ1w4nBgNb1vx+DqCdmBRodZaFqDWvuWNewKSPBvaRJEUEGG\nkIRGzA44WWCXh0Ll+8G7M6V63HbK1p+5+ZcAkObb0LhlzeNH9II2kkVYLZnR\nJw8u\r\n=kuOT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAxH3hCP2Xb9RIhIBmoOMyJQwyB5mVkBDfFBmda9ZtRPAiBYr2zzWxho+Q/wDwFM4LlN0S/bJif1AygLqgPAPXKung=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.3-alpha.4_1536262154580_0.6591622419612193"},"_hasShrinkwrap":false},"0.6.24":{"name":"@creditkarma/thrift-client","version":"0.6.24","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.24","@creditkarma/thrift-server-express":"^0.6.24","@creditkarma/thrift-server-hapi":"^0.6.24","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.24","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-MpxUHAACH2CvByoVL8op6pvRGjVVgmTC+IvpwEjMBTxJwkF5ViAfCl1BU2er1bPZP4PBhoX3yuqmS6CIBAKWeQ==","shasum":"a9c824cad296c48960c75db7344fc2663d150947","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.24.tgz","fileCount":58,"unpackedSize":183299,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbksSkCRA9TVsSAnZWagAAd0YQAJDYOwUvv3FTUf4/JXDA\nm6+TtD3ysxKit/4Sk3rsubHSdf1UsTG6q/GN0SZOnamybjcVBegioJanIP01\nrQM07x1gQpzcZg852ja1Cef7SjFiZznd3wvYwnlvshoR/D+RNGAgPs7ExLRh\nsaaKuewMBwfailO7AWu4wxF6JiTL+xI7oifVGAhm44/1iyDm6CnebYXDtRFW\nxzPUh4hgdQiQHMJkc6LkmUMDE7H2yTq7yyTLsxkrL4Lub8mlea1E9/P0W8Yt\nIYBPPDXeyjM3oZXRjgovXmHB+AxwArLujEFEpsXbft6McR+ytzl6EiT/f5V0\ncVjMKzcTtJgm7kw9AWyjDTKfsnOigwT96p0S/Z/AYhHMgo8mQULO+w4TmzJK\nuoWTHmKBsQvgxLkLuW9Zq6MukKW1CY9BQYpbC9AkOGnmNIq8mU6xxD1dSq7n\ncbRthhH+xsKJMYgviKjLcBDI7ejBhvSYop/lIcTQQnAvEu8mwFyoNfsmxDpM\nr4Z6f3xNEZ6P1Am2aL61YQJjittgslOTxMjcYrBOLsCU0VHPc4/AlOwQ+/PW\nkLproT+OJX+f9QvSNtz1Zxc6X2iAnHy01zv92p8yfPImXgltYnYhr/oCUJIT\nMcI3YTupi3MLXa/KlhlrRbqb/DVmgoFxFiJWwtn4LXC4VbzYXgGRGtA+FQI7\n1Bh3\r\n=KS8V\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCFw5ZogSYWwSfYCGrTPP86+mmfGBrQvINi8/4G6vEKUwIgOJSty/pIXjMoepKW0L/mz8mS8GX7TeVnV49HW5ncbf0="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.24_1536345251429_0.5816824872659696"},"_hasShrinkwrap":false},"0.6.25":{"name":"@creditkarma/thrift-client","version":"0.6.25","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.25","@creditkarma/thrift-server-express":"^0.6.25","@creditkarma/thrift-server-hapi":"^0.6.25","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.25","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-+Ea+9M4tuZKRNyvtki9t3vNxQ9alS9waxrX33k7EBGn7ckMBxVNy5r/H/MpjeRqzqCeqr30WiPV4RoNuXyiaXg==","shasum":"c492db521e9144bf9ab06f0d9a535dc0b596bc21","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.25.tgz","fileCount":58,"unpackedSize":183299,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbksZCCRA9TVsSAnZWagAA1dkP/2mKTHgfIK6rjjhJNbJB\nBjyyWPPTLgc70RtBwyNqBd3C3PdtRQSaAwg7P1w04gzdG0ahesBzVENp6tzo\nPRTl+aq5mQmRYNrFZZ0XTy9nl2TKiEsG6rsTPxCF9kTSs7GE3qH1f+ZVizqT\nGBINdlZjwI2jEWfCleV/kbMnZ4f7wSmS7WCgS9Q0+gXtPPs1FR8rUIxyGLKk\n0i3CXabNOabwvDlbjW8SIrhiazWcXDxZwXfeBiuSLysecWRUN8+G8CNdv7nb\nK3eZw9GJslc4wiwAOfcZHqx2zaUyKHwILth4mWWfQnXSJbwSwr54Vr9Eypxe\n1bF+I8lVBuy9qugZKAddi8MXZt85vtVilCsXMnmpkL6bA8hJZMvhCFu+5E5e\nzS6+U5iPp1cBt5l9uqYbMiyQDSjcTo1FgoFf9KDB8OI4m2APJVzvqumlRKLP\nm5JimaywHZWJi0H3naDwX1n+1eiXlwsAE905MWNfjg4MmsnaQ1ecVKi/WKtQ\ndpz0srElBgPfZCPCgtVh/rLzl5GYRPAVM3UceB/ZZPiZuItOgDC8GzLQTzln\nrDGnNfKwVOKHN+XY8pJP3oNDW+kOsJeZ8LIhnXsDqrO2o4Qk0Xds5emE5Sru\naOTG55yBnrOVUeBcQyM/Tr723/cBuKvVMXxQ5iy9qlGr6LNdDKfuACZ2zSIA\ncK/9\r\n=PlqP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDNMtk0dGwXpNhdR+9FAjF0vn8ewOgNXl0EywHdtuJQYgIgUzCeeCIDTiWCMRt+dsVM3riTIAlFXxMYtBYjmksDrl4="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.25_1536345666159_0.10233103145914857"},"_hasShrinkwrap":false},"0.9.0-alpha.3":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.9.0-alpha.3","@creditkarma/thrift-server-express":"^0.9.0-alpha.3","@creditkarma/thrift-server-hapi":"^0.9.0-alpha.3","@creditkarma/thrift-typescript":"^2.0.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.4","@types/express":"^4.16.0","@types/hapi":"^17.0.18","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.0.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-WV85QaL9xhZMnpIacQev+jjzAVkTJ6DTDPUFZgnylzIhp+iNb8PH+QU5o9hSn7IfWkBMZnMUAjzLA2AkbK1V7w==","shasum":"ba7582fa6de0095f35a25a9dd3fab02bf2d14da7","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.3.tgz","fileCount":55,"unpackedSize":201769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmEeQCRA9TVsSAnZWagAAZdkP/A02S9bZFEt92Dqt4C6T\n5PWdC88p4nMdNA71Mx+QczAHgHzswpUq3uMZq46KMWP0VbpHFF/CmBSWOBaj\nrQ8hH6h5V56nLs0X3BzrH19HYaS3bSp4bhe62tSENPdD8t/+XmcHM9xS17zs\nSf4vh8Dl1FkHijtwnrc0EtTBGnpQtK0ZirlmWYqEDskVrKu0fdpLB8R5Qqms\nq8VsBtWgKY/rzL+vUiIoIHYszJRVbikG0YSRw3Z3pxzvhQ899wyRSsYxqda2\nHEGqCFBTZzfwkVgI4Mzfnv91FqCFvubXfkV32o8Sp5lzY3Kntz/Xj+QrM4Pi\nZPNiFYWmX/7CZPc5S1VXqbjYIaqMxnXehU7OWpcRNk7pCSvTRGwcOariY3Fj\nbQbZsVnLBbZdt3Px89lNK/eBDW3ixzMfRwVxf8p6nEC/A8mYR/LTqjkMCSY3\nFGuX7VrU9tcluyx9iTQmCpm92jNuFDCmv9rwUHFoPG3Un6mYP+jkEDIPIKNb\n7iuiaiIjsSScfVyQpoH9rmxDyF8m0+biKziiuqcW0dLI6Sslj8TUsKD983+6\nljlw4WxErVyFTUW8uoq8sSCsAl+92dKogiYCM/eVaNqyedpMIuBw8p2WV2Z8\nD447M9ztRMZ9gkffj7S2Qk2lYbNUBnCFl+JdK8zeN2EHmNe1iwvXmTCoY4SM\n6c6L\r\n=EcCz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyl9zlqpiGW6gqZiPd5F/0lGCPhnmAPxQj0fh1yoivvgIgEamhpCpqcV+Abh2288Ol5s3AS1WfXCM1s+uV63rxqHM="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.3_1536706447239_0.8338646361988413"},"_hasShrinkwrap":false},"0.9.0-alpha.4":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.9.0-alpha.4","@creditkarma/thrift-server-express":"^0.9.0-alpha.4","@creditkarma/thrift-server-hapi":"^0.9.0-alpha.4","@creditkarma/thrift-typescript":"^2.0.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.4","@types/express":"^4.16.0","@types/hapi":"^17.0.18","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.0.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.4","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-J0Npw5iuSQtPkv8Ptg+rQ1UvsnlGXOOnF8yk8VzYfSSoJ4ATFmfQi+pHmUhfUSL8qqLdcmX0Pt+R1qcn//WxKw==","shasum":"bd0f46071cb4d94b64f148f4be6aac5e038f2171","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.4.tgz","fileCount":55,"unpackedSize":201769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmU1jCRA9TVsSAnZWagAA9TYP/2PSrWGsEz5kHJuyp3s7\neGQzdr5cYIJrJlCXYDyIuzn8P0Ii3r/D1sHo6E9NlBV4Ty9U/AvD7wGHoTlt\nDXH23/dW7U6jZ6OLm3JqSzV/aHYF6C820fvitgH5jBRuBC6TJ4zJhZmzyRz8\nmBEBLYNxysULLgNDDSelQcP2P2IFuWdbdh7TvtOjlNdkmZTE1wvKtSM8/9mK\nOppjL3ulG3U/69OjKn5YjXSFqJoj2NCyR4npCpmqYt36+YjsPsfjyRp1ipH1\nhMdLo3eqo5gHDICgEbxWBpYSAn+sHFWqP3iUGX419R13u1sBAKBwoW4ZGVpJ\n1Id6+fYbp5OXB0tYIfSeWfJU9sa+C7waMIdluPneDllZ7lJaGhhGb9pvY3US\n0Yxvf+KT1MIjYOeByZYi6sDqbd1ge9ygdDTh0Pr1lO8O/s42eUk99e0Y+lHG\nCCEQX4wdTp4KIQySEpltFtYLFXm7XNSLEypaJbX7yi+C/Bw9e0XlpnYnYI+2\nRitBK9tDEfDbuz3LMOlspowULQe/tJJHpywCzdHpgU2XAvCE1Zip0ahRlVvA\nGBQfSxjXp6ijlngOKwNiNI7e4XkEHe8O/N0oY7/TrT8H/1DoFV49hK00/22v\nWs8XBzTE/6kDmaEFBd7APmR+qn40ao5LHieY/KMlX1706oSBtLd7BotssUYG\nUcJ7\r\n=olpA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHhXau/Hc+foVtDLCTF3iRBkz9e2C4Xnt6nQHN0tCpMiAiAG3dFzElDbvBPoppkT6rr0w94D5K4KGkUJUddFXr8BEQ=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.4_1536773473442_0.5652358301684992"},"_hasShrinkwrap":false},"0.9.0-alpha.5":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.9.0-alpha.5","@creditkarma/thrift-server-express":"^0.9.0-alpha.5","@creditkarma/thrift-server-hapi":"^0.9.0-alpha.5","@creditkarma/thrift-typescript":"^2.0.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.4","@types/express":"^4.16.0","@types/hapi":"^17.0.18","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.0.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.5","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-Ewu3tLMPrGaxR5ZYMc7StQYCQGkrohTFFoqYZpMKK4jM70+uYyI0pd3xWuGILopiIUcusJOGBRux0QtSOVP9Yg==","shasum":"6153160cb5c5fa994747612fd4fe2f7c10318655","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.5.tgz","fileCount":55,"unpackedSize":201769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmVUxCRA9TVsSAnZWagAAUegP/AgLWyeZseaZPtdC8EgN\ndgDKKrFTKubxzCeecVd07Y3rJoq1zb/50SZYR8OKWDWR99Cv60cWR0hf3JaL\n7chUoGI9JXbcxsjUE5G9IbW742sRYTiHgQwDx/S/IjihCsJihsw0eumubUnK\nn3eMf86oPVyMDVb3WNnpPgvcpcXrgdB7Td3gp9fHN/EFi8mBOWUKhL40ZpeN\n9i09YpWjXP+F0jZGsWybyrHQ+nGOOBiYOp8v6Nt1TS91yZfwxNUE5A4N7VRK\n7T1/ytsBf0/qa8VugGorAdf7cNt1RLMXac1xmckP6OelE1zInocMqU2QxTcV\nqDe+uG0eS86GiZV1p/IUQn8bqB5IpX6EonyPkK01nVgD9s/UPxQrowR+jJKE\n+4opHXAA5lDMbgoF1w9wG+MjZ45gXjmdP6Plon8pkVYJLNKC3kcvSYKaLzN7\n7UbJKONwa/3ywqlz/0uTqqMScifTnDMT0Y6a46NO43wL4yf3S9NBdmPQbzDg\nrKBveV2CujNK6AtZeJXKxleEKdYRefqb+c9NOtNs9FIf+qNBesFIFQtaZ4ku\nCWVGMKXijg5xOtLsjrp/BUZV1QaoFyyUlWQ+37JFZjzYdKEFJk9OSlcrB5wY\nIYnNqUveTPT7xohIjMlNshbWBUT7lPNvNdece0tuDbw390ljlkeiItRutBUw\n8bJ0\r\n=tCq3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCl25iEbG7GDSwRKahKyKr9WpORReKDd9LSciJ+2T1BswIgZuxQZpTPMPfLDLcQYiGYlnG1nWb+AUqsDs4CXbIs/pE="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.5_1536775472746_0.8088042138057883"},"_hasShrinkwrap":false},"0.6.27":{"name":"@creditkarma/thrift-client","version":"0.6.27","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.27","@creditkarma/thrift-server-express":"^0.6.27","@creditkarma/thrift-server-hapi":"^0.6.27","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.12.0"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.27","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-aCRWcxtK9K5Z3PNuu4nMfsuS1F/DC6vgUYOGVEwXkzZj/OQ7WrVqAtdi5FbCdyW1oxlta4FWAL4bIgLKHuZIYw==","shasum":"874325a4fd13a879fa29975732082eee6fa8f06e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.27.tgz","fileCount":58,"unpackedSize":183347,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmWS1CRA9TVsSAnZWagAA5IAP/iP0dfcMHDd5o+ghjgKZ\nfOM8xgNYBPvupWocD9M+IjUMYAy1bplwM3EwUKaI6duZIp7tT7uwNhR9g2pY\nOaoPMAL/MERaJQxlY1KnSLvPcB28im6MGyQPoFdo2CyXSAeF3FZz4jTO/yAH\n5YCR/IBB/aFwHfedtFfTau9KQXkm5aZCLrEttJScObzFymOn6nFRm0HZ1BNF\nB0D0re2G6J4ygzIIVzvspeZFSjSa9dScVrFebCQQBOoMmtrXWfcc2u7Qa3I2\nrXH46LeLf1OnGi2VYgaUFuprMh06KMqUTVUYjfftZTZSZE0tKd3uDNSFUrlB\n5SdRyOX+HU5J8LnoquwOPvvsL1gjurZ0rH7IcBQpX9eGfYkbTpDaumkVbHBD\nXBpTrAE1RJSzojKw80fyauWDEL2/I/nBlDuyCwNlYsShjrVFNO2od7LYVj7M\nrDM03lK4gLeMJrscjn7iZHgt1rl9FaFoVxyMaesEVoJncJXHfgwVdTNxGMqY\nC2Bpt/5/iPpzlL4tmFKa5gTyE0YoayAALWptiFrI7awA8V6uIpEaDaeMbZal\nSUFzXtq3ypR9f/EghY1gc1ktXUh4xHEYhxXB+0HMNluabNREZKIDnbxVIUm7\n//pa4oWUDdfHK6QHgQATH3nHoW3we9BE4vWRIsiUK0guC9ueHAydMSRf/uHZ\nUHxQ\r\n=JRA7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDmZrSwNMitFQll0FVwI3S70oXkKajkuqd3UpJJRBP/hgIhALyBtrXv8fshsrHX/3Ihf0laN7YYfNG+ZWOSu6CnEz0J"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.27_1536779444579_0.030328772433632745"},"_hasShrinkwrap":false},"0.6.28":{"name":"@creditkarma/thrift-client","version":"0.6.28","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.28","@creditkarma/thrift-server-express":"^0.6.28","@creditkarma/thrift-server-hapi":"^0.6.28","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.28","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-F9GzrMwXYOVKVD8Zsoyfj72xu7/1H4Gb3cZmtAPi8iesa58rY1NOtEgkW8dQ+/4RpoZAQSap6ZPPvKeUjRnfNA==","shasum":"083d3ca6d017586888e050ec31caf56079e83576","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.28.tgz","fileCount":58,"unpackedSize":183693,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmYO6CRA9TVsSAnZWagAAQucQAIa9dRIUsdzRfh/Z2Osk\nBkiBq28XakDEOPBZfzCIU4rFe9+TXXJfwy7oBybU3edSPzsruKhLjTLsvWte\njU8yaX+snJkdkEOevEgCKYhlWG2PyT+MFSJj64BnW2BP6H+g3egQNI07M4EE\nc+dyuMhlhpaAIVkudfIiaAoEJFJiUDIDUs1gw/XNc+fLlc2Wj2di4MVq/SIT\nsO8YZapAJ8LGp64jVH1qACjp6zXwNIPH4CjE+ZA7ADu/Doom/lNYNQSpLXFt\nxXFHGwiwHTw2rjmA6YPAsHkyb8ZItkIbV+1ealrsqahLJRR+xY8KGJ/rVun6\nQ5B6gE41SNwKHZJncqaS8ojlqeH6MTCDrxfL3cVIQY3tAJFx2H+g9VNqo9lR\nXvVDmd2KgV0BBzSc65/cgJwWbmJjgBXCJAhvOVs5arG+lNkcYGqQiAJAEPic\nuX3CwuBXZpgTGQIYRlSG3jNuycOrrnrN+W7vTCJwo1kwUh1pLUNHPnJw/iPt\nVX4Ev8yRMxvUtm6SauULfMvJUw9G03PDXU0teWnpktq23AfeBAf8rAUzKV49\nvjClVPk3dehPXMEqVIwMOINEUiG7tMKZGGxKaNhvENRYEDBeAnIjy5gOvQ+s\nQVawvP6AI+d6nMu5hdDQByeBWxj2h7lNvGAhVjFLpqYugI0JLb3cWWnoQalK\nQZLl\r\n=TOf7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCw/DSlxIGp3MV1MswhYTvi9nBsCqCq81pRo572uaOQBgIgezA4QpnLDtNfkPMab8WdCNAVNlT6NTNwbj50F1uHdYc="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.28_1536787385632_0.5986251439867523"},"_hasShrinkwrap":false},"0.6.29":{"name":"@creditkarma/thrift-client","version":"0.6.29","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.29","@creditkarma/thrift-server-express":"^0.6.29","@creditkarma/thrift-server-hapi":"^0.6.29","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.29","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-w8XaWUDLfRh3y1yd9LURLCGWAtR6whABXJ+Gw/EkrqlUr3EtIBCUYheyWBMyatWNMZRQLnG4MG1xuE7hZZfLFA==","shasum":"9059cddd2fe3db01da9bb9df5779970170e7196e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.29.tgz","fileCount":58,"unpackedSize":183693,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbme3TCRA9TVsSAnZWagAA2hYQAJPlTKLo3jv0woAgLzU1\nj4RTYf9EMV9o3RgFC24t7+xfYByy1E7KZ82G8iwST4T3/V2el464PsVQA0CJ\neLlJwAnVyk/uLWhY3NKF4CcsNIJ17WszWNlk1CCkmPuT18DFXb+5B9HEJAm+\nqfshFkEMj4s9kSaMgqSOFo/b6hIYTSPZtOVPQwdef0e5kPyXUjTg2+IMZc2h\neR9hzmBP5rqwgWQAYzS4IYDIZCK86uHTGS7tdDbMwshZR2tgrNIU207BHtkf\n8qRCYlN6aMrTX/CjhiaWTdENY/fR4VQpBEO1Ux/fv/xy5C0T5xIRp6w9ncU8\nX44YIm0wKIJz4o0Jq9CkWQID8KbdpW/vUxrTU0qh77u5prGg7F4CBKiNRPLr\nWraYdWg6mH6z6oY3vrMFtcXbaGTbJDQfelltfltZjTUoEQSpu8Obwjfeuy9K\nCwMzGNTGTbSH9Gob7rA2jBwJ4Z17JAEXvCa1d8QLeiRZsS6yL3HBrtArFZWU\nYxrue4j2GtO5BY9WIGsS3WXaz2MKR76FbpfN/1r4ggnBxIF8kVaFltrZslJt\nOK6Up9kwMc8iSMIbkBemZ3adyODglZT8j0q1Gy6Ne+v6k1+iyGH4MOtk2xl9\ndIpIakHLZcvDNyNcd/i7XJYtanTfA7BasyM6ODuDtKPtxpjg0ZO6pHjUVLIB\nMzGv\r\n=t1LS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfV1YuZQFoYfRW8F9O0KvLssrLHbou1DnB6zgj9e4ObAIhAMue/3nKVWdRmmS8AgWzJ5XkWQ9+Gv3tc/qwxsTb/Z9E"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.29_1536814546568_0.29556898930360775"},"_hasShrinkwrap":false},"0.9.0-alpha.6":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.6","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.9.0-alpha.6","@creditkarma/thrift-server-express":"^0.9.0-alpha.6","@creditkarma/thrift-server-hapi":"^0.9.0-alpha.6","@creditkarma/thrift-typescript":"^2.0.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.4","@types/express":"^4.16.0","@types/hapi":"^17.0.18","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.0.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.6","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-01WLP2iwriGNWSB+YUllhFmXnFK0vecc0wa9Gz+CW42TIlqveFa6uqB7XpgYVLCR+evzFDu//Q0z5tX1k3R1vw==","shasum":"0cf09ae2b65709b7ea6746fcb916b0f4ab89bcd9","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.6.tgz","fileCount":55,"unpackedSize":201860,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbmq39CRA9TVsSAnZWagAA7rwP/Rw6tmqwZYtPmMPAs+1j\n7+TiegB3SUGGA7qMsfk3XDeGvZoFfqV3xavf3pe/0MnV51hFgSUqijftZ99f\nnadrPya6tDKvs9Vz2eF36sp/hXzcw0Zj7NlKxQAQVcwwcF8WR4kEq0itZPBA\ne3m1uiFENmGZBbtV5Z8Bzc9dAVU+EE6QPGkZaBufAK7Q0CBKpiOtUzesVu4o\n6VpTDcoGb+deMkO8REXzfcF69arW1S3HGNg+KA0wwG2RRgZLpXGL2FgbGq6J\nWzNo2Yc6TA+PZpKJdGYM56SVMIfZBbJQnmNTrIDxewi/nxkmOb2dze/gQbBi\nowcwW7AxDo9yMayHVnG/aZk9KWnqbGKTxCnDzYAN5nJVT4MBOdkW/4yPqnAp\nGZkRgTnGoF1EWdP9xkvMBRotlO6uvtXOSKFPJQ+UvUWm02kSWUv8OHeyq9k5\nvSbeVJhOKNdCUFXbVkaqwZUllYoUZaMmvLqdUDYckOESBUhgMxrChzpmnKZQ\nWDHkafLFz+GNOTiN3M10mPj2jAfzsQrKskCFOLRc6HaQej7hRUL9la2lMtj+\nsCxpDvr0jzKWW9azm1iwChlEEdFBl7UqfsniY9Mzt6pm2mA6XR4gh0y8reP/\nNu15TjDY1NpK4PjfeilYQZQQsVQm9quwnnnk8+CHup6y2iaYbbcXnwWqQ0YV\nA3MK\r\n=sGSR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBda9KYMatO59DTfgoApYwhDxSKgiaYYIhrjvn3JhZE9AiEA/epd920zDE5PYsJPJZ1/hGifBx0TCe39NaH48xAIAfY="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.6_1536863741162_0.28094747373691553"},"_hasShrinkwrap":false},"0.9.0-alpha.7":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.7","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.9.0-alpha.7","@creditkarma/thrift-server-express":"^0.9.0-alpha.7","@creditkarma/thrift-server-hapi":"^0.9.0-alpha.7","@creditkarma/thrift-typescript":"^2.0.7","@types/body-parser":"^1.16.5","@types/code":"^4.0.4","@types/express":"^4.16.0","@types/hapi":"^17.0.18","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.0.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.7","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-UIhfuhro6UJOvBAkAP95Q8N3SF2YbGt2cDFR9xfLl7avFzVNEGp7VtNjhUjFIhEmLYkAvKAJ2UDypXVA3LKh1A==","shasum":"4cc159e5706877a42a58277ab97d0f80748c3ba5","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.7.tgz","fileCount":55,"unpackedSize":201860,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbm+ICCRA9TVsSAnZWagAAXbcP/RcQ1e+0J/phrkw9JV/x\n14v3iyXaZYRjTbrRSPp0mdKegDWXknzsyXTUjet/hBPSozcNXu2+3BvfOowy\n3o3DrCmLy1g+q38CUKQgxswvtdaC+oH2/Jc8JrjNkExPEh4uVZiZM6BcPAnN\nHoy1p2dOIAZOojN0Sq18p5IxLnCBpSAQ2PiVIxXtkX7qxf0RqpdXydng+mhO\n8N4K7QZJIiUA6V8xaEnh+teD13LFiF8yMWcTzdNndFF4pRYYJGofJPrGFb+F\n623ys++TgzP0DrzuGlTy9FuT+l5703+8tBxCR+Sduf3Ub+TJIn0LeJzYvTpD\nTa+/v+Cf3KQ+z4VfZvOdg2wF5cIfqvLAz7QL6w0BxtVVMqMi4BcO8ZEcnf1R\nrPUKEHXo7S/1R+hKW4xogI3urIFlXPGrC/yYXVwk7ja6Uu9lOHvFZfLpO5uZ\n/rIPU+b+OZe60N/rk+AC5ap3cJCQPHSOSCv/55kIC/B/F0QDm84wBQIwAN/y\nhpPPCgWn+RNDdoeQyJ8j2Z70GDrGn3xIbFEzXJAla6J5rNQCscgKFkAMlcZa\n6rDakb8HYe/UkTYCfo7s6vDddVWAk4yUOE2UAPUOalgcju9Qdo/ZLUhJSE4/\n5Wi5kMBaitGIb0spzQqfFKxHabVx1G9AVAwL7Xle81bXce8oErdVNsN6kFzS\nZRYX\r\n=KW3f\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHjTqMq/WxRCWGXubgns5YQMYpPjwFNo+cCoaV9GL/z3AiEAoxx0wqsw0H2r7JM42qWML3ODsUDZU5GejOTGKUjk3Gs="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.7_1536942593585_0.5104106853969337"},"_hasShrinkwrap":false},"0.6.30":{"name":"@creditkarma/thrift-client","version":"0.6.30","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.30","@creditkarma/thrift-server-express":"^0.6.30","@creditkarma/thrift-server-hapi":"^0.6.30","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.30","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-uXS68q3MsyhRWVohZwgRllqkAsZ2M5GKS5vGH7ZaT/Y49oWv3qAUR8s0jhKMPGQWBEB3Y1v9c8cw4mm4IJCFKQ==","shasum":"abc29b94ad7b3563b62807e58edc1dd728d07b8b","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.30.tgz","fileCount":58,"unpackedSize":183775,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbqXwyCRA9TVsSAnZWagAA1UcP/RSd/HalDeZdM+kUFVIE\nhETk61ELC4obnPAj67rVR4isfbMa8pJQmAIbqMvLCq9YLV5edy1GpGKGbPaL\nrCM1JKLaZdk24ukMqpzlxQIXbwlb07LA7tS7TUqnyMbYXjNShezzjmsl7qtH\neFLCGIrczj8Ow4qxbv0oX+ya+u33CMfj9CbjjcR2OMUIr3azwGffoo3rQhdf\nLmTrJZ5c+5nq4LyHt9Aehs1yEfZH+KIaFJgi8NuJIUSxjSjhhl4JpT6O34eY\n6S+IFDOgCiWKeZCbEd9w48q9jnjeinsIr528LPNFh92zzVSMShnDzkJ9UK4g\nsC5JPFpJGJiQeRpZ7QjOrcCJjw7xAkkz5oUyt9ixbvv1TWiGG9YKIz+Xgh5B\nS1ieZMZs/1ShctHyxZ9vOalEUiwRe0yUFCJu4LZW/jUjerbWkXzNVyJe27LM\n6PBabCjx4pqWU+SOx/ZWK1r9WXB+S75IThKGX1SXY2Nm9f0Fi6B9/MEHP98e\n8GDB5VKj+H4puaj3Zwf3/CZ778HlaLlsY/EZWCFiKAxikZYENxtzDhh7fq3i\nraJHz2FPVt0oj2fk8QYA8t73wsp8sXj2a4iKBQvjjKBZZllaqxq8UecZVjkf\nJMXSQ2BYWtY12xFPOeDCqIrIgRsorpq1YiuXZbcJaVHt3LtZlECYpOFogTPi\nJAN3\r\n=0QUF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDhbyGkTj7r1ZwcfE4pg9eDR8kZBDyKf8Rxbl0skH1XCQIgLZY9mhMwBLPjDkLTnkhBXHKP0jq/an9w046cN7SAdcc="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.30_1537834033741_0.9481195868442165"},"_hasShrinkwrap":false},"0.9.0-alpha.8":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.8","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.9.0-alpha.8","@creditkarma/thrift-typescript":"^2.0.8","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.8","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-5US6cZ0tK3jWZw7Hr9iPV1hWaai1/ZOKy1iaGAlAkUe8JBKI7kWi85QAcJ/Q4fMd28EvbQuw1/3X9ru1yujDkA==","shasum":"d87c6fad476ea6aa87cfa029413459ac8d75411e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.8.tgz","fileCount":55,"unpackedSize":201607,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbuD/4CRA9TVsSAnZWagAAdZ8P/jTqtmhEVYGFj9pxp+Sj\nhEga9Q1xTVgV6IrzDVvQaUZelkcJtORtTE7uSt6uneSx4kgzV9aKvovm419i\no6yOz3aWDJ0XrZ6P3vQGaqYxOR9+NpE/PFkCgIPdx/G9En9JoBHjlXl3gQZM\nOo7Ap/QILBbWmcsg2O0bGjwoeMW+M4GcEalQ9DhBry3yZYT4ZESJ88/4oI11\nZkAx1jefF+yhpbogImKu+sDqdtvKPKhMdUxJSwpfh+suMIbBrhPTYsroIBfK\nReT1QEEJZQcP0kquBLGiSg6MQdbh3CJJnGyF/BWhEuO25e+VC405XaR2e+zN\n3CTxZYj+kW47X4UdS9zNBh5MPQ+io5eUm7juSEwPjpqaY38mOhyc5SO8u76M\n/YGPDc1AtxC04zMc+qMvugu05OayoWzthG2IxTBrQLuYjjJp7Vb10Yb9WC9z\n586+hHc2xMxq9KzlLN8TtQNaZGmUcpADCTaviaUa1AgHsP0iRMFy+mh4sKFk\nNAmV7PXWnjTp5abLDy4zBRo59ine+QEN8XH0ACFhAy9O5qoBGo4nVj4chyq5\nt1w0uV2a+txBgQ0cfG8jEsOAXMDkwng8EQoqKi4zvx3U6dgpiO9WQgUrJBra\nRHfO+xCezoAPQgcBryFNW56u/jLgoGOsTbKodzqoWFETkQTiO5ew3qfgikpA\n+mGQ\r\n=j7RD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE9p8XGw43ng5yjH5Uuybo9HdCJei51yHKOp8lH6vVvnAiBOkLPTaaUICyb9so/mCLSxUs3wXBmEybCCUNAJzL887Q=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.8_1538801655972_0.9195499904563953"},"_hasShrinkwrap":false},"0.9.0-alpha.9":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.9","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.9.0-alpha.9","@creditkarma/thrift-typescript":"^2.0.8","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.9","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-QWhfWKoXEcqqILR7lyiEDtdn2KwVUEvoYlmIDIB52wy0SLQa3bizG93Whc+ZjeNGKT4uBtAtSrsp2ulFRV3R4g==","shasum":"d7e9906e22ed68d88dffd70c7fe634b1fa7d25ab","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.9.tgz","fileCount":55,"unpackedSize":201607,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbuEIBCRA9TVsSAnZWagAAvGUQAIORGvCKdPI1vY90En1A\nwkN0muOJ4FTosIL1Dfw01zlrB2468oo87tx8yn1Y2Eqaah0quRAIV90Gcz+9\nyFBJxLvWJT/0Eig8XhoEhuQ5Tq5H6YM+Tw2ev1Wq+2xBr6u54flJkSZsZ11n\nvWacJjyDU9Vi2xHFU3PWpDJmNojBx+2jG0mVXu8wc92yuVqhkjRW85QGuv1z\n2NcV1ojBt5PebFpdNJvExVoHr6QHjnneVd+oJPy5z2gsXRcLeCIYZt8t7o3i\nLzWNFb+wsbJje8EbYMoOJIqPijtMZ0Ti5O34pygC2gCjQC1SwHMDRD8306Dg\nDDOTOkF3mgnqj0reSAa2NeTx5Hr2CtIFGaYdjkogGBdwLpFO/VIuIWvxsjWO\ny24QhnTcPSif/aBcIUtVSuzCujX0B7rPw1j9yM+Slj3n+MjXdmgvcynKvHZW\nPUDYg+LO9eGNfGDVCcfDXWvPTF0b1VBOEex7LJGwh2bKTDL/KGaNIoWgb0bq\nGHS8ZW0bAntCWVlvdFFFKyRbgsmJ/hi02HJvotRYHPqQzczx6MoqDjEK+beh\nc8U+V39GHNnaeUWAwpYa9/H066BPDQScuRpQL55an8040s8yw5Y9Mf0Ge8CQ\nC7+LxBc1FUclSnPWrqJlCmj5lvq4pgdwLja3fLcH/3NQbhNFsgXIYHfPT6sP\nvg1V\r\n=tWjv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHTrQ5X3vU+SPPCGGzEOtEoPJ9c1uAOGmdZwC6AQncpHAiEAhlcYUBAOXcvUnDV/ahIQvep6C86XfUPUPeDu1vkmuhc="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.9_1538802176984_0.9641626883006607"},"_hasShrinkwrap":false},"0.9.0-alpha.10":{"name":"@creditkarma/thrift-client","version":"0.9.0-alpha.10","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen","build":"tsc -p tsconfig.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.9.0-alpha.10","@creditkarma/thrift-typescript":"^3.0.0-2","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.1"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.9.0-alpha.10","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-Y2P1vAnafaCzT/Yug6dnI7l33vSvEhqwttm0M0rzxcRSVVj56DYOPuuiXVwR5xzmVIuzkh3nxsuTWFb+NHCupg==","shasum":"a93d7be43cf4d445d44d5a84cca6e3026e6f765e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.0-alpha.10.tgz","fileCount":55,"unpackedSize":201610,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbv4Z8CRA9TVsSAnZWagAABKoP/1Ij/dUXPvt/XrBU07zY\nvmy3lCUm7rpn/fYfVPGv2a1tkTL046G9I82gfkf5RdBPLEV6dE8WISrsTO3v\nmlrim+WYCK5EcUTlNYi+JLOu7lFl3BOjUNGTWxYxjNMBV7LxkHoDYC6h4U9P\nmF+tOQKqZIoMVkVIF3m4rGARqHMR1ccYBAuMj4FvYfUewmCgZervysk3gM6d\ngxzhdPixkQZts/U9Aqpm1gkxjBefy/Haw58ZO2WLROzGQ0DT33IYfD2CdFta\nkseyKQVnpgd+auAbKKQvrs9n5qSyhfRtxB8VlJIfroOh5gITcxcAEcgDvH2S\n+giz+Q/wW0VilQK030/HVy9qK6fPqUIpd85U47xPjMN3XzspiGNQ9X+jtazS\n3sba+K6FCSnhEl42if0NREhhRRnyzvo6mFCYFW+/NlsHQ4Jz08+RUWdssNoO\neU0FBgqAK82+xbA80Obo4TzALhNOraxJ3/4MQPvLV/gimMYxnEuwteKoEQIY\nWCYJIWzUutYTXjewEtQwDmb/98CMCVZX9Ij9QgcPDDYebLa18jKkll7waykX\n/X2F5VENkGmKhx20pPy3TN481LdGELqRbmKsCyBtzfaEDUCGtTcOUHmJ1WIt\nu572Kuvs4wQNKtRyO3jrgog6UgcS025RvHCYrlV+jGkBXXFQ+g00Sb0YyIFj\nZhlX\r\n=lcO8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDHKA6l9EQTyCN7/hHnlToBPG88K3qV8gYOWpED63d+gQIgeaUG25PrqcJybPUapjQHv9qJZgVDVOo38Vbu0kHoL0M="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.0-alpha.10_1539278459344_0.37045227223679533"},"_hasShrinkwrap":false},"0.9.1":{"name":"@creditkarma/thrift-client","version":"0.9.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen","build":"tsc -p tsconfig.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.9.1","@creditkarma/thrift-typescript":"^3.0.0","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.2"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.9.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-hqWPQnglN18r2xSJaBw9NvdOe3ST83D5EWjCq4ClyMFIBpFT/n0joDlumnWfS2vjTsB+TK5SeqSZyeqo++7xnA==","shasum":"da5a8de8886ae62bde7cd36cdb206c7391739a3e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.1.tgz","fileCount":54,"unpackedSize":194543,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbwQTJCRA9TVsSAnZWagAA+hkP/1QYkDi15NvzU1Y6eNxl\nua9buMX0G0ErxPD8SMAj0YgDknlAuSO2uxJ75MIZZ5M9ZxKz0Cl1QGK/+Cyf\nqVAZlAVtJtjqo7vus6GBtQcaC5dm0qdL2Bi+PcRC0vmIqoREdjymvGRsPEhD\nz84k7sNpNYGAPWQoY4OED8UwL+yjp64ZMf9YQX3zVVwaMjh3Ao6scorR6Lv4\nSOttrUHBpdT24IFoDH8cvDwAmLNduR7yquifn1VW7wWF4QmbWI3cO7lfWjm6\n+5ckP7qx/lxa1yHVJ/Gd5VJq5HJl8oFamSgpvwEnenX8KEe3FLeOkn2Z5mHh\nDxrf/Y+6W1x4DZkFHqAXJ1QDoXAY+aq0p2n2hwyjuztSiBsFVvvwP9IMHper\nFHSFMf76amKINfSmpqYRqBpYkTjWnzUr7U01le0LY7SUUQQxThXTPpVSgeDn\nW1BDyc1hdo5N4YfkC2jj4UuXx8682egf/NB5oQJ0E2+SUIKqRzvOf0mu9r84\nI5vptuLV/4L3Av3+JmLEv9GmPR01WRnn1LO9WssJ0HGTfIYa0pi/AF6YtzSE\nkzPI92YJ1tFFhLLJaw/5q6ibVVPXlcaF71MhR9qD73gTqVTbDRorKwKrRrL/\nP7WSMfD0rlDVcs0y2Vz/5jJgUDzWoe3JM7dgHd+hxNhw6T495upePoSyjIpM\n0UQM\r\n=LiRt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIApHjHw91oQ1axKDvmwh8FYftG2ACoA6qroTKNxVmPVvAiEAlGIb92urpnZP2Cf4cjUsdJCLwrpz3H1kcemQM51MwEU="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.1_1539376328354_0.37590362578710645"},"_hasShrinkwrap":false},"0.10.0-alpha.1":{"name":"@creditkarma/thrift-client","version":"0.10.0-alpha.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen","build":"tsc -p tsconfig.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.0-alpha.1","@creditkarma/thrift-typescript":"^3.0.0","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.2"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.10.0-alpha.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-ZDHT51eJwMH78ZpLnxo7BxU1eAd7b6qlwkcmo8YzUfnjGGziH6rhbRd3Nv/Ukya4mxGwkDHpGwUFPDe0CV3ERw==","shasum":"7fe8e0df47ce35787ae3ef7bd04518dc137d4860","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.0-alpha.1.tgz","fileCount":54,"unpackedSize":194078,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb0h79CRA9TVsSAnZWagAAJhcQAKCKcglHokYuJSFOuKgO\nLKescsntOhbbTezWgS36JF9uVddq8ppkgX8exZmY/LUFbznaBYrwXg4YX5zJ\n9MPIaQG42GQW3ydeHktVtyAWUEn0vNOJVzijzHbgbxUthZZAnOhih+cmebFD\nlhlPkOY0AE60e2C9xZydNBYnYOgjAz7D8lTJqC8tms7PnYH6OrEcGDpuqqoy\nurXJC2o4rG4MuxPONeohFA3AfwqDZXcOTVuX4uRf+OwBc95tEEyKFm1xAnWS\nCxf4hKZu8+OHiaLHOtxXcjqjtGx9EufiouawLsRaKXGpdGZ+64EaWdhki0ad\nUOWxszvN9C2bM4GLHP1DchVf9RJu1Af4abi8bsLM4SbN5zx1EN0m7Ao27wqe\n2xW7J294SxW33TfENmarabMMkq/PAzgyRdDRkgHkbLeJR4gwf7hbiECBZUya\nDMNSP/W540XJj4NCsuIlXQotjoaiMIZXRdYWkmCBL7RxlW6UC86P3jr6zV8/\nhjlb2T7AR36hQJuBEt5QKn6xyTCcseS6j2clJYw6Hb9oBS+/hvWj0frXbzaS\niU4p/mRzhKB2tkeE9ZASlypiVL5R6/oMLkSfDpy1jJ9Ez00RLo0O6KHy1cKQ\nv+2SmEZ4Jv8Vxnp0zczAONGDr5gOKEJ/3WRtTdcbolY8BeRRt1g8UBTpEy5M\ns0rA\r\n=e+Js\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICd/UG/z1OddoTiaDk6Tw/POMFpChArortqVJtVxhbJZAiEA7UWKfcnb0PnlXoPSDkEV1raIUlvArTHpuLCtDsKdYZI="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.0-alpha.1_1540497148018_0.7972957425891711"},"_hasShrinkwrap":false},"0.10.0-alpha.2":{"name":"@creditkarma/thrift-client","version":"0.10.0-alpha.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen","build":"tsc -p tsconfig.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.0-alpha.2","@creditkarma/thrift-typescript":"^3.0.0","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.2"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.10.0-alpha.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-S25Q8NoZaI/4ETAUEFpuR5KiYrLhL1PhOPGRO+gEPuYdODZwCplvWR3YUbViUa9r1Uox/H841LABv6wYO05PVQ==","shasum":"4eb48357fccdf62dfe1b68e26a91bc4bc058d634","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.0-alpha.2.tgz","fileCount":54,"unpackedSize":194078,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb0iOpCRA9TVsSAnZWagAAQ44P/jRrIPE1WdwXsgRXQ1ld\n4gGG36Ddhq38XNMH1AuPxbbqR54IYMZ44DaL+9hIhpoMziejwX8mlKY+RF3y\nJoK0HLm7iIz/nhPt4KsYsyHvh/BGmdH7OYBzR9K8m1i4R1p+DTmNipIhrq3M\n3j58KQAdJt5wOzZ7tIIwnvKvoFmPDZeooWvSbRKXYoFi/4Y8uGym5Utm06th\n1Y/nVJcEzrR/gvT6Tf2LO/zFzyhf8OnG5nAcneZSW2p8RdYIz6BeT7MAss3U\nnGMX1JnhEl5rduYXrj5mdmBKtg3xpWP2T5UcUzFB75FOxVfZo/0ssUtatlge\nSGvlYsSw3SgM1fGv4GddTLP1FRxc3b3SgWg0E/Ggtz5CVxQP+ogU2Rv5eRgz\n05XbPonLoSCy0M5oT92Mh+9DkDhK8xjfwEO9RQauhaFwRJJm8J3EDa/pUtEZ\nigCRTyBaXmK5AtCldNMvSvFMyiejmXBzlmgKleQymD4oRKTl89OKIA04If53\nbukeR2xVyewwrPLa+R9ZhTXJ5M7QWtDlh6HughMwD/f8jtoVBt5y+/p62ZcK\nUNdQe2nh9kymO6p+7FiwqRxbCDWEw0k+JyMRelgQ0lb9MfSbA8kQZ3/+rXSE\nlm/09Wt3Jys7Y8CTSKe5+3o8AhwtLQyAqUh1hpFqmLP4539Dx9iI6iFcEg+V\n3jCJ\r\n=Z8dT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDkk23Vqb9N6UQyj81VIZMI4Wo4glXpd8LEInPp/cYEoAiA3AG9P+oe/0upc6kNFcBNdQSnGnglB/KgwqXD1+rmkZQ=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.0-alpha.2_1540498343250_0.4958856195709911"},"_hasShrinkwrap":false},"0.9.2":{"name":"@creditkarma/thrift-client","version":"0.9.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen","build":"tsc -p tsconfig.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.9.2","@creditkarma/thrift-typescript":"^3.0.0","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.1","@types/thrift":"^0.10.7","body-parser":"^1.18.3","code":"^5.2.0","express":"^4.16.3","hapi":"^17.5.3","lab":"^16.1.0","request":"^2.88.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.9.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-ho7piXFyjSwLABYLzt1DtS27FnL8a4/TajWWCu3yflNsfA6NiBpB9W2rbHLEmPbYsnW+NQvSiDvaMeC6P9R7vw==","shasum":"957f3d41bd455819408f653206904de7080fb76d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.2.tgz","fileCount":54,"unpackedSize":194649,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb15K9CRA9TVsSAnZWagAAD3kP+wXzQnJnk3ljT4oTHDcf\nywPntZW05dG8DruQX7AWSJ73i8akfbY3TwOwvhs6uWh3w+0MgkG72Q63C2oR\nWJfPSfk1GEQ9CaoJUavrHHQTMsJjrXCOU3KGKHLg1wGECdQYFkHfF0D6TCgZ\nvsrJ34CkIpP2byL5CiIA8poIwl/sOXyZjoe2tQ6YZROMPAO2v7ryphftPMA7\nOF4NoZLmIVddfyDoOWxGB9o5IYgebhynaFtvE0XVAb1PIu+J2hznwFfFvk0I\nd6TP/wdVdXJaPI8/tAK0PuTRRLs0cBH5C6kkmv50TTJadsz5jFf+oXp3qJkY\nmO1DEIxVKEdwXbhzaI0nvCUgRCZSUyacP4MXV+g5rxTPhP5t49hjuwPN1S+r\n6ioFIlpqUvJq/7/6itVmGH+IEgefpt+P/JjBlLQ5+kctj0sS5s9EOaQswZHW\n4rFZk3aEk25s+Pk8+hHGU9/zqzYG5a4eKOpFNmfUEyVhCYeRZvm7PCtzQqAZ\nPPcM2Sq8nBsGHg6cLry3+H2xJjaYX09SrVEgFNx6R+RMmBCbwn8ql0LNTZ8A\ntA9XBRptPTp9/K2lq6FYtUvx35E+ieZr4zaonwZbmqKpI6kbKARW20+fA1eZ\nC/npO1RrKZbNxh9s9Vn1lwcCJw09nnqbWZ8O84VK2Ugp4s/zRXTjWgaPWhfv\nfVMW\r\n=vlbl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFtyG85rOMMpsJ/hb96DunhCppfRsG/iTY0p8vK/FUD/AiEA1t2KaDRzIspBzGqNIAhQXYkzP79wsbb7AnxHfKSUx6M="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.2_1540854460322_0.42135441096860937"},"_hasShrinkwrap":false},"0.6.31":{"name":"@creditkarma/thrift-client","version":"0.6.31","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.31","@creditkarma/thrift-server-express":"^0.6.31","@creditkarma/thrift-server-hapi":"^0.6.31","@creditkarma/thrift-typescript":"~1.1.8","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.31","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-IF3JiJqAKpjKGYFj4YzAyT1uuRIE444ss9aCeQeHRPLEp/i8QhjwEmuccdeNw4SQmpHP3u3iOEOF6PEC9UVcWQ==","shasum":"1426c1f74da1ea5670b14e540177d841e23c5a78","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.31.tgz","fileCount":58,"unpackedSize":183881,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb15YCCRA9TVsSAnZWagAAlecP/1w+D81iI+tdPeNLWAio\nGZzFv0CvWivoglc7GUvnzxmk3YxtF2rVljgVqt6uw4q23VTR3hbChtvdSFfO\nmYqFhRSMPAM90RrbEg4w1IQQHRzVdT/hei4fVSXhMKTylrxsw4GUkbPYnqBo\nixDbhulaNaa1KGpEx8P6L6M7Ol2zBpUIOj+D3LPNJODaNhR2PtbFkwBWaF3p\ny8vbyvV7fZuwyw9uwo5/GknGY53qien57Y/GmmTNo7eHtjXJqCveVOVzw5kh\njUeNLCJx6EMmbyLfIJWkO+CnuE7mdGMdphkfFjZPabPm+Bo0o6pahTknQ2x2\nMMqhw2IZ9T4Ar+8LIDLAotQvHln8CaqPOuMhIkddZvuktWv+Ly2HC/TlAEAR\nf8pTUp0JY2Zt4qKa3N7JeoSWF7sX7rDUk90w08IORA4HZWagIzCjOpFOiq2a\nT1gSDvvzcVhUMrffw4ciMT3DriLTI3/DT8ZF2pUA+2ZH7idlNkLNl/pLhjsM\ne4u0gplj5qaF4EuPOW/JBBkWd/sLvglUo0TA+4i9GQMCWNj7Ole8XvAQks5f\nEj27W5n/AUmKV92oOxlF0/s+4OUkeNTXKEGFXNv/3ZoWZ5fr0OSFKWsrrmSU\nvnQ9zuWmbs8YNiL24Qpy9dN66pOZc1vOWpFDxrKhfEzSexrFloffaofrc7mi\nsHm3\r\n=ye27\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICHVks9Wi4bmFL9GTPYNjqdiHAy0PGmI97B3t9KaJNLeAiBRk0SbI/5f3zSg1RL5kEFUXcZCeVQLa+GHEtf6iba3xg=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.31_1540855298172_0.4436487143036316"},"_hasShrinkwrap":false},"0.8.3":{"name":"@creditkarma/thrift-client","version":"0.8.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.3","@creditkarma/thrift-server-express":"^0.8.3","@creditkarma/thrift-server-hapi":"^0.8.3","@creditkarma/thrift-typescript":"^2.0.0","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.3","_shasum":"0ef289d677d08b5a868dd6ecd83ced37f2ba9551","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"0ef289d677d08b5a868dd6ecd83ced37f2ba9551","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.3.tgz","integrity":"sha512-Tb6VnokGs3eW2qJUDH87To0bSERq3FQcwOEa9HhjhGrWduh0vUyukznrV0kk3jPPh2rnRBD4Y7lhlkwyIbMVvA==","fileCount":55,"unpackedSize":201779,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb15jmCRA9TVsSAnZWagAAqQgQAIvZJinTJcbvY97e0cwI\nEWkE8xcGeFjRz3c781lWglCBLh4r6KTseMthwqwq1ry8qWJYKfPnIWJyZlFx\nKsQ1HS6RhNwgx9SKfUvi3jMbOmQCA52tUjaxh2gNQoe7ceN5uM+lJJ5UPNQj\nVgwjls6dhZGI46umMS0xOa2PoVacEyivMkX1FEUTh/rm07V2lsME3knKsTwr\nW7cQ67b6ldGQxXYDsVst4370jP95ZMIpBkEAKue/TxPi3TnysKKVjatF0O39\niNnUY6AcGzrz37LOCmRYrQfUDqMGNplUVU56cGBE32V6xV+lurqo+27yZ9/T\nGkZ0qyKmz/YVmX9h9Ar8/KjSjFBCa4nHyVI6WC0ZdOJCNRsjgDEoVS/IZGF3\nDH6z2/cZRqLg56DGpATM9fSJoEg6dN63nZEF6ue2Xq9UDHfVeZhK4J7VTOs5\npzCcxkd6348RO2jTGso0BbE4PlgWA7ftFpamGuAl0OS6j9iDaSgkj6exhvf+\nr0g4K2qgMBnRukMAaYalG7YtA7pV5o/F/lk6Cdu5LcpLY4sFOZkWdx9D1dPv\nny9As+GVs4M6P04Dvf5Q62pdKKrOziDFB6yj8HLe2o3G29culZLmr8Kwwfw0\n7n1y/TM5UFni+w2MSLExrCz+IxqAv3m232NMpI3/1AJdCaaKaNPl+7L4/VZD\nDIfb\r\n=EgrO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+9IobJy/RS7amQNeULvWnTJKifyDn1RGMWiZXdEQPFwIhAPhwh10r+siizUou/Os2zrsSy07CwzWNsBoC8w9tXAu5"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.3_1540856038116_0.28010283916570544"},"_hasShrinkwrap":false},"0.8.4":{"name":"@creditkarma/thrift-client","version":"0.8.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.4","@creditkarma/thrift-server-express":"^0.8.4","@creditkarma/thrift-server-hapi":"^0.8.4","@creditkarma/thrift-typescript":"^2.0.10","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/request-promise-native":"^1.0.15","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.4","_shasum":"2ac28e7a29b43f8fdbde409448c9d99705b54575","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"2ac28e7a29b43f8fdbde409448c9d99705b54575","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.4.tgz","integrity":"sha512-MTSuZcY/V8i8V4wH2MQi9F7OBhHL7QcMRaPf0VDQA1f1r1xuk/p6rwtEIgTHpKbDrGsiA3l4Pkm3phA9dVZ1QA==","fileCount":55,"unpackedSize":201828,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb4NAVCRA9TVsSAnZWagAAs2cP/00BLGu2y7zfJqY/aLIo\nBGXKzET9c0SGGkqfcs33ZFQr8ZJm1TGqv1PAuIvzn4dlYwaUF7fQC258j880\njLsGb2QBrQVI3PtVJxMKC4wOA/V22YfB3xIsRLtbefiSetWK+YWZxJvnK87x\nQzGJTgcGo8Sq8J+xVa0LHKhrbnxNUt50c8+v56Iyjx1twvrZhsUizSYFdEgN\nrNVAEz6paMd7FcblVxMiNsgxV5AQbPmvhAjJSZSgo1Q1CGL+gouXvRjvsZyp\n/CItJEx8DuD4MJXeF/CxDegxarOJaYfl+aLlDvweBn2IS73jnkuBZiJzD939\nOJaAITUhdlVCmu1W7ty9UAwCqnnPxlUL7vUF0WIYtrjVu8SFUe6YXhWztLhi\n/Jt5zixmegCid/okZuhi7l8hNMDGte/KH9kSwbywbEaU7T7F2kFtIQyFAcOf\ntyXmnJCht1RQMGQCrJHPbr4ILPmzYFGRH3uajMd/AmtfOxrPUc5tSi3nw/Jw\nd9tIw2aRaeUqASMBJX3ggv43Z1mDiKaUyJZzbO3reBzuOrGFnsS9nZCtZK2x\nYHXvCCIEx6kzjBcvbMpE51V/7bgl5XZNRGJQqiL1TL+ntvnAnNv5OT8KnW14\nahkMZSNL/Y39iPY0T35CJoOi2ZrwUHCgnYn1n1eymqEoXaNp03EzQJFkb8vd\n/eWS\r\n=wSaM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHxz0+WbRyvc3mkHiDkcflixMCcsrHNwcx5BC4WMljE4AiBry2nIk5R2M9AlJCqK5yRwNegMQqCJrx98liBFZLybKQ=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.4_1541459988831_0.5410541576870418"},"_hasShrinkwrap":false},"0.9.3":{"name":"@creditkarma/thrift-client","version":"0.9.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run format && npm run codegen","build":"tsc","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.9.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.9.3","@creditkarma/thrift-typescript":"^3.0.0","@types/code":"^4.0.4","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.47.1","code":"^5.2.3","lab":"^16.1.0","prettier":"^1.15.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.9.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-tp+zSld7HDUL68n6TcdXHEgrpDuNcGrT5rjp8xj0sPfw8la0zQPXX/0KQxtL4TgQ7ug0YOesNRfzZpz7gRCpsA==","shasum":"ff1ca763f222dea3776a613668f015231100b491","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.9.3.tgz","fileCount":54,"unpackedSize":194861,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb5KPnCRA9TVsSAnZWagAAYfcP/1bKRNLYkDgAiw+6PxrW\n27BEbakVlJODWiCTHnjpevLpatZKyucB1XE+KNCotY0bFlMMzL6fonuNO82B\nNIDoVwcJ2JnmXITLoBP/qEYnPBb/kPCb6fl3ePAiWbtlkStQ5lqK4nv0wIyO\n3BdqcEszlcFzzhQNWwma9EayVT3tfwnPa6SVfEdQ3ankJ6tyoTqC11zMQLPc\nrLD4fbttQkqK8kNFJ1kDxGyo0aR/8YvuY7ROTuGUyNCijXtfX8cJCq3aZoRg\nAOc2iJBpwKJvjkgEIW5zOo03EBmjKtIcxaqeGqK9voxFXDDSb4S6C7CP+uQC\niawUxbcK9ll1rGOrOgVHp2ut9AP4QRPWO0/BRi1Au207ZWuim8hmymXoYnwq\nfQ07/odO7buSkeEEpxommQ873sZ7LVi5QomiyUWdSeVqOnSii17U58zrpVg8\nYkwNLAjvDIGIDOsc64YLgStzCoyIdgk/Xc+rzqcXvEi/8iQcW8NvjHvrBkFk\nykMVUNx6mHFZaaG73QmszQETQ4vPl0Ui9c8h6+rOPOB7gIcgbMFLHn2KPp9P\n7WZwwblIqCkJsmGJOr3B+ZeXfD1NGCfmd2RJrkIQV7Atu959oMeuT44PDmZP\nnuiscgsKFA9w0pA/WfwTzb4LQ4wp+DeNlWVaI+jsBJkDe7lHiQCNQVDhEVIt\nqUZX\r\n=lNBD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAwof9v13ekdErBTOnVAuwBFFOd4mxNr9tgUcejFaXFQAiBlklyoeFM+Mn2gsgaOAKnqEt8h8hdH4GQVByM7qqPnHQ=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.9.3_1541710823061_0.9255395064932508"},"_hasShrinkwrap":false},"0.10.0":{"name":"@creditkarma/thrift-client","version":"0.10.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run format && npm run codegen","build":"tsc","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.10.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.0","@creditkarma/thrift-typescript":"^3.0.0","@types/code":"^4.0.4","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.47.1","code":"^5.2.3","lab":"^18.0.0","prettier":"^1.15.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.10.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-i53vEd0yImG21kjjnsayBwPoM/6R9YiMkoLglhykjZGq4Pf6auUp4xOhh1AvkgJDXyBoZ3L8O7Z2rQTrQdhyAw==","shasum":"8dd34b849a811c5e13bbd88efecee5a21d3b4dab","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.0.tgz","fileCount":54,"unpackedSize":195156,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb705YCRA9TVsSAnZWagAAyc0QAIKJS4TFfIYF+s5m8ehO\nqHgHGJWPXMU6ZUWZKENTJwXBYOlwfWpZjlBiYbQYxkF9A8xDxaRLUuTvI+5r\ncuKSN+793pIxVaCL8St4OaP693xKkc0YU9CEMvNMyWgs3aonYFarGDRSdmtr\np4Yi6g1J4+wgKN33NuE7/047XNV50sOOsSKy79yk4j3Vhzg8wgbjt8YXWtV0\ncg/qEE30U68VvKMQbtJmi0jp/I3AKvFBxfLmr1sDmmhVARSSFn8IYGKReKBP\n/OOSLahCe7msbVYbKERSkFMsI6xVhoxV1jlMIi+u7YgiA2pVoCRP2/LxrdME\npfV2Xl5/O8yeO+JyHtZEUYZgD3N/TXDbLlo4TyWTqHfodIm3Zr02QDSmyNIW\nxrLADncEyUAsTdq4T673aCXvWqPVKIAMpfgzxPmhxFvbLO7glarTWnaj5635\noH6tKeO/fvJjA75mSmu4Jp/NWpE/NflQJBWMyiErDiZLs0+1PVzWg7TbDdgG\nufE6txcqG4a2WlXxvBPG/NthbqfQN6fSPt/Z+wdsuTl/TfVm9xVyyAuqzU3h\noz3Ah+p0VbfXh15yMqz+kfDUusz0KNi9lKGq2lEzvbxd1u8Ed37ftreqyL4s\nwwRPCAeH1cf8v4gCWMz6Mj0C1t0wMr5klLYOjHU5ocFppc9b5RAksZs2jwIh\nlvOx\r\n=iNrO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA1mb6MQH/1kO8Lw6UgHHaWkKwGSMDNUwsTnvnq2unmvAiEA7KBEzHnn24aWEmRWRbEUIckMvDE6peB/kQze8MAuTTw="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.0_1542409815207_0.4526605228197127"},"_hasShrinkwrap":false},"0.10.1":{"name":"@creditkarma/thrift-client","version":"0.10.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run format && npm run codegen","build":"tsc","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.10.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.1","@creditkarma/thrift-typescript":"^3.0.0","@types/code":"^4.0.4","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.47.1","code":"^5.2.3","lab":"^18.0.0","prettier":"^1.15.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.10.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-nX0SFQLaksd8ZaIlAFbAAn+Mb3vp/eOfdnX26SkQsPdyG3WvtkH9W+2mV7D7pXTgIoAlG6sNGzVwrHKw+PVIWw==","shasum":"2c3b518cd0d366a5a46bd177c8c492d31896bd40","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.1.tgz","fileCount":54,"unpackedSize":194942,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb71SCCRA9TVsSAnZWagAA7GMQAISsEjn6+RzqJjZZ/e4I\nxIPFP2QJ9Bl0NOHfQfvTmP4tfKwR9PYC4MnI0IwPyfmim8K2ckksr49S/XxU\n2jKTmBBHx697uKYE9vCsN/PvolESocaJL3WzCTG4ofdxocW4i29d0Wfuq41z\nC5onLxEeNf7T5tn0/pxbsxu7uzcNuAZ5SyNr0ZGoVeCwCM6YnSqgUU8xhRQU\nlyGjMgWzNB6cfRV7h0L2EK0++n+ArElcAKAZ+LJloaAOWLl08TIB7qXsVnht\n76Nmtd6t4QCgxXiCKLhiTeks6Kq7iFBICsNF3N+fmE426213kGmGeeeQxyUI\nZPcO1PDw5cLS/FjaL92HLXMo0n5dcw/D3jIm9X3ocYAdD3s94ZLCn3UJ/nl5\njh7K1Z4WAzPfEbzIej4tCzJdmNqVHGOwgn3fW2wV/WXL3GMSLwY5CW3HZ9Nu\nWkE1WjmMEVUwO49UTiHRfmZjid/btCMu8jO9fU/L9cJRYG/KEwUONY3SLg1H\nSG+AuBh8k4sMtg4tSs9lOFjIEafn7NlC7GrgjasBkznUqZ48HRdegDv3YCIZ\n7VR7ccJEPrH+c4l91KUqDjbYFH3FOH+dVeORryemdn2vBkkLCB9MRmonPcvf\nB+9ciu4V29XF4Uq2OFCJcnFV0RVxuvU6epiauP61HLebwsldWh8mMCUVfb69\nsRXj\r\n=HOf8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC14S26NJmqYZaYcdjq4l4gmvfAf8cpIUi0pTd+OVmD4wIgJrHAtaIq68laUqBJLb36qlKeRA+KxsD9iUuRR4HU+78="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.1_1542411393234_0.6417376450845054"},"_hasShrinkwrap":false},"0.10.2":{"name":"@creditkarma/thrift-client","version":"0.10.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run format && npm run codegen","build":"tsc","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.10.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.2","@creditkarma/thrift-typescript":"^3.0.0","@types/code":"^4.0.4","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.47.1","code":"^5.2.3","lab":"^18.0.0","prettier":"^1.15.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.10.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-ENEyARL3Ydqy0XNBIXSfGAG38BfqVZtbqBkvqZ2AMSStlVLQKTpUyCoRxCUpW8Kzz5fxaOuNfOIKC6DCZeIh1g==","shasum":"8be79d01d9180078bc3089e69a81fccf5debaca0","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.2.tgz","fileCount":54,"unpackedSize":194942,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb8iZnCRA9TVsSAnZWagAA+zYP/1oOv5cVTSj0izs227Ot\nQvdvrKAlT6j/DgJ5L7JktycqnmMJTPupi6yksXYBzSmMCC4K4RGIoN4Ut48t\nddWzJQjWRxuy3rnKpX2nfCHS3TFonzv8Cd/BU3s3Ex98aIf0ePJeyWvXGoi1\nKaQPjb3TAirbXCX5sEYnttoOX8lShL2KWe9g8AP7yx7poVIEPrxgUGSTA2ot\ntP5Gf+f44OYO38nVOzYHKK7sTB12EIQA+OS7YV+NAwQYJUb6OVqNMgMXcoTj\ng5KXMpCyA97BxkVT8lgKPRIZixdNsfCXOjj006QBqfuYpT4836DkgYTx5rG5\nW4MZNjkkdl9xPKZFisbWBxF4u4NaN8l+TY4G0dVUn4PMBMVn1cA7Bj3WXJE5\ncHUlGv2MZOtTjcva13CRBUKdFcOVpCzAoPozfYUCEzhVHnpwRflzbGT5C1Qk\nvI3X154KqQvzZxA3UFLu00euAIB15EGtqZCsboOvf2qKXHra+KSmSguLE1wN\nhjVycxgQYdS82a640xvONuN108gvAY2XCbwozazLst7Saaf3Jx4NgSaiA+ZT\nKrXxe0C2VYZsxfneLmewF9q2d3rJj1dvlE97Dq2OFiQWM4EQ7ASdqTutvNsw\n3Gn3aNw9jpalWuqbiYafoUvXMAp7K/+IOkQIrU6n8goHavBN10G0v/Wgfhd+\nqBAs\r\n=9snW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICm7EDNi5Eo0fXLxZ/kzmDuV3prlJ4bkbzJzMVfmskNdAiBVTZBEciI7WuKAXrA6vceNDH7uzjUBnyK57csWwIt49A=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.2_1542596198438_0.2973172765749619"},"_hasShrinkwrap":false},"0.10.3":{"name":"@creditkarma/thrift-client","version":"0.10.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run format && npm run codegen","build":"tsc","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.10.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.3","@creditkarma/thrift-typescript":"^3.0.1","@types/code":"^4.0.4","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.47.1","code":"^5.2.3","lab":"^18.0.0","prettier":"^1.15.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.10.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-Q9dBJHQ5O692I8LZD2zqVXdPPWORgqCjyRxGk3v7Ksh84MBetXuf/HRQe49WzmWmyuBo1GJxfeJunzH5Ea2x2g==","shasum":"54c25dbecad2670a4b757edf64ae2ea70b28844a","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.3.tgz","fileCount":54,"unpackedSize":194942,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb8vU4CRA9TVsSAnZWagAAUesP/idLNImdAbNW4hc0TEqi\nBjkT27SfM2xNKRUzCqOZBqVQvJPh5ClBwoygVRwqCvea7GW/5ADgDNH+1TRi\n7mJ92syXHExV6VqR4j86ea7E6795jFAIYs8zqql6CUb6FDfVCNIKVuVZxgbW\nKAEKgTxZd3Ga2TuP66tObjG3DqMzazec4vF1gYN9gmkLv6cKwBVEs3YasTHV\n9Yx1XvlBGni5X2t8GnKcZw0hHcPFBiFphs42xgXAO5lvTELllXmyLTGoTkaG\nCAavxGbWa9i/kjNU9w8tm70QMDZae4tLADhsegkrzi+/7WudbJjOKeCSFixt\nqWKIY7CYQUuNu8kIgycrpvolcBtvS7s7trMdDP1Fab3uJiPV+5dgFYhOR7ZH\n+eOmJbghkjLqLEtY/bP7gmVVjYJ0e37tCPXPzvgDAwMwfQVLmTYTw08OT/58\nRMCoJsGKjM4bbTeZ7uU1veAtx5GIU8a7HMr1DXMuh9CGlgOuf+VWDn35YXuL\nWbt4EUp86zf72RIWH8Xw7uriwTrz68F/h2Cbv4Uw+v9mh4ew9pmkGYyHMuga\neDV5xhhZmf/ZcQZ2s7Lmq+vOPs6M+QF/lrNGRCu7cjrOEKNfVjFdauiOwIAW\nVL7f5ut6OxuX4yeEPm1abIkxmqj/cFtCzKDKoXJr2PNi8lQ6LRGCbC3i3OLD\nnDSx\r\n=gjAh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDRG7uXIkrFekJpfVf9goWb3Su1Htpes+nNgasZJ17YMAiBdl/tnl+Ac/7li34CUQyoCITCpa85z/uAf9y64lVFMEw=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.3_1542649143890_0.6105246169129539"},"_hasShrinkwrap":false},"0.10.4":{"name":"@creditkarma/thrift-client","version":"0.10.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen":"npm run codegen-ts && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run format && npm run codegen","build":"tsc","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.10.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.10.4","@creditkarma/thrift-typescript":"^3.0.1","@types/code":"^4.0.4","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.47.1","code":"^5.2.3","lab":"^18.0.0","prettier":"^1.15.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.10.4","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-s7RHiPZCkpnbRcAqGqGjsYS9LSA1L7HDlXcc3vkmeS1NB6tWtKhMk138GSB6jleeQFlLaAXxWHX5Q3k0sMGbbQ==","shasum":"33fa77b93b694f908b7c36e3eda110a79580a47d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.10.4.tgz","fileCount":54,"unpackedSize":194942,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb8yXuCRA9TVsSAnZWagAAVOAP/iEjSPGD0y+Zw9vQpOBE\nKy0EQ5lxHHOKfrLIVJDlcmNfIshJ/3hfVaUub6XgzofeaabaCAVaLUguhCne\naBBcc26FdGi7YsUvpItTPIaEhzW60RpYlWRCLDAI9s6D/pFAMzeWsY9PKmcg\nxkeq6gL0jkmmOH2M+ArWYwVhbITknuA70eyQVUmSK8H9ZoF1mk+JIxhSV3fw\nlPUnGe2ic4JUSdn8oP05bPSCtKgyAqHtldV/G4yrxIjPQ0ppbFZZrJuHbVaD\nIj6SC8t728+ups9c4lRyNFq7Tu08zGajXPrtmDw9Hxb1j2DH3L68T7Rkmnmr\nalalokeO4aponsS7UjWZyJO+aKDWYDhKmc0ETDzWUJNmrxFxrV1KhXviKJc0\nGH67aRpDDUCDoIW6LeWT0CaM1NxLn838mQ3J+87vLUaIFlLhp2gn5ls+MuUm\nwnSzpRKxASmqHGN87lY0eb4ahXw8OxgpQ6GCbHmPG8AVGhTt09+NiVH9NORy\nFGge3C7KSKKXKI4yKyf7xpgXCxMlNnGj0EkwwQWksvWwXqQ/LJoH8zb0kQ5e\nZKPYxXN0uJZ/+9hVoxm2JuBVYlpw1DkXDWIGCI2eOApkixX72iXUnCJf5Q67\nl3KVi1hY3t9w22tTapNcW7Nz1isKXTglc1Vzy/9GZe5iVGmLr0A9RS2rl7MF\ns4r+\r\n=U+0N\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH1e/K27CRDuA7GPOLVkfLnCridYqLKl78F9EkNNuSoOAiBzFztJOAb73dDXLNNqb5hXooUGrx0iOUYxMVprxXKrBg=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.10.4_1542661612945_0.334557743234456"},"_hasShrinkwrap":false},"0.8.5":{"name":"@creditkarma/thrift-client","version":"0.8.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/ttwitter ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","clean-twitter":"rimraf ./src/ttwitter","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"npm run clean-twitter && thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen","build":"tsc -p tsconfig.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build","test":"npm run test:unit","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.8.x","@types/request":">=2.0.0 <3.0.0","request":">=2.0.0 <3.0.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.7.16","@creditkarma/thrift-server-core":"^0.8.5","@creditkarma/thrift-typescript":"^2.0.11","@types/code":"^4.0.3","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/request":"^2.48.1","@types/thrift":"^0.10.7","code":"^4.1.0","lab":"^14.3.1","request":"^2.88.0","rimraf":"^2.6.2","ts-node":"^7.0.1","tslint":"^5.11.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v2.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    traceId?: TraceId\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Filters\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two filters for helping with this situation.\n\n#### ThriftContextFilter\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextFilter<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextFilter:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use, either 'binary' or 'compact'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through filters.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinClientFilter,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can go to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n### Running Zipkin\n\nThe example app is configured to emit Zipkin traces. To view these traces run the Zipkin Docker image:\n\n```sh\n$ docker run -d -p 9411:9411 openzipkin/zipkin\n```\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.8.5","_shasum":"030479b534a8f2a98b48a1016786f67a94a3a670","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"shasum":"030479b534a8f2a98b48a1016786f67a94a3a670","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.8.5.tgz","integrity":"sha512-dbz/Mqx9Pcy7MraGWIDWi70KnKvdehsjxRW7ZfrleoOmnK11uyMFsnHdpvXb6f249ENHh6tC7GR8kNhh/z2rxg==","fileCount":55,"unpackedSize":201214,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcAHQqCRA9TVsSAnZWagAAkckP/RG8NjridJZRG7NI3IYM\nX7xzT3CoxQNa1j8p3V5+faQwYb5R6T58zMaRXmQk6EpOAxlFsbcK+lsddehk\nc+foQjbVluAGQQGPdhe9que/2rm6MCgDN5xvUxnLyQvAz2CIw0LfWLyu01HT\njTlTAe9o2P8x/MK3JHJrWWYwRYijXSyBLPAyuwxpmGVgLzEPpiTrGnfm/B31\npJOuY89+VtAPHHkbaOGEp3jrj/pSFwOWzYkGgQmVzXUHpaZBhLQN0ju2YDia\nn+gtQE2Fb884RXaWxNVgwO+Pug8ItcXODL2ZN2GOzlOsvFXK2ECYnKr6JC9C\n4Y1rRGqsvhsHKJLR37pmEztNP27GDBfeXAEaSJ9uRa9hsa2RN3gNzvrO2Zu8\nKfG16wf0MTRRjH0+7JnxnSBemSEEwJaQNwAb4QAD7OPG8EEJ+VILHeahh4cd\n4ZwmDQ20ch6tsTgpw2qFG2fj0XMw9AIguI8W5G0IVZfRCdb2E9q/wFijTJAv\n30yNkRQ4t1SIYlD5tEeHD90sGBFBQQXSIHbUSAuDsyvjkzsj8X27HO/MoPZ3\nRNjinq8kyaRXR5CZPmHdGngNbV7WR4w31qMqmTOarR2OIJljZkykC4HUV1VB\nOR2eFFzN5075dvTmdat/jn8+cO3ltBDJfsjfcN2T7QZ5ugfdBWmmSz269clC\nONYd\r\n=9MX3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFSIZcJgq2aqJd30VUISDv0iiWfY+785ROYXLMBtLWJYAiAKIJC2F09rIgkZP+jxopqkjRBcz4KhgGsufG0QFAc9Nw=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.8.5_1543533610071_0.7623234190941051"},"_hasShrinkwrap":false},"0.11.0-alpha.0":{"name":"@creditkarma/thrift-client","version":"0.11.0-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.10.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.11.0-alpha.0","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [TTwitterClientFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/ttwitter-client-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ZipkinClientFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/zipkin-client-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.11.0-alpha.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-HC3U5WCxdh614ChQU/e3vRRMJmsUKceei3cv9DizGFQ97fkPku/eVKD9L9OuegXZICi1cZfrTvz21am1ZmXCbQ==","shasum":"2f04bda81504ee3aef7dba15b9c7b7d792fe0564","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.11.0-alpha.0.tgz","fileCount":30,"unpackedSize":65415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcAKcZCRA9TVsSAnZWagAAJZoP/REh/rT8XyxuV2F9YBTg\n5xw8VAZPD0qhryJV2UUBv+63ro/VSgRixBOXspn1sQIO9aq5hlBcqlJHgyXT\nww61abX8CSqodb9g/xOuCZqQF+NkNAOZ3gBu8adM18f/Xbkuqp0pfJjAntnE\nkoGFIHPDGO5WUeZVBotITzMFqM2AmiflDXRsBQg2FqH9UjKFTysfSnZYZtYH\nunjjwWgv5uCCn5tRxGFbHAl+u3HJ8N0GAr0ccDesFo6sQQWxMOdmBAfB0XEw\nHNTyXoOfYWMBxGjMUkOENfz/L32WBXlURMNgVkdJ9aYiJKheicKrWuUL1ryV\noITBHxLnBXVPyPO+C9bhjfcLltLOaiOwDolTKrCcvgK4wf9EEschipDhHfjA\naGtFLhQSmzU2QC/c693iRw/9KyIPRdNXWvk9nwVG8b0GgnQ7FLqN+tuZorEb\n6P0nfKKaNJcbmaA9Hwh7e4/3FMX1hfQksPKg7eL7g20OpqU+B1dAzOYQRd4/\nB0SWyyoUEHkxLEgqszyxcyXqXwYhNTEwdcq3lbWLuWpQbQhTvaRNA0Z9N7PB\nQFohqxVb/tq2j0NLL/TRbD/cfhDvHYh6k42Wrq/13Av3bTZ+E5UrrWHrZiHp\nR3JWQWxopFrZzfeHgDNrpyzDF6Z2OBbXo4KlB6WUqBt1dhErQ3pXsNogXqRx\nL432\r\n=ev8h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYKi5gpRt9sFqFxen9dfRlU08BOCEh/VPLX/2STr+b5wIhAKVMXPSBIRIw1XWEVxKUXe7F5UHF4OCNTBPd7nCOP9vb"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.11.0-alpha.0_1543546648273_0.4023790755118264"},"_hasShrinkwrap":false},"0.11.0-alpha.1":{"name":"@creditkarma/thrift-client","version":"0.11.0-alpha.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.11.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.11.0-alpha.1","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.11.0-alpha.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-clCyVaNlyZ1Lrz7GjSwTJP2Zyo0QOgJ160KzxSaxv4N7KYfUDuwPrk0cRk6jyiot7H9YAl1/mucse6pKE0m++A==","shasum":"fa11ffedba8b2c5d0c692f55922ef4e95da88a80","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.11.0-alpha.1.tgz","fileCount":30,"unpackedSize":65291,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcBviECRA9TVsSAnZWagAANfsP/36V9D6OC0BwXjbX9n/x\nUTJ1cQQaz22s7sTeksw2CdlKItnZd7jR9eVJ0c7QgDoUHCv0VZ9zmClKvjyF\nHZGt1oUjX5cDx7RRhJBAl7rsr0mdYyRrPqP7gMDXW4ofpi5WzEimpv7cwCTA\nOzf4kVplr6d7wJEyyu8/mc2kpDZvK87q9RDfPfMhK0S6mLNN4s+jD91ZhcDb\nOqPF6JmOorWADk+mquRMnPhXnVR5D3DoTcIUjK7uR6dDWzOXQ57KABqjdnXF\n6vigS593GBtzvUfEpx8H9LQKCGFtXe8LmnnyjK0+fik9JlgnmpBweNvpkPX6\nwpqO0fOUehQw2Mzpmu+ESTeD8TUVQ3hrFBAHu4atuRvnv1flWOzunpyIif8H\n8PbjoW4Rh79+mvnaPx1MxaUwaHqI4/lpjojOGyTqcW33lwSxu29qDvGjxR6/\nezoYpOouj4RgUEdKZJM+iok9yFwsspdMAaoxi8Vgb65edOvhPhsXtt6PZJic\nvBy2VMCq3XWSO0WsNgZg0JfO5EojnxgzlpI2T4xSR22GPHcWhd2iYeA1XjeA\nSvvs9gaTET+yEKyxGAwJk/6U2WXkqJtv0LfoLljq99L+66AGILXcTpJEp6Wo\nq/lMUa9QBZPnVMJmqr+Rm2IUlsw93AAboNJVW/76Poqfx/maC+LOGqiJ/mYM\nOMV9\r\n=xJAq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDreYOQADFgCAD74ZySOg7UsZDyQuDPpjY4ULiBRAyhugIhANCIkP6YQ2KyOAa9I4qGBHTvQrYrPGXtzKqw5OFs7/LR"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.11.0-alpha.1_1543960707489_0.17086639368515066"},"_hasShrinkwrap":false},"0.11.0-alpha.2":{"name":"@creditkarma/thrift-client","version":"0.11.0-alpha.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.11.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.11.0-alpha.2","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.1.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.11.0-alpha.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-A5GX8dHyFADDX6QLsH38rXKYoi8/Ez2cZ5swvv86pvohcd0n9dclWKceJULVHbl07G0d8tJYG45hOldoxNTiYw==","shasum":"38787bcbf0a97f92049a27dad42b4a231c0096d6","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.11.0-alpha.2.tgz","fileCount":30,"unpackedSize":65342,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcCETbCRA9TVsSAnZWagAAxaMP+wSfwnsdRiig0qRhhuHn\nnTzg2b4D1xD2YSfdc87Bamp5h9hc00esTuZ96dfQmP+3cya/tZlp45a3m1FL\noFIdyo+NQS1ztsRotKIav72cLc8PPorPWilq2FzlBjmlcoheVSA7OY/ljE/g\nCLpX+RhByJ0tjaUdxqcunVhV5YNc9QCwAEykB9C6xmbtlQkAC5a3sQCpNOBm\nHSYi1kmqxIVjbweOkaaIRrHt4MQJ03xjC/QQY4hqyYxp4/J1OO3FA4QMEeEY\nzv0rw+EGz4exuR9loplAOTM7At5BiUKBCUqNQgIDlptU+pO9LPeejJXChm6l\n7XWKn3lD1/8WqyAcY5/yI8ha/lNZlltyWB71HXrGHu592EXANtlSPyk6WV4F\n79CnTbFTCP3UYfGV5rlNA6m5ZqbE66St4lz/NTFQuvZjCWuQYBSontIL5Zjr\nlhQF+o5+ZjI7CqFSRLJiDkj4Wqr53UVkcR8eYLlJXDlLo3g0lOxaXZBMx2RN\nRAQEC+jsLqgNlqgHyfXpzzCbO4VqF19/gySy/O/OtMvMGMM5KRZPbE3+PMw+\ngtnjqC3vp1u96gZL1Pz6YX5HPJphdRklk8ixHFs2UTwGAAYE2YUCUw9ZDpN7\nX2RMSSrA353zPv64HggJ0GU3xkxbDZxpxutIYmlA2H76y0bid7y/hI3sjcmG\nwmyX\r\n=h1tZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDPn74Xt+qYaaqCsS/2nRq7FYOKhWCudD/YnabLYjcm5QIgTYiV23LDOXePWkpzqMoDuVJcksMztK2zcH0OCZag6RU="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.11.0-alpha.2_1544045786464_0.9319489060873403"},"_hasShrinkwrap":false},"0.6.32":{"name":"@creditkarma/thrift-client","version":"0.6.32","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.32","@creditkarma/thrift-server-express":"^0.6.32","@creditkarma/thrift-server-hapi":"^0.6.32","@creditkarma/thrift-typescript":"^1.1.11","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/request-promise-native":"^1.0.15","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.32","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-BIO69aMwXRq9wgQP3BvvnySe27yn3moGhWPhF+JzbH+TyTUvsjnSii55gQrT7KhK33Crv/7sM+/sb/x+1TPfKQ==","shasum":"e09dc1b3fe92e0d838f4a601533ef6f266a25f93","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.32.tgz","fileCount":58,"unpackedSize":183930,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcCt3qCRA9TVsSAnZWagAAUQgQAJg0RNPmOwjytdFAgq+p\nynHC/e1RYYGShm3CBMpK9lBJYkZ18KXrTvUWQN+UwKibYMbtrlAtxbflW9PH\nkjYjgnuSuYmJksYbZL/BYXSWWRwEfJW67BySuT89zUVX2j3wq03cnalin/6m\nqhUxN/5QxDRfFPXUFaavUgB4HO3XKRDNRtwziP+E7tc/1By0ARjmt9O/lu89\n3K2ZZnw6PGTn/NHpvy4YAPQbkZ8buMggyFDFlv+tGA7wJuLezl1PzOU2FGCs\nAL4S1Mm7am7sMjSek3JTDHq3hnc67BHYoJWyeSMoP/R2pKcYl+UxlJqW0v9E\nj9gqQzOgshN9Cblc1xbWsdvp3OdVuXeZJ2neiqUeS1diA+u7wxiZscDW3Plm\nYCSoThCLJtVrRrt+aXepfE4wLVnIoBjeQpdHsnvSS2BDucNrpy/IQk/z+JDu\n8YfAFuMH+K4K0wZAxAesSW3FiPoXvLMNjwtIRYmN9ZM27Ysm9XW6tV0KiSpV\nl8KXlwnu9kFjURXPEQtK5QrmbJxLZ39rH+h7QqX4IQq4txZUkV1HzTUYBux/\naCmWw9sninEG5LQFHRh7GLuAnbdNwdHWQyZiRj1s0j5ELGg5QLmh9vz9sEa2\nXRXFowM0Hl8WI4GGPIMKs2l/+kXVRQMTxLc7EN8MkQl+GuSh5zADmlV6K1od\nb4iu\r\n=1YFY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGSHSjgICa0at6Kh+r456e6xuLhEOAXSgEWRRwSnyrzhAiEAsuzRSFNPa7YeGnPOe5HgkyE4Ut5k9DinqRxMUPySCs0="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.32_1544216041578_0.5204792564647325"},"_hasShrinkwrap":false},"0.6.33":{"name":"@creditkarma/thrift-client","version":"0.6.33","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.33","@creditkarma/thrift-server-express":"^0.6.33","@creditkarma/thrift-server-hapi":"^0.6.33","@creditkarma/thrift-typescript":"^1.1.11","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/request-promise-native":"^1.0.15","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.33","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-6b7sae8KauUf3V6hZ7ncEUZzn7K0fQ9brWR378UKNy7e8NaQGLFx3g2h1DtaWiFYuPO+s3/LpvrO9/AN4/8veQ==","shasum":"db0bc711d48b438887a78d32cb92832957794c0d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.33.tgz","fileCount":58,"unpackedSize":185917,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcEpVYCRA9TVsSAnZWagAAUcUP/A9BKyKTcyH6qeBZ+yoq\n2lRik01CE5BHsHWiz/BQiWP6VEoPBGHhfV+z9F35xMwILoizwTFDUYCdO1Lu\nXChnB8v03ECCAxgkQrZlD2pHZloIMq8eB3FNpce9jIEMAXLMoMj+1JhFaYtG\nqThDFCdCHnZEwSSM2qgfkRoyeGFvrue9EBeHx5c4PbxxQtxVZlFVr6VK7uve\nROL8XxGGvDYO+cvQSTJfeMYgD2HkCixfAqwSW0PajtucNnLbDUUlWMNjVi2i\nfE5am85J7Xj1BBxfqVi9pXE3xlUbkBMngZz7Zy5/s7ZEOTWOsMWDeolNPO+U\nIgs7SRgnomE7L1HbkBJZBckm+DSZi0blpJown5/A6UKH+MHZxQij6+pS6b3W\nZzhjzZoGn1b47/2aB94QTqNRZ+uzk64Ien75MimDPC5RW5daFVwenRp5yFPg\nPC4jcuoUxPkN6gSsxd+OYJajvNZ0dbboWp4egc9/FAQ4fRfIfHiZVwbh9cTh\niLRsG+Sp/UCaPe5vdNgzT/Clnlzck6qiE1lqWUMv6XUJwxXjXGJjQHyMQlnh\n7JppyHiMCcX7DAmqWLd7o6vzz4DOlWEF2QYc0DP3k0Pw72NIAfhD9qzIW68/\nwVsju24HfsNLy+NMAluHoPUMmZ0qfKJy46JnguuWinfNQMdiv0DUxiSzJpZK\nqpxX\r\n=nn/g\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC6qPGkI5Fm6edaejwFdqjGkuhXqWO9VdXKcHbWpNYLkwIgNFey9fEv70XcLhafhrpjTu/eExvJPvyz2i/Atn9W4Zg="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.33_1544721752116_0.32002709348871305"},"_hasShrinkwrap":false},"0.11.1":{"name":"@creditkarma/thrift-client","version":"0.11.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.11.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.11.1","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.11.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-f7NgfwuEmJeuL/HDGGbfg0gUSB2jDTvxUwY4UApoc49V5b1FnxEToHD6TexsYXcq3XqX4VJRuufPmqoflFFg+g==","shasum":"6d5d8727cd0aa57b643c4c22966d14f26d40f784","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.11.1.tgz","fileCount":30,"unpackedSize":65326,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcGYT8CRA9TVsSAnZWagAAlq8P/3k78fQFPThNtNEfmwAr\neDDekIxSXMeAhIsx34yf4wXYtVWtAZnp4n2Ido5B1Q1fZ9ogoITqVUXC5eFs\nnEsyOSbhvPRUXFnlTpVH1RjqZyaCPt0Pi+mJa5GSLZ4kiFGd6UKvMtLfj+wP\nCeFNLoCLrDFtZgbc5XQ9xW0iZ6XMiZH5jJjvf92H7/FZaGGyzhctGP+gediQ\nTTyp96AIBvT7IFN+DwYOBhOxmW7vTYI06gHPxKD9Hrvb9ngj59Bqf3mDXYer\n2Rx4s4B4bPFj/x9fu7rDnusaJNXNEyW057/KfYp+FAP7K3Doakpi/l62m8vT\nzEFMWonuiMP/Y4UDPO+YoBuwegguMtyggN2MsMluqYiHtRgoHcaW5E/hCr0K\nPqCqJM1tDIm+jTUTrBdo2Vqx7zCH9tlWdbP1iNe8v2Q5qDdcIL6Ynr48V+zL\n/lPykTiR3m7LbBfH/qo1glg5cYAdPSNAuIpc9pYnFOkHEevrQXcjrm2VHQKi\nauQtZs5+78tYXO1fbVjIirPtbkemFnfcQ03jmFPeQW+IP1hCBcd6h42oUMfd\n7ye6sXx5nQlWk2Z8SIl2nrQsY01XK8c60XOKEWS0V0Mcj0imhFyeO6pzybrX\nNRW9DHgd9UOwkW6k2NQ+72i5GkdfJodgyCxVSWDCqM9s4hui2ol7gjkB3gJ8\nxLAJ\r\n=tk3p\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPYZQbzPhszYArEzmNJUAuIS977QQabd+A8YupHSVAggIgfqOGiZBVzJRkxaSsiHvm5ARYWWDs6gaoMREf+QsSfvI="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.11.1_1545176316092_0.8377649743331856"},"_hasShrinkwrap":false},"0.11.2":{"name":"@creditkarma/thrift-client","version":"0.11.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.11.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.11.2","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.11.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-uMdNPLzwTxvYCHaEhUDioHl8QIG3aQkxQ8cZjn9zC3FrR7+74WCIOiCshWzZCnyJ8RJGp5VKk0SyKp6UMcL9EQ==","shasum":"443a3c616c03f6c6b4725e5467fc603fed092635","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.11.2.tgz","fileCount":30,"unpackedSize":65326,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcM9JSCRA9TVsSAnZWagAAf0YQAIRVa58xKL4w78TDJU76\ncdcsWJCEdXO7tXpEtIMYTLGjtVyX/HY6iuFsn2XbcefKrdJ9pkc0afiOnppD\ncxKdpiuQYYz0oo2v+4liRhL/ZawNWIxie5lChgFE1r1ChUshrfpr/LZlxAHV\nGZmgUGuy0rVnA84VYOmQYZgRJ0LVjedT6GvQYNDFYEDUla/xZZQIEDaime98\nigQXBfOBUUaCnDljf3ZkjpCtYPnlcBVo+crtg2VmkMsiC9vuTFEhaegK5iDd\nCRqioWObs6xe7k5+I+IKIn8Fn0iEMtCp990weL3zk1QfqNZ3GwqzFk7xCnK2\nsn31ZP15fkEQFwFfck2lKAgCEnz+h7xnzRt27H+G92qEceaZYsT1RXjedBAW\nwGmD1AldsLpcdiU3e2AvkK1dM6JvF7MwSyBqGXxYVwpD9q39N6geKGnZt+5s\nw3+1dtncmEg3IXF4dMWKqp5RI48TfDrMpv6kQfJ86jwXAgJoLiFs9vKHmCJa\nwoJbnK1GVjlYcqKZ4dq+Wxuja6E4OaSFanGorAqGvljQr+0v0T/PlLF7WwbH\n3WLhNbE/Tq2zOMp8BmYhTqfdBfdtWbzVh6b6QT2OTM9rtd60OgMejmwXnb1E\nLtvMnnR2Sy6nRv4qHCx9OmEQr971k6h6f/zZmP+eBHnuyqFvZQJ5cZEo7s/u\nvpI/\r\n=KzKQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCUZgHPFCi0WBq/vZJnZoqTY3yI5R8NJ/1QS1P4RAfacwIgO6vbK5hzg8hWZW/uK/3NP2l7+QGzTXkWsX1a1lX4FgY="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.11.2_1546900049766_0.30800248536679975"},"_hasShrinkwrap":false},"0.6.34":{"name":"@creditkarma/thrift-client","version":"0.6.34","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.34","@creditkarma/thrift-server-express":"^0.6.34","@creditkarma/thrift-server-hapi":"^0.6.34","@creditkarma/thrift-typescript":"^1.1.11","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/request-promise-native":"^1.0.15","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.34","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-kSVCStpwoiQrcct9yv1s6y2Mj0I3AHfcn82UBBmq+lvUNjU9f528qMxH2T7blQTegxmvcbVbH2oB5r7Ka11KdQ==","shasum":"2e3757bef8e18c009918db83b7866da32735c77e","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.34.tgz","fileCount":58,"unpackedSize":185917,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN9ikCRA9TVsSAnZWagAA1OMP/3IGOO9TgpWMm1euAbwV\nRkbAf9iwyt4AKg5krZkPngF+j+C5KKKbC4S/jc1zEq1hpcveZBTVEehypZqC\nBhpIlm/3AZ/P/KP3svJheF1hMhMcJB0qfRR7req4r24EGKa13+Bq5dtGPCoF\n64dSW1kEPi8xNawy0Zma/ic7Gwe97tjVw8ArbpzHfdo6c/k8/oOvngZ/Fe/B\n2mWfYMXnoYvU//NA31s6Mvll/Fdn21GinJaVtkoqi8AL7PsRMtZt9rcWA6xN\nQ03lIOUZv38xANyV2wlb454/TXpv8x1eeQx2A9GtNOSGFAfS0Z5d4X8wLjJE\n+Yji2pCPZqzT51IV07ODs6EJkzlf0HtHy+ntCUGiI422MDiajckAHTH1ij1t\nXJy1jzBQaDGa2es/FyfhXrfuh/guR1I52N8xTexHLQbMYOuX9NloE2+zOUxT\nx7fheLPsVerXjNce6wliwfglbQOmLBlpOXHb5oMUw8nTFRF0cXwYqG7VkkFF\n/vdwLcN6aoG6EfLdp+egH3MA1eF9qDdOAbQFioYWoZMvaDwu2eBau1dnRiKk\n5QVBU8oZSSTKFaVOzE02gK34nbL3Z6J3I3kayoX0+zt6NODh/+Wi9J39QPDD\n4FNjFLzybMA7gpqtLiRvDQ6I+DepqKIaEgZrwAvEMWx3/htVRTjPHpAY4Cb1\n1KC1\r\n=0s1X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGmPTSWUlEEuvfOywIfAcskAJjHdpRNK2vw1O1yqs1SgIgSV9vnZHDZi/UArFjxFRiV47F19FNCASrbDkOAYgBaO4="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.34_1547163812081_0.5143524036772926"},"_hasShrinkwrap":false},"0.12.1":{"name":"@creditkarma/thrift-client","version":"0.12.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.11.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.12.1","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.12.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-q+gef0v5QoFq84OH8kekzRR8J9SJWsz21XCxLyC8xZOtJaO8BHVSWzTvAYnyH/PgIz/3DGBO4ISwxjt+WySb+g==","shasum":"3b017a2c6c3de72617586d7b786332c529457bed","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.12.1.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcOR30CRA9TVsSAnZWagAAtZoP/AuOF18XMLcU4bgcFkHF\nCTnAQ35awqVWRjGkBs3KXXGTt98ZsFQltPncWzdMj6+rTd1otvz5TbZTaFNj\nWN1qhK4/Vi3OCmQyTnduU+3+S8iCHf9e3/yDR6oV3036Tx2gUHRaWFmyk/Ty\nr70zLX+nVEpo7SN2tmxlODrJdgkLGYmGIr41eBfjIf8qozqsrjg+Vw37E2aO\nSuW2kOqCR8H+LPkA88Q91VVmEyBe/Q6y9jKJZEw30e+qeOzXA7uEZOggmnYc\nrdZJTD7/IkhLhnr1wrD+Sk7CxtehOOtErKYantfnroEE5uP3B5cNQbS1ov0h\nwzCqDJpWz5x+j4UKA7zGNYv0zdjY5SJiLZS1yL5whn+2R+OggJqkl5JmpPmH\nmwceXh0BifpY6MkS9bmvIfEdl/i9i+MhFqYHZUeTmH2QtWEsYvNKWNYZq7zH\nESbLHxkEQTHbfVlMl03ynNwiVJUIsBGsaF7sJJ/W7i1DB6mAyuM5egUrIoQF\nqSSwpnzrNEnJfOcJx+3n0m8vfF/vm19VbjNVGpCoDf+CVowvzbCbPGNnfkn/\n/9FN3syDEE0AJm+U40A+g3FMZCr1W3196kmzC+h24cToWMaqdv3dvt8UIGzH\nei0TSur7bgUcCl1YPtV+1yZxSKSRpBSRsQiOBYBExxKzMhcQPYYupg3ZQ069\nThaY\r\n=mMCr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCQJPOpGBqv0IOP8ak/FORq5ZSZnWy01zMAwYCOSAVQ5wIgWBJlgsLBNJO4YWjwlXm9oQR0IyCR/mMbBRpnCr9ps98="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.12.1_1547247092215_0.540090388664676"},"_hasShrinkwrap":false},"0.12.2":{"name":"@creditkarma/thrift-client","version":"0.12.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.12.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.12.2","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.12.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-HIhWZbVbW+qT5p0Ib9udqP98RzUUexUAgQSsRohvWCu1kmlXRdl0WMcpLgJdxJ3S/b0WgwkkESPd4eQtzYIC9A==","shasum":"fd2670f887052a73d5e1f06f2f4a02f13786df91","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.12.2.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcOR+uCRA9TVsSAnZWagAAKZoP/2ssHefMVeMdUC/MSGTj\nog6d6LnILXek9Ph+mFoA2WHuKqX8WjovXEuOGE2Gc0LZ11JB7MzcHTfzrmht\nuJDaE29aolwigp6FFbwqPDthrWV/dROXAWzttrTu0V9zOMqWhU/c1jpp659s\n9MzRMe0R6Mv/S56ivcZAPerp90fN2lVPfEPD1xbiaN5aIP1OriXYbn+8GOr7\nZD7Uv7aXFqTWHxestiwxdrZpKgFx4ZgbnYIf71ZWTzTVzAatvQYNyeKoXcgp\nJAE0AIxATyAFmVYwnNc2t5erR3TkqMGVi6jRXj/onft7KqQxYtiMmdFOemgD\nsyB+Qott8wRH3m/jG2R9I+H2vrp1jqUzsAGTPljrxvIf4yEKdOu50y997GkK\nD1OGx3tYq5dq2oFkR0bX0GCjzzvlAUqh3IskgtvNI2RRgVKhfSpogOtjymJb\nRt4Rjzqvvwp/7haoz/UhBjFXXFwdgcwoHNDCLRC4OENreRJs+BoO5vw295KL\nDcMnOU8E3Sz6MQFIei6wYYnW8LeN5kW+i6E6NfMh8Gmq9YaYG/AyvHAL1cwr\nXOV4yGZzEoeG+Gyuc0l5DgXncDTQzv/4dPKbV5zXLwc3P8KhQr5u+ushP6a2\nVgCqwy3EectLf6CRrZU58VIZFwAafJ0f56bYH0XCqJHMpw30qxk/NKuOoTDP\ndO3O\r\n=dvQq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDtEPnW/O/FGR5FpH5o9jYUM5DFGr0e0C/Hg8UNzfMvvQIgAZWYASf9mKCgwsCs561DdPiBR88t/MfGjeEEvlL9CRE="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.12.2_1547247534146_0.8026910884287963"},"_hasShrinkwrap":false},"0.12.3-alpha.0":{"name":"@creditkarma/thrift-client","version":"0.12.3-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.12.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.12.3-alpha.0","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.12.3-alpha.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-vXN0olswvR4ohWhqdjvue/049wZ7v2wZ+CLDPMhUFXhVwSNINlgnn0ItajnXKQxicCNd1OYhULQHdwFXHyBQvg==","shasum":"f3ede8ff0774aa7d54ce23278a44275c294d0785","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.12.3-alpha.0.tgz","fileCount":33,"unpackedSize":69415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcPA71CRA9TVsSAnZWagAAX7EP/iOcN1A1ysJ5hojTVcAR\nltNUy41QHMYYiTxxRtq4OoW6tSUNVZOPCFU29ieqrKn83Z+lbgGZv4a+X/xB\nSbQDYt8JhOE+jCieLREYBJo6JQmEcTF9mA+aK1hTl3dMpTK1kF6hrz5qWjbO\npS88MZLMhQOwcvFP40MOicAvlY0nrZQPvVUNIcrsoWlIVwQn2npjqrLSoOb/\nEhlbhfKhL+/nIjpuppu8Kme3Yx1FkmAtVgGYMMKP+6pjEMIGclww/CQob9g9\ncjkmkqkLMMA3oFU/Vz3aG85ttjRlwwP0OScfkKziUY2hFWXvVmi87HO95j6s\n0KBeeuli/3wxzgeXZHpgslbMFcFa+1pS63BXolnpMQ9SOFoRzYIRFQ16iP5n\nv+QTl64nFomfS6i1rXXBvUKfKpaJovoAB+V7GCZcyhLplNQ1wjXgwdhC+7MF\nKLOrQTDip/RnLuNjKrf1WDY0On7U0Y0hJOUVIUSzWgg0VpEed50JL8DOJIUK\nbGqabt/ta/gTHz3DnDc0U0qm7nXaJArelVG84U0hJ77c1OB2SPjARlmiqolB\nTnkrXMwiAIJexV8d9wfsDY0q2oQPjeGIvCo8bLnDxCr0cTicWi99iZuA6Fy9\nDbzP7HvHv3EGE2wmRrTVp0tJtnDHDf3W3eE6gVWj6iRzeVQ0gjXbsXw5rObq\nD86u\r\n=acx+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB6wn/Wks1xP9ltXeSIecMqyL7dcPWbiKM8Z+BZp5myEAiAekQ3mQ0+tAOizyv8vNprHNgiZeHJEIGgK8sLnLOyEIQ=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.12.3-alpha.0_1547439860920_0.41200052921846453"},"_hasShrinkwrap":false},"0.12.3":{"name":"@creditkarma/thrift-client","version":"0.12.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.12.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.12.3","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.12.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-poK91ub9jUD2sJHCfJHx6d0wrWPwgIuqi7qqroHF4MUNfWKcNpawaOGVLUmXNf1hH0JUee4IRsRtj41QHGPGWQ==","shasum":"dd4f95888ea402fb7cb8d56424b0c84aa6880632","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.12.3.tgz","fileCount":33,"unpackedSize":69399,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcPBSbCRA9TVsSAnZWagAARMgP/iYn9Y1W0JYmnMXVzdYT\n5ZiLENedND11xPldhVqVZncbjhBaahLJWlZ5pg2Q4VzPKQLV7Ac43XNaoPTs\nY/MPJN1vDrxhOLZuLoJA4i8aUT+xtTi7uPzhpPU/5u7BK2X8MBZnohWUz8xq\nR1rfws7kY/KWWF1VXxuFSWVpGY1APKw03k0uK4VLtcdL2EyazQBuFs4UAv6i\n7U7TIHeoIVeBC1P5JrgiZ1ieA4nq4/3B1MUPWFIhPWxQPrBNJEOkWs2pK2yO\nM4ViZiziqr5HlGaQgMUCu6kpmFeE84omfUOa3w/UjwaILkBAMG6+SmTrWI0y\n+NrbogHpZP8dm962kyC+juaqO5vKuBV1ikPBAVAnAow5gnmYaZ2FEcoL5eyb\n89tQPKCpHE7RM4bv+kOQdp57FwNiwOG6sa4/jmM53dBDJv3VPvj/PpkX9j8D\nZu36YI42G3aK/aJTr4skoRvzc7Bgn0Kpn5zuyS5McYr10vwTyUvVyuKg9SEW\nUg1zmS8cTZAHj2tImgsNXmW1E2487NwYEAuOftYkeJ39zKF6yojGaVVTCx2h\n4EhC9gLYBrBIBAUFetEVRSMqo+3WeR4ZGV26RrKg67x0jTYneJB5LQA9Myfz\nB+MDirwRDke5gwIR7yZ3YcJpN9Le8Zdy9Xjywv4IoTzLiRC8SaoevF5W1fGl\nwLF6\r\n=ns7W\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIArxYtzHGo4pKafg/3OMpS6qZ948f7+oV5Prp/L4wIs6AiEAiIpRELY91snMcEJf+CLx1hAcSgwtd+OYrapCJ2SZRyo="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.12.3_1547441307179_0.7579542242541382"},"_hasShrinkwrap":false},"0.12.4":{"name":"@creditkarma/thrift-client","version":"0.12.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.12.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.12.4","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.12.4","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-VxW3w9+YYlH/Wy2NDpUh6r5JYjSHMWyLFCpQ2xESq0kUKDiW63AfqrId0o1XdUDdtsKXZWNBIPiAKL8Vl5rAoA==","shasum":"de4ec7f866a258a6b8a7eb3132bf5c9efaa01000","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.12.4.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcPOUeCRA9TVsSAnZWagAAQ3YP/2heD17EIEUTVqaRKt2h\nPC1AVxNe8w2/G458u+MfDo0A3CR+WNIospHAcVgvMtsyWEVv5QNoxpR8Gxxl\n7qbXtUXUXvx2Pv5IS2eYEG1RLviQJOMcRjI8Bi4iuwJT8elj4mHiDL3aD4B8\nJCcDC1ARJ/aOHrW1afOd7LJIeAPxjsijfBdtihKnQBRDCVajXGlR8K8ACihz\noe0/XRzLfflmgksKuP4h3OcYV8TF1IDboQ4gptxxcgzeIYZOdWXfX2GI4s17\nUTZZEO0qkzM8FK40tUChQy1gG58guPNrEyz4ao+ZU0HHEkvrivT1DNPHPS0Z\nol/0FTzsZUI7LN7TM2pwq4Ds9WCoPLB0nIvgqF3hF+S92ohmA1ooik+wtiSC\nVyq6jpIPM/6Xw4Zct1eU5quCkoyhFQmJ1oQRiBqNMFUpQku9XFtyMqgDinBN\nLC3E4P5TE676vnCsof6RPjW1iDGEYRKxNIynLRTUnn5iP2IDGLjZQ8oFcA8u\nsKJoIFt9OcmCxgCKjD99zYmyi4tauskgTXNC7IMFlynQ88fiqobvNM1Mv2aR\ncRRPmcrbVqWwLFo+5UKBZ4Du1+5O4TaadV61yDdrUIyO7ejcAMTUP3OqcXYY\ncudUiWh1s33ST9TJkCdwzLWTotJKjZ4kKKChZbFu9ZhCZoCvIaTQ+/1kjW8Y\nnZko\r\n=7lTB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCFqQz+w0BJIzFy1OJeD2NdHXJ2hpDx0bJKmCjkwiS8FAIgW+zLkINwgmlKUM+eDOxX16yL7k7JmTsrEgkVY+/82V4="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.12.4_1547494684201_0.4276279548532078"},"_hasShrinkwrap":false},"0.12.5":{"name":"@creditkarma/thrift-client","version":"0.12.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.12.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.12.5","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.12.5","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-c6itfutpD0ExMdHyXvxwRVr/lDb+RQqNPX08Hto1e2auUHhkLJXO9NAwLLimL6tLmysWdRiWfFEvzti6ll4vww==","shasum":"2906ad3cfa7c6c6adbb29d12d9e8f67422a09820","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.12.5.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcPQpOCRA9TVsSAnZWagAAK3IP/2TfFf/YBisxgukBtIfl\nxeNm1JWJAK3r1LfzDPxOxjWbaSwqreTB+QwIhtI8K3uoTdCHjutgPyPeHBn+\nxvQxR8ZCHWeovvbx5mrK8SY5/68IVHQWZ1R3Dogll+t6IPbSwj2poyZIrbTe\nwJCwt4B+F9ht3IgpxyNG8nIyfcYXkGH14jKWE03BMOoQsHFPKzXrPgfKudqb\nmIw0d+S8WMcAkIsF4cuHWMxqNTfyf/yWL9b1cSyBk1rdqgJOPyfX4nhta3tt\n2nSyHBEbaK+hy11+vg3qN50K+UEdOGbchI2P7Lp9Psgtm7msuTOoMAwR/B37\nuxYP1umIT2kteTO/0zXNEv9WxSPw5aTRtigzTWK+/z1hhe6mT2T5wXQ5fMni\nGLzx5L35mxYJOf3c6COymhDmXkmnTgTjFP/sgPQkSLSyTkUL4TDR8/4sAg4c\n/+qdrT5ziEP3q1R6HtJ7Usb29RQ2Q2uqAfkd0TobdsfRUfKpsglWil+qv0T1\nAXV3yUzFmbFJh962eB1oJgv2Ti2dciX15qWBGm+akU/b5Q1dpS/lOoJDw9c+\nIBvh0spo3RsZhrPHt4WEug4MQkaAx7LbxUvdfmIpNqU9XsQQyrWjlWbQheBx\nRp+V+/MtSI31q0RfgT3j31AcjhaAZ33IaAZ7yIaQJ9eUt4FVW1CrxTTPK0Je\nkzfR\r\n=WLLo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGLb0lZC/p27XTt6ZEmTLVhirwdI9HDENJA44YhchgpWAiB2EQYvZ7JwxFoH5g8tzGDDR2A5SB4sxYBVEmTps6FmKg=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.12.5_1547504205784_0.28756033144093407"},"_hasShrinkwrap":false},"0.6.35":{"name":"@creditkarma/thrift-client","version":"0.6.35","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist ./src/tests/integration/generated ./src/tests/integration/generated-apache","clean-dist":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","codegen-twitter":"thrift-typescript --target thrift-server --rootDir ./src --sourceDir ./thrift --outDir ./ttwitter","codegen-ts":"thrift-typescript --target thrift-server --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated","codegen-apache":"thrift-typescript --target apache --rootDir ./src/tests --sourceDir ./thrift --outDir ./generated-apache","codegen":"npm run codegen-ts && npm run codegen-apache && npm run codegen-twitter","prebuild":"npm run clean && npm run lint && npm run codegen-twitter","build":"tsc -p tsconfig.json","prebuild:test":"npm run clean && npm run codegen","build:test":"tsc -p tsconfig.test.json","watch":"tsc --watch","start":"ts-node --project ./example ./example/index.ts","pretest":"npm run build:test","test":"npm run test:unit && npm run test:integration","test:unit":"lab --timeout 10000 --verbose -l -S -P spec dist/tests/unit","test:integration":"lab --timeout 60000 --verbose -l -S -P spec dist/tests/integration"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.6.x","@types/request":"^2.47.0","request":"^2.83.0"},"devDependencies":{"@creditkarma/dynamic-config":"~0.6.7","@creditkarma/thrift-server-core":"^0.6.35","@creditkarma/thrift-server-express":"^0.6.35","@creditkarma/thrift-server-hapi":"^0.6.35","@creditkarma/thrift-typescript":"^1.1.11","@types/body-parser":"^1.16.5","@types/code":"^4.0.3","@types/express":"^4.0.37","@types/hapi":"^16.1.10","@types/lab":"^11.1.0","@types/node":"^8.0.31","@types/q":"^1.0.5","@types/request":"^2.47.0","@types/request-promise-native":"^1.0.15","@types/thrift":"^0.10.7","body-parser":"^1.17.2","code":"^4.1.0","express":"^4.16.0","hapi":"^16.6.2","lab":"^14.3.1","request":"^2.83.0","request-promise-native":"^1.0.5","rimraf":"^2.6.2","thrift":"^0.11.0","ts-node":"^3.3.0","tslint":"^5.10.0","typescript":"2.9.x"},"dependencies":{"@types/generic-pool":"^3.1.2","generic-pool":"^3.4.2","zipkin":"^0.14.3"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n* Add observability with [Zipkin](https://github.com/openzipkin/zipkin-js)\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary protocol. Framed transport along with compact and JSON protocol will be added soon.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkaram/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configrable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of middleware to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Middleware\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with middleware. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA middleware is an object that consists of a handler function and an optional list of client method names to apply the middleware to.\n\nMiddleware are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftMiddlewareConfig<Options> {\n    methods?: Array<string>\n    handler(data: Buffer, context: ThriftContext<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the outgoing Thrift data as a `Buffer`, the `ThriftContext` for the outgoing request and the next `RequestHandler` in the chain. When you are done applying your middleware you `return` the call to `next`. When calling `next` you can optionall pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n*Note: The difference between `ThriftContext` and the raw `CoreOptions` interface is the addition of an optional `request` parameter. This parameter represents an incoming request that spawed this outgoing request. For instance if you are a service agreagting data from other services you received a request to incite sending this client request. A common usage of middleware could be to propegate headers from the incoming requests to outgoing requests.*\n\n#### Applying Middleware to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Middleware to Incoming Responses\n\nTo apply middleware to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Middleware to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add middleware directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(data: Buffer, context: ThriftContext<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of middleware to apply. Unsurprisingly they are applied in the order you pass them in.\n\n### TCP Middleware\n\nWhen using Thrift over HTTP we can use HTTP headers to pass context/metadata between services (tracing, auth). When using TCP we don't have this. Among the options to solve this is to prepend an object onto the head of our TCP payload. `@creditkarma/thrift-client` comes with two middleware for helping with this situation.\n\n#### ThriftContextPlugin\n\nThis plugin writes a Thrift struct onto the head of an outgoing payload and reads a struct off of the head of an incoming payload.\n\n```typescript\nimport {\n    createTcpClient,\n    ThriftContextPlugin,\n} from '@creditkarma/thrift-client'\n\nimport {\n    RequestContext,\n    ResponseContext,\n} from './codegen/metadata'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ThriftContextPlugin<RequestContext, ResponseContext>({\n            RequestContextClass: RequestContext,\n        }) ]\n    })\n\nthriftClient.add(5, 6, new RequestContext({ traceId: 3827293 })).then((response: number) => {\n    // Do stuff...\n})\n```\n\n##### Options\n\nAvailable options for ThriftContextPlugin:\n\n* RequestContextClass (required): A class (extending StructLike) that is to be prepended to outgoing requests.\n* ResponseContextClass (optional): A class (extending StructLike) that is prepended to incoming responses. Defaults to nothing.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n#### TTwitterClientFilter\n\nThis plugin can be used in conjuction with Twitter's open source [Finagle](https://github.com/twitter/finagle) project to add and receive the headers that project expects.\n\n```typescript\nimport {\n    createTcpClient,\n    TTwitterClientFilter,\n} from '@creditkarma/thrift-client'\n\nimport {\n    Calculator,\n} from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<RequestContext> =\n    createTcpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ TTwitterClientFilter({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            destHeader: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 1,\n        }) ]\n    })\n\nthriftClient.add(5, 6).then((response: number) => {\n    // Do stuff...\n})\n```\n\n*Note: The Twitter types are generated and exported under the name `TTwitter`*\n\n##### Options\n\nAvailable options for TTwitterClientFilter:\n\n* localServiceName (required): The name of your local service/application.\n* remoteServiceName (required): The name of the remote service you are calling.\n* destHeader (optional): A name for the destination added to the RequestHeader object Finagle expects. Defaults to the value of `remoteServiceName`.\n* isUpgraded (optional): Is the service using TTwitter context. Defaults to true.\n* clientId (optional): A unique identifier for the client. Defaults to undefined.\n* debug (optional): Zipkin debug mode. Defaults to false.\n* endpoint (optional): Zipkin endpoint. Defaults to ''.\n* sampleRate (optional): Zipkin samplerate. Defaults to 0.1.\n* httpInterval (optional): Rate (in milliseconds) at which to send traces to Zipkin collector. Defaults to 1000.\n* transportType (optional): The type of transport to use. Currently only 'buffered'.\n* protocolType (optional): The type of protocol to use. Currently only 'binary'.\n\n### Observability\n\nDistributed tracing is provided out-of-the-box with [Zipkin](https://github.com/openzipkin/zipkin-js). Distributed tracing allows you to track a request across multiple service calls to see where latency is in your system or to see where a particular request is failing. Also, just to get a complete picture of how many services a request of a particular kind touch.\n\nZipkin tracing is added to your Thrift client through middleware.\n\n```typescript\nimport {\n    createHttpClient,\n    ZipkinTracingThriftClient,\n} from '@creditkaram/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> =\n    createHttpClient(Calculator.Client, {\n        hostName: 'localhost',\n        port: 8080,\n        register: [ ZipkinTracingThriftClient({\n            localServiceName: 'calculator-client',\n            remoteServiceName: 'calculator-service',\n            endpoint: 'http://localhost:9411/api/v1/spans',\n            sampleRate: 0.1,\n        }) ]\n    })\n```\n\nTo pass tracing information along, if you are a service sitting between two services, the incoming request needs to be passed as context to client methods.\n\n```typescript\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { request: req }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nAlternatively you can pass a traceId in the context.\n\n```typescript\nimport { TraceId } from 'zipkin'\n\nfunction traceIdForHeaders(headers): TraceId {\n    // Do stuff\n    return traceId\n}\n\napp.get('/calculate', (req: express.Request, res: express.Response): void => {\n    thriftClient.add(1, 2, { traceId: traceIdForHeaders(req.headers) }).then((val: number) => {\n        res.send(`result: ${val}`)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nIn order for tracing to be useful the services you are communicating with will also need to be setup with Zipkin tracing. Plugins are available for `thrift-server-hapi` and `thrift-server-express`. The provided plugins in Thrift Server only support HTTP transport at the moment.\n\n#### Options\n\n* localServiceName (required): The name of your service.\n* remoteServiceName (optional): The name of the service you are calling.\n* debug (optional): In debug mode all requests are sampled.\n* endpoint (optional): URL of your collector (where to send traces).\n* sampleRate (optional): Percentage (from 0 to 1) of requests to sample. Defaults to 0.1.\n* httpInterval (optional): Sampling data is batched to reduce network load. This is the rate (in milliseconds) at which to empty the sample queue. Defaults to 1000.\n\nIf the endpoint is set then the plugin will send sampling data to the given endpoint over HTTP. If the endpoint is not set then sampling data will just be logged to the console.\n\n#### Tracing Non-Thrift Endpoints\n\nSometimes, as part of completing your service request, you may need to gather data from both Thrift and non-Thrift endpoints. To get a complete picture you need to trace all of these calls. You can add Zipkin to other requests with instrumentation provided by the [OpenZipkin](https://github.com/openzipkin/zipkin-js) project.\n\nWhen constructing instrumentation provided by another library you need to use the same `Tracer` in order to maintain the correct trace context. You can import this shared `Tracer` through a call to `getTracerForService`. This assumes a `Tracer` has already been created for your service by usage of one of the Thrift Zipkin plugins.\n\n```typescript\nimport { getTracerForService } from '@creditkarma/thrift-server-core'\nimport * as wrapRequest from 'zipkin-instrumentation-request'\nimport * as request from 'request'\n\nconst tracer = getTracerForService('calculator-client')\nconst zipkinRequest = wrapRequest(request, { tracer, remoteServiceName: 'calculator-service' })\nzipkinRequest.get(url, (err, resp, body) => {\n    // Do something\n})\n```\n\n## Running the Sample Application\n\nIncluded in this repo is a sample application that uses `thrift-client` and `thrift-server-hapi`. To get the sample application up and running you need to do a few things.\n\nFirst, clone the `thrift-server` repo:\n\n```sh\n$ git clone https://github.com/creditkarma/thrift-server.git\n```\n\nThen, `cd` into the `thrift-server` directory and run `npm install` and `npm run build`.\n\n```sh\n$ cd thrift-server\n$ npm install\n$ npm run build\n```\n\nThe `thrift-server` project uses [lerna](https://lernajs.io/) to manage inter-library dependencies. The `npm install` command will obviously install all your dependencies, but it will also perform a `lerna bootstrap` that will set up sym-links between all the libraries within the mono-repo.\n\nNow that everything is linked and built we can got to the `thrift-client` package and start the example application:\n\n```sh\n$ cd packages/thrift-client\n$ npm start\n```\n\nThis will start a web server on localhost:8080. The sample app has a UI you can visit from a web browser.\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](https://github.com/creditkarma/CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.6.35","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-lNab7AReJfn0v3Tv7BoFqK5KYvV/lIMVj1r8NTyu2yRNU9Lch3Gox+VuzqFHhcwllbG2uXKfdTG3fyvZgfFFsQ==","shasum":"c4a21e3011a9e206aa7e2f94bb323de6dad0dbb0","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.6.35.tgz","fileCount":58,"unpackedSize":185917,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcb1K4CRA9TVsSAnZWagAA3RMP/iglRuwIjQKovkk5wsLp\nda88+f0XZ6Vl6XoXwaqDocrNHkWgypzXAycCNRzIqIqOgogTNnBPqQ/dTuAk\nHaLa/JQMO0eeJbuPwmtCEHKCeIgFBsenfZu74VCK5KcOrWFoAo2IKecOrXYf\nJPJw/os8BxKdV3EzQrB8edUAY+RFTo7BCc8DIS3OYziIVhU20kv5wqQd1Ecj\nKPYIrZsx/JN3/f33BvM4Auk6imEUllk+xb3RZ/ASzcRqR0y/zfr1teMNSB+b\nji40w0i7Oh3d6nMaLR4WSCmSCv3ESUsMS+wP1Uf5VrgpeLp7XdvnLm562dHi\nEwMLdkeEefdcQdmEf1Tme8n+7dcbrxpcWYfQXQJCS4m1ylRrJaERYU0B4tQQ\nO7lWySUWvP0PhZk0PC2Npop2H3SRY81PBT3sRhF/ZK4IhpKGznKQXYWEopul\nhedRYCLuPdnjNMO27CI9S60YYb0rViH+E/HmPunOdq4yaxcDfKnLGQnssQZ5\n/Ar6MMvSUbjOyO8gGwencYXg7XKGAbW752eWlQ/oUvhAAFkRK8zL4wWn1e0G\n7ON4Fp+uzo2mFtlKo1Mgu4mRXFIj9fD4B/jyKqWeO4ZhFkZj9068rglP5HYX\n+vK+OkO93+xF0HVvtGQMmfQ6vAq5k/piWqfOkpUQqUQI5oVQol8wF61h6Czj\nCqXb\r\n=PhGT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGAqON0/zNRqzv7ltSRvG4mCWWxCKE76HCLe3KezluUQIgFv0c6KpRk4CM/vRX4sJcTyaKsFfQTJ7V+Yi+qot80qI="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.6.35_1550799543568_0.83133729070232"},"_hasShrinkwrap":false},"0.13.2":{"name":"@creditkarma/thrift-client","version":"0.13.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.12.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.2","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-FMqZc0GtJfg+vQU07R1pr6DhJwPPnBQvdhWhMt/OEw59VOsaHelrmV+JVh8mrHE2v+WmDiPpzaA/ZPYmHUmWxg==","shasum":"268d04e330a941019410a6cf0d5f84df3dec6d07","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.2.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcfgeGCRA9TVsSAnZWagAAbSYP/RxVl/wn1OGbMkTPlPP9\npjnC+nEC8U8GufwKRkOvrUN/9/ETfDmCdJMgAWKHg/P2e43mZZZEuG7pfG1G\ngsfcFkxF1LQXZUokt8ljibMcSzOocbabNWYTFUCRhLwwDTCcgzyZXYJ1h7Ng\nR9Ndpqybn3om5hBiOf/AVwRut+fzBUcn+Jh4BEYhf7rMuPrXW1MlmMOzfOyD\nxvXzEwV1Ne2QwEygVLq5YR/LwIZq5ireiSa8C/nWkPIVx1CTNMLAJ/HDm4pB\nysZh76nDqFv2eLOm3kmQMr4rJ72LUd/0kQiLpSS40v94y/4VdMUcMAz6vMT8\nKJSFlbD+AW2KL6eJyDP7kBpW8xhbzqPnx4fm2n+R0Pki/N/RamP90yJCccua\nRqcLcVlkoR9MMwn2g5IwgMEYNBzOK3ZADmgS4dFi3UpUL6VKvw+gVLUdUQPO\npHR0mOFWOBoXZGOJZRmTe3rnjWsirS2KXLaEJ9ivd+8lERGUk6N8BckPRTLD\nmt7EKmZjzptTZaSpla00UYvizUlVaiSfuOcNFDvkYcuV2wi0JJR3SS+DWD4P\nE3nJYd12pBCY8reunRmW82DdFQXGrVO7l2I0kFuK6BMEb3PtO8pk0IYapBzA\n8sY5V630tTu0WKtX/a4GHVK0wFQ+Lya6dq4tUFdqKxKxGbJUElHHKZ23prlb\naw1i\r\n=uop3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDbhudU+uoz3k+2hfjo/rvko1GFnVRD5H6U1XPPqUmgEAIhAP4gJWb3U93AFWNmhmdDZdFsuCPS0aY1A+8aPtTXTujX"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.2_1551763333149_0.9900029417284875"},"_hasShrinkwrap":false},"0.13.3":{"name":"@creditkarma/thrift-client","version":"0.13.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.13.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.3","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-Sk9F5KV/RQVEXiK/kIW85BN2oA2Cfnzy6bip9CUAJ8b99zYvmhJi44zNlaqFfoIwHn8MHvtsrpFgS19HyG71Wg==","shasum":"52379f192822bfba3e3360677da91fe8ffffef2d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.3.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcfgg5CRA9TVsSAnZWagAA6M4P/jacFV9wcdKW6hn5VH3E\n171w07tJbFybCp59aQatKzy/w15k9l6RL19N1jTff+JqxyprEbDOTwJlMWDR\nSCXsji+CTWrx/sgY8VyrHSZvA9ZWSqfIztK/NragFzCglvl4Um2NbDzGnne9\nnifhnSglAHqpFISUSHVvzT84PPGF2qslNnGbFIXMBlOzBLZWAyI9mqX8Q41/\nJ6i9I/Kl3KoselCjdOpLwkau40xSiFw7BqLOglM1SNDkXtTurc2eIz0xihex\nlprUMsbRMPTnvoo4osok4hD6gg3AB8AQ0uTXVKIleFeLFyE31++iVVeY7j1z\nYQWEE1V4DVJ1tVANjxk+a1tiJu/NnHSEWDp8zgftTVo84lA17UMmU0zW4/r4\nKtwdW+SlIrrsBLNootSns4SREHJ3SZPZ8hy9ZRKCUELX6MECVHoEQ52lczKy\n5MKwnOlyWfrJCdG5qQKySbiqFImMYgsJmKbk+vJRvAhVKnBORq4rFU+N2wdy\nibW87wWKiwpx1daaYExGUjh+s25u9W5MksrziK2/Aj0YqFfWm7F6jJ8fIYFO\nSz8B9PAa/9UDJInuk8tyzWFe3PP3svngHkkR2acQbcM+ebk+IqARr5AFh09A\nrucfpTDTiGvWK6/f2+f3umaNFT7AHQfAz2njN7Ezl1zsVTAn6pdMvUpp6XvP\nzgjl\r\n=SU/O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFKVGhURGUAwpc1ck6z0XDegA9W2LStmFzZ/74l/rzTyAiEAk4dfg1pLkgh3M3jDkkcdvqbI6LLL9A4pl+uz5QlPNSQ="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.3_1551763513189_0.1778637916731769"},"_hasShrinkwrap":false},"0.13.4":{"name":"@creditkarma/thrift-client","version":"0.13.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.13.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.4","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.4","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-3Hzuoe3hQzoOWwJrMJ1CiPmUtA5JTpTOyinK06DNRXLQyvjdu80Rypw5gEtP5UKhAREblAg25YfzF5O7bpM0Fg==","shasum":"cc4604010f641ecc917032a8bf352b1acba1305c","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.4.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcfpukCRA9TVsSAnZWagAAUDwP/3xXr4S4UlslvyLlktjm\n6NnRzbKNVOLVc5z4IsNx4gZjOC++2Ip5u0UAjdpqvvJ4vZvnsPQuRouI6rrG\nX2wA+lAjsbUEsOtyRoCBZetg4sbJ+eWydnX+uIbCbPps3/xirssaimiLh1Kf\nvWiFL6jcl7yFC2B0Xtplzx67sHDh3oA5tehr+nYgD4NTyYFbJ+qToLxRMX2Q\nX5v+IBFzxtLX2Rvga1uM4jKmPdb6acLlGObyMRRhUbGC7VwzgFhZUM3cpbba\nLrvt82N8SyIXOu1yI7P8aXuGg2NbReer3OFQwHpeQNHdaSlI7wFYWoqwg43I\niVyXZISh4osN3/It6HBMlTNXy7Bui/ZOw0DdeUHLrMziRNsUai3WU5Nt2tJ+\n8p0SG74keNH0LEh2vL4Vz+ehBCiiHBUsdndj4/WXXxlMFpid4QWb3dO4ycVR\nyiwql4X+N9i9MgOQ3hQOQqXcmO1A7kt1HgT1rf7UuxCIrZcOx2j5AYJw7eUp\nJ924oihLqIzjCgVPuGxHYV1Qa350JG4B1cqbTj6ASm7IP5rDKOHj9aNPPhEm\nSsh24NYNYAk55HmkPVvVkr9WynyOYYvz1bfz7ICPaZVQ8QlWkTrxygUvSiZp\nF9gMeKtDqXs2MlnPfRp7WXeAnS+Dd4eIx3FtapWMopEeIBVwIDNvcIIjX+A5\nfKUp\r\n=Cauh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDe4bO1Uive3J4hwJZVHMZn6CgQU3gEk1JWrhFzxaJIvAiAuSL04/RZT/BnyJIKIDkqgHbkfWf5I5dVXJMgW83r2PA=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.4_1551801251277_0.9095462292989915"},"_hasShrinkwrap":false},"0.13.5":{"name":"@creditkarma/thrift-client","version":"0.13.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.13.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.5","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.5","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-MTv+t4BmUcjuXW0hhK/VCGEBFRCpzxTCni9FlwrssagltGZUhCFqU/rUy6xh5+p1Lh2Qd4rYneUeFEiuf2Z0sw==","shasum":"05e6a10be7e19b3deb62347e5b56e16ecc4fcd91","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.5.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcnbMXCRA9TVsSAnZWagAAI5IP/RzAQsFNZHu2gFLbg9VE\nCNgAZ4KhsMI35/YHdcdiC5zD8BXXZHHU2F//7h7noMn+K/PewcxZfhh9YphD\nSrUhBSGOEU/cC0r9q1krcgkMfVj2ISxF7r+aDcvQ3GqpxFOY8AcBRB89AYzw\nj/z8lGJeJvoDphasFiPAxbA7ETRW0fceICgZhp7ohUnPGDSKmVGlIitbjC8p\ntXl9pzpW/JRMceHW2EJHdaJfdz06OuitH4nqAKVLhp4L2rvsDfTlcUn+z4ip\n5n/cGvLmLHaOSmFGpSVTKZFQz/6/TWhWE2p3ONrK5p53FHnv4J/heWLNhZUR\n61Yl/miGweTCjkUQiK5SvpCQGxXU1UksYoG5Ef7VnmFCA1/ANdJrp5ase5xE\n3v7h2bXprrpgaqMDPKgyuhZXo40lxbKwlHqV1o+qBxBMACd4XxGob1i/4dgj\nEmjIHCy5F88hUWQojV60w4AhjnqT0nGk3BxEchlefxDeFFNRkFMJDJMcGKFy\nTdiQ39FfxOKpvu21DBHh1FJk3VOeHZPAaA97CiKBlyoJ1DptyEAdliAJuMf4\naTbE81IFmy4G5RtuQWEOirqlomCUn3O1Qcflw0W5/Mk6f5Vot7CTlf479q8Y\nvjHH7d8QF5mLxc8IFupqiHSRtDREqqKK8Cd9QauTwCcf5Nc8kYGQOJS2ViHg\n5xVo\r\n=wRMu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDE6/B+XJNKArWuwZ2YgQAjQkAsRbGDlkzEtLE+929f1gIhAK70wbtwUILKZOuvcPo9W9mO4gkBlEdOTa+PISPf3YK8"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.5_1553838870813_0.7816710914699503"},"_hasShrinkwrap":false},"0.13.6":{"name":"@creditkarma/thrift-client","version":"0.13.6","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.13.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.6","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.6","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-3Dcv2QpGX1KrVKYJeoX3E7+Lw7kRXPkUjYIbZXFGcqg5/gmwhVQhEGQRF5o3s0m/+hwNJ85I0XHbW66H8+iwXg==","shasum":"2718494e79fbe12f468842e7e1e2a8fc634bcf13","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.6.tgz","fileCount":33,"unpackedSize":69191,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcsRCmCRA9TVsSAnZWagAABPQP/1pYIdgB8mXencz6wXJH\nBTfIrqFMeSWuPbduTB25g8Blm/JT+7Rblqk6hRlY5prjdRFhfzqh2PuzJhGu\noRVQeFEKaedHP6IC4dP5WQXlRdnc30swBzBgsNTa3gJE7oiv1GIcOdmwkMe5\nHwceT/pl5jBWlrzjx5pIV6H6QFPnqvbrBX6jmqXEzn144uFhDXgoSD8oGdRF\nlsCQ8WKkstDQrHnD3a8is3LB9m1BROpBP1QMXBt4yBuibtsNo/2eCqeG3gpP\nVHL5X8QrxwLZ4bmOH+80zZrU6fdw9WeogA/vatdKDb9rc9lQDb9dv4x7SyMg\n+BsQGoVH8g0zYptqGw5NcagrNieR6xja2w731sLuFVf1Dimx0F37tByVm0ZX\nru6Xu9BdiUEvNTqxDCsIWqURMCM9UshNMCTMf/4J///4Xyrj7Td2nhxyvo3Y\nGZlQ9ykauDzldk3t7Gw79S+VlCquVGSCRycnV2OeXg7gcRropEwgbj+2u2L3\no2JSxLGND3pmpoLsaapSx+jOPLqYeNtxp3gNRSYDVbH17HtC2lbLt74s6OJT\n/SoVn2OeNddeWmXfXXrTqNQs68bVj1D6bojXoArGvnQ9uSVe+xEgPjEBDWth\nD//UBG/o3Pf4tNFrKn1xfM93whYmqAxXD813+huatuNQ9m3ikwEr/womLb0I\n/lUE\r\n=9saw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEeQJC9/a9q7ZWcq+2YwZI1s02mzBCAHuu3h6712w+xmAiB/VY0tnsuNtMwT7bqNWBKIqpVftQVBT4E3eFX+aGI/sg=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.6_1555108005586_0.6325932131400782"},"_hasShrinkwrap":false},"0.13.7":{"name":"@creditkarma/thrift-client","version":"0.13.7","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.13.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.7","@types/node":"^8.10.38","prettier":"^1.15.1","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.2.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.7","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-mr41pxPMG0LHwPPzdiuJjG/rvd3J9zny9r/0t5DAcwuH8lsC1PQuJHQOdK2BOHr+G7wVj+W8On7nScqTnsiKtQ==","shasum":"28ffe0c842508648016a6500d79e9258833f1275","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.7.tgz","fileCount":33,"unpackedSize":69147,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdCZtYCRA9TVsSAnZWagAABQsP/0NoC0rRu/qSb0vzWbCm\nofeQVEgw4JiETNA2/DGDeNJk73e1chGu8oPancPFbpZELZ70Pb3BKE1h/0qt\nqgabN8Abu0Gknz6rRs/PT5v+f77nfMDgRM3PJPNHUmBYIB+W1ObzULjl/b2B\n7i2f1csKxQ7IR6wL5hHHdI3M2Alsj6zZ2x9uhpoFaeT33uEUJFRPmmXdDuUf\nXM3F2cPeFutaGTFtZDS7oIixcrNQ2t/PV8XLuEt0ZmekH/FsU6vz1kfRA9ZV\nYDQnd55GoTDZ9K7prkBykbkjHtGHYEWIl8p2bfHfLErawVuyqCIXwzS1eRKP\n5AUVHqMqc16+EzokLD8Eoe30Tvsera+hAANaxTjr3aeC77ECksoZJSruhixa\nxC2sO+ib3FPGDGSDW1IzTB0PkpsvcJxJJb3Jb//XWMoJpl2Fp3Tr56o4+uZb\n/i5w4UYolXjDpkgYkRoxaQfugRTcRD/G1F8M5fRhkpy0y/b54mBdY19aoD2s\nTUrDVI+alOI8X88qdZL3iUCGTqonjUQ5w2Zru+lw6nUIoliFOXDFqyNVl59E\nZvCCxm4ISzU70n2PlCCxkEsF5kmz4oU0ThcxlQmF+R3pCssbKP2Bk5z8aFtD\nsg1qeVAW2B6VmupBKk4w5ivo3xcLLYZTsWLpQLkDCy5kwjn4p5qAbn/eCmT3\n0O+Y\r\n=C599\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCtpw978Q5rxY5eMV/Jd8EcWKmiTGTu/Fe7ZVqzQdzPKAIgO36KcIlGVBASuDTGCpzlpeHN9sufod1zjlC2LeQfrnw="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.7_1560910679151_0.7293864120783473"},"_hasShrinkwrap":false},"0.13.8":{"name":"@creditkarma/thrift-client","version":"0.13.8","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.13.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.13.8","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.13.8","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-WVMLMmB7Gva/eVt65zp5B2CMtDlBjLXWGgzXERkUQHJfdcnWOovWwAZwLiqsQlgilyUYxP7O/WorK28s9W8yWA==","shasum":"8b338f0fe84768683045211b832215b78c81d688","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.13.8.tgz","fileCount":33,"unpackedSize":69480,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdSzklCRA9TVsSAnZWagAAs+IP/ReUQaN6RdLbgytGsOxO\n1qlpTrT7dq0QuuOu3UQX+/dNS5b3/wRfUvg8Fn7U2r8ce0XtUjbsYdHRpnKI\nBL2grhj1dpekD6V1QZgxCqGkXq3hVyOB+8knhJ72YDYYFJiiDzuyZvKPp90p\nCqGgOXd4X81WPFQrQVpipdscDgWeG8tAbSwHHYxYCMuLkdgueOFFbt+zQshH\nOSKN1axYrHv1vJMzUnj9UMTUsooA2lqiRns21dLEqxcmKUSWStCu3VB6y95P\nd82WHWJkJGjvSlgDOtV5b33TU6iJrf+Z0A3ANNmeHINaynICP2S18SOcnixN\n+foq3ipHTEZUvmx9C2GJjkJ+AcUI9Dsrd582lqSm/blacGtJkSKBhXb2SBxj\nXJ4o8ix2Yxl0++roJqL7O5QruDnSI/mB3PGABOpgFcWOmZLQ4hgoWdE2EZ4e\nfYKnYv3twyU0XdjUzo24HCXDXYEsCAFn05FoCvmBnsVGeq9jSDYZFByULgUB\n3nPItLn59JjZ6Uzcj2MHkY9f9OC8H9Zanxe8TAg2LovpGMg6iNrMsKSM6xtK\n2qLpPwkeB6QL8eusi4JfcfCNWzm2Mirj9lObHZv5PlBFVkEYA+/aPgVmIePQ\nVFklecanCKefs1M/2RV3qOPQrDFbu5mU7m48VfhqA9XUNnNLEfWjpxccYjiU\naAbL\r\n=Bhs2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD5q7K0eBWgfNAzGo/jn3IVm3rRm3jpbEPNtfl+0htBqgIhAIHIxyMHsAARhn/lVykVkZHfQrgvi/Vb9Y/ipwmqh8OU"}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.13.8_1565210916493_0.36124163906980433"},"_hasShrinkwrap":false},"0.14.1":{"name":"@creditkarma/thrift-client","version":"0.14.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.14.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.14.1","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.14.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-NUz4BtBGcZyX/EZljOGsUAbOLEVGq5C0E9JGXBGGZVgACrqBKspv42pBxVpzbqnXGbJ3y4nz7KlGbpWCEKZWDg==","shasum":"20115a2fe53bc92b5f01c5346a43d8e9d94114fe","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.14.1.tgz","fileCount":33,"unpackedSize":69480,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTgZyCRA9TVsSAnZWagAAgLUP/i76vGcaXe1mqwQnUmHK\nxJKo8w6Rz+JhBIqpHLR0CDql4hDkz9MZZfAxFjDNnwBO+vqAvbCT5Qe9+uUv\n7s4TKpk84HmgKCQnzRy1oG74BOoJzTwKnxAVZXQHC3q+HBIHWdwpGcwCCLZH\nKY+FKgMffemWL2jxET7xNi48dowhfZDC2WKPzbRbzD7Mpi+FSjqAhkhxQshH\nGz4DB9P2IHS+zbbcamJfV0ISJX0tmq+wTsBL6mkrDB8PicoryCd6F3TLbvUN\nDHUtlbHEtF6t6cU/M+ETbwYKB7eZ8vEbcWyYuMgCf21Zb2HVRIOTDsTmING5\nDXWwEw2thXgJCKp7YCG46TLKxqu22hnrOOVyVI//2re4oyIsBj/wOSuDMfkv\n4UnCZLQt5gC3Y4015MfSKl83kiHL2M142ETl5A2hQaWh9+jipsfP8v/NmGrw\ntyJ58EBTZwEayDru1jXDLYGANxHj+YTY0XTD67TaQ/yC8BfYqNi5WsStqASs\ntC8XUFr5sYaw4d59yjGJT1gEp3JeoI05/z9eXSho7c8CKGkgrDBA7d4APXjc\nh6BjjJNeQHx9c8UoklVK+W5em/o+XSN3k+LlWZYS0gEh7iFrZFcLyj6Og3+b\nSDZ61Rr8d2t6yjfLHwFif7wzL0L+BsOuCwO3jrxACwOVXFw3qsLFNNA5lSHk\n3umN\r\n=M259\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBpvI3ICF0NTg06jSojVl2+0v/6HJzrmaA3EdkCp/qWqAiAL6SHMHcF87iwO808uztSiA491X6SH1FQrQ5QkXPBV+g=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.14.1_1565394545702_0.9338591290620044"},"_hasShrinkwrap":false},"0.14.2":{"name":"@creditkarma/thrift-client","version":"0.14.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.14.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.14.2","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.14.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-MjFdvVpyuixi+x8+YN8fjWosepr1CdkUBUghwRYgJcvh1SgxlZgD+2TSC/m3p/R6fBzpHUrgYmWZVKIW9wfQjg==","shasum":"4fd3671d32a90e13fb27daced41935657b17aea0","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.14.2.tgz","fileCount":33,"unpackedSize":69481,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdUvPfCRA9TVsSAnZWagAAnRIP/iE/1qama7o8oryahurX\nMCLE+Bo75Yj8qWUjCs9r4RV5xY8xgSaaKe9VfX6Sn5BVWZoaS0A41Z/v+bF2\nhnt1kMSrtCRkz+jMKvpZ+CBscwtm19aNg1G7RVQ+P74OftFsMTJu54xpJKeL\n4K0BL/zngzu1xMgfG5HyHDz4iZ978gu64tsgBfhSp8NGI5WctxFKHnZNDAxt\nFozslxqKMpmw9dx7p/H6CB7S1uysnkYLr61kRLw+YXtsEAQKTO0dQgkUjQ99\nghOBwkMiKTxG5YfudHBwLGRXhKWlBc8Wpgl5K5L2iQrqxp53rC2ePp+VkcRG\nHdzUkqYH63XbLG07oc5lJvai6iaKnDtwzPZT0JFLhcVWN5/8RJ1kqaPfHXHu\npbCovjfunqmC3g19W5r1aEUYody/NhKDyyl7jJPWkAkDjwIjM+C8nKSPplIA\ndJZX/ySweAHygJByeXi8Cfminq/YBBRNGWzY2QHRJQM8j73CisaLuyNoyWy/\nGWmFbqRVoiZAE385XVe1cfBNkCY5zLlc//pANl/TFv/u4EaG3PU08FxdK0uH\nPROroUf90BphRBI/ANuetEKYFNL6aHSaW8Co2B6D1t+WW79FcifczE3xX/uy\n73I3Ul1jskE7XzB3sJtEtnwzd0wFB8UGRDQzVu+I8rjGSMA1nK3fB8bP+2+z\nE1nX\r\n=wIpo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGvNAZnnAFPUZtVDTArKaGMvAvJlwQHts7bOawX5mVxgIgNItEQK2O0fp42+elj69bpO4qVYuQbStFYqliM/HEMEE="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.14.2_1565717470260_0.7233743131530379"},"_hasShrinkwrap":false},"0.14.3":{"name":"@creditkarma/thrift-client","version":"0.14.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.14.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.14.3","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.14.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-ZVjOolVikktc2kZWBbddbyBWNzLl2MjnBYGjThQlUujI+fAHiHfsYmngmO5MDffZaRyY7aCIIu+fG2Mlwa/1Dw==","shasum":"434008bdac798caf251c9c966f1bbeed0a671f07","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.14.3.tgz","fileCount":33,"unpackedSize":69481,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdUx1SCRA9TVsSAnZWagAAy7kP/R7F8BpaTNuyHB6RMxYR\nffAnTXV/xhyNf6btHNIYyUS5jEqB7VQbqfirBhCMDiZ8iIWhL0xWii0NthrF\nD9CFzcaQbqsEKG5e33GxU9Iua+YehaCy+uPDnWsgCrxtlbxQCWUcojeLoymQ\nRUzubzt6Y9C7TUhR8rwwUY9Y60i/tobK9tpUSLjSKeioqTZaBinGEphgJjf9\nFUwHiJl9XhaEA8HFaiqK091G676dJsrvk1kUOHg4z/OY6c30SAnmMf2EdHH0\nQDb/nrZQ35Eo1sQnQNBVflsNXpx7I18RoBksT9vXnh+g1nirlHN1rM7r7oOK\nJTDw9U4EG3RYz1q2q6XFKAMh7+IqKzhlkANJejCC/xNSGjJgPPJAkw0H2i/R\nYKl12itlgM4SALc22A6q4+YOLxZhEFW1xCoH/ly/yOzCMLQ+YVYJjsHiUe5L\nLVrkoc8PBOdi2sr5Tq6aT34sOYtgOy6IgXk4aBHF0McpwLAJVCArc6G3LCSZ\njmazlxc4zK00VZUAZki5P4/GqJn1vqToq1ny57H9dZm6cJXFT4d+3PdVAZoa\nBvPVqqICh5vnlwoCCYXQIvVuHKVnibtkZpURBRUqPlsrehYlBr7gOyy+2Q6S\nQ8l+IOYPndwojcU+u0g3VZqb0l3+xLTF+90fOGNUbLaNb942qU6xc8SKnjK/\nuvyo\r\n=AtTb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAtvl5kz9DG7KRHKX72viZZdsNYRnv8EfJF2GbYelbxQIgFAMGt5CH4qGAdU/Kex99iUXiCuq5+N0EzzzMSZ9qlLg="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.14.3_1565728082052_0.5597496033166651"},"_hasShrinkwrap":false},"0.14.4":{"name":"@creditkarma/thrift-client","version":"0.14.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.14.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.14.4","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.14.4","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-fcj9X8pt5q7nd99q6Mod7ryrNvUS1LxMvsVgju7/qW/i1fq1y0fB3NuxjLlWHBYS40MnFWaFfLneRscBw3YZTA==","shasum":"31db4b30a36055a3dcc355a787cb6652421edd6d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.14.4.tgz","fileCount":33,"unpackedSize":70796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdVi1cCRA9TVsSAnZWagAAGNIP+wTpwqgok+/ifxJ9nLZw\nV9W63Om/Y7OijmYvWWt6ojk7jvPRLBFoORK8ZawjGneBwk1yRlLrF2wz2SQk\nMKVvhE+twUny+AI+T9oSh9eqrh9NTCkAW00tcgJ8/3cma2kCbOhZ1r6vQJHP\nCCZMgTTx5LhN4Ox2XzFlvpA/1s21pPKt7g64MO9FcHpfi9HEYVRqTrkFIkuT\no8KZDo29g4HnNl0pKUGWnXmtAMIIxTwUi1kBovyrOiGacOrFHPdrhRz6aP2V\no75Qcmy91vmOZF8OKBAXCiJAxtVi3eKkd4cDp9scQ22hchR5uvvpO+GnXNxV\nGDVIDlLtWfzKvtJk9Fg/eWDus5IvWTLAx4s7tFt8mzTGz3OKZvEfnbv2K8Ls\n12DIODpxLe4XXEP6JHLnYi0DxNHbGnpbSLSrsBCe4wtatjbCZD4tQfTtjqp6\nmN3o7TGhfqVzjqbjBKVvsderNJxiRk+oK1jSgk47w4E6kNowqlJdRtEn4MrF\nxw/ojH98njxZdovFJ2V4nwab3Wu3x3XTvsbSH/oN+Ka53vbkQ9V8HYyRDts9\nK7JclhQJ0+gEJK0tw7yqnNpMQpKTaFe3P1wv2Nr+3s+jMhqV2K62ws6WxayW\nGOv35sqYTw2LrnOm2Ds5MYyec5kaXXV2Gjf/Zr2iBS0Z5t7R5mF8+pg6t7mc\npqNe\r\n=Byaa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEp6imft1OSTGkWjpr5Wzky0Gsx6eLdmUYbGz/MHu0nPAiEAhHZRfxbJwpzGsV5p9c75WJQImm6GLRQYr3LyExQ7JgI="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.14.4_1565928795813_0.4158772332215763"},"_hasShrinkwrap":false},"0.14.5":{"name":"@creditkarma/thrift-client","version":"0.14.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.14.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.14.5","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.14.5","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-os2HoVtAXtYBy/KRcklzQmRPYbzs8o+Ww+D5vqdT6mSful4T7zo+W1toG4QDIWLcJV3ru8nGR9qFUNwegUlzkw==","shasum":"83d048b435509d106cc02e827c6b8c3564b52fa9","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.14.5.tgz","fileCount":33,"unpackedSize":70771,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdXrF2CRA9TVsSAnZWagAARPwP/i1cyxbghbpDOl0JWGUz\nfKJqtoGVCrJZqsirSjPs+lHHs3MxgezYHij/cxwfHmQkmMHJPrccGvYUJ4vM\nF9gL2SLZu/K6GSrKiM6IKgltCB4k7aWjGXO+S7Nh7Sk7sUJ3Eb3TBKWHjUkL\n8OvcacArodS4VBfDSJ9Rt1P1enRteNrPJShIp8sn4fe+dn4c7qwyd77IdK0q\nfjNINydNJwKRdnjRy7Irfjr9oZNJF7uof5INfX4j7S1GA9YkT3jwQYXoRWGM\nO+wE+1sfdUueWVZEc6h5bm4oE3YA7rrCoI1g/RDm5Ewde+ee8Q6IDetXvoAW\nCoUH4dmGNvoT5HL0p/GAIgQQqKYcC4uJYa458oHVnPsTAsFzM/mZMIg9rocN\nggahzeEKFMbe4GBsRJXSobPBm4W3qVq2tGnWz/tPL6T32Va5jGZs+lJdoSYY\ny66lmD0VKXlz1IcnSFa9ete+UMYijF4cpyItKpJGYnN+gRR5FNRuMJPq/j9p\n3OChw7nHOyPqvwPtzbY9gczAjTiLN2G+uvN3ZpxvHD1Q7Xje7mnfs1gN7M7u\nGGLl6hPx+r1+1fDCz19+arMZhEh0eaRXp3J3L05AiwR2yjJ/O3na5evI7p9o\nM69mJj60JA70QJ3lmjrPqBorqfCmK4DEOTz22sKZiwuxd2ypjtTihCz3yZve\nCfg0\r\n=IDk4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+4m6ofoiPw6L3luN+7WD3tNrJRzvqqJhzejhjsf9uWQIgdaxc1Ti0MnI+3Wh2eob9c4PaXkpkKNiKPEP0Fag98Xk="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.14.5_1566486901295_0.6822192098697799"},"_hasShrinkwrap":false},"0.14.6":{"name":"@creditkarma/thrift-client","version":"0.14.6","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.14.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.14.6","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.14.6","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-4xUT1lIvLppXzbMGU9FExpVjQNZIqR1xG7SmOUDmf7NSQxj8NE592Q5ViEXcXakPY8vwFil4+amRbs1W2CvBkQ==","shasum":"cf4ed6b8d85711eb603ff7a12ae67ca9f538d77d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.14.6.tgz","fileCount":33,"unpackedSize":70771,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdcVwTCRA9TVsSAnZWagAAUeAP/2Fw9FtVDsIEtr6pxk7p\n4GUjckUBSc+OrKDyfp7Q4dW40C0SNR4BQSbs0d8GRpUH+RiF9QNDp7xMrek1\nAKK5G1W3A2emROirOMCZOzqu3NEysZQH/IOkRgStuPW3CGQ/VJjpz8x293xq\nKT0GeG03OqQTOlDj2eGGbLyHXZ/sqIGMSMbh8EOxzzb8BjubAX2OGAesXbOp\nMLA72+hnMtjvXdhwJmjyb8/9pj6TfpNrC31PPuxWP+TSXh6GoHz6UmPT+9ve\ngKJUFx7q0MNzwDNxXChd0WYv2R7UE6q2OFjPH6Zg4hp9RF3pTzMZ/3SonGPU\nhWao5GtJxtVJiPfdvbZY5AtFkob4LrzHZb9um8LLlyvk472rUfIw5UC8sZcP\nrBN6r+7w8GFt5liXRkHNL5LD3Y1gBNJv85miV/5yD7eQYBkKYW82Jb2lCzFX\n70Q88WQcvIRItAB74TlkPjMOzRRs8GNrHB8FlwEiKpxNglr9U+wiPdVpHnfK\nG4QH6ORC3iq2mXyxXksGXgtYnbYpBKHP20bPrtyL+Vg7FcBXWdYgkTBcvMWE\n/X+A93Nnis/wYL6qmY0xG31jbGCv8qB/SHoAdQ0STLiKJ0i7zLln/lybN9DF\n3RzxnWPVkZQ42hCmWolZlabQ/xUlJzSVViMRg1RVXA+x6GskAdGvO7T/H16O\nGdHm\r\n=3fzS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH+cJDoBoV92nKrQ4OmQvo6KEEh0kKDB3sj1l7j+pbXgAiEAz8OZpb0SCISqkXXaBmzdvJxAByPVqcHvNYC99jh63As="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.14.6_1567710227096_0.3144325903470764"},"_hasShrinkwrap":false},"0.15.1":{"name":"@creditkarma/thrift-client","version":"0.15.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.15.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.15.1","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.15.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-T+n5viUY9ooJzFnDXU9Rs54fLzG68oFzkyM4vDJhp+76qvzfKkPRnWZi9JSSrIjhgKqr501MObTmiLYuX/+p/w==","shasum":"cacf36351eb6b7d190c71e2a27d44091b32c0e75","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.15.1.tgz","fileCount":33,"unpackedSize":70771,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdlOWqCRA9TVsSAnZWagAAE3EP/iZdxzyEJNEKie3RDXg/\nKSYC0TmswbHWsmi27RZn3C0REBtV5CuJhZL0/qHZbqM+hVN1A+f8hMR/B/Z2\nxG9Uot2jakInCDSBINcWzX79ri1HQsh2qvGBQS9uH+Ank30tYdtUv3ha9B7d\nbpJUrkEUL4M6HxoGRv5ZYTOM/tZxY0ltoDqvJBCBRcqYwMOxQTQ8Z5FfsvCo\nmmE67U+UvFLzdjUbk+0WsbEjOInnUPRBwi/9kLQ9a82rOzoC288KFTSbKEcw\nsDC75tptvfOqy+wm9DRDqZWODyqIZfm2OGvHzlYpqTH8XLjz7KJ/71qm2B1s\nDBTB+ZazKoOqBiH/4qiKQ012ImovhJqBuLhJa2VKrdC5J19YtbgJJJJ7iz1Q\n4isYQKEXseTejEQvE7T37JlSWDSbLLTtIrakAQPybCQNLNFSAvKiCR/oMQEY\nVzhuljdV8D5pzsmbC/rSDWeyaLrPhdhtPTSVEg32JTBnhWiLwrFlP8Lo7j7M\nHWWF2d/jWHF05ra6h4D7sfeqUVUDEwTf46OCeyfGN5otDCKTHZJhJ1gl9p2l\nhk8n2D11RD0EbnkQHmWrv1mnnfsw3/bELSks0Dg/QaUMaGtNpL5DiCzBoJsc\nSTi+Ge23S7SxMsp9q4Tz3pJbqmptefRNikHrGvNepu/Tnjs6Yv4P/kr1SjDb\nuH45\r\n=WDuC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDcUqnZAt2wzeXW2Cc1o8RUe1T42PdMSS6jWaCApaxtpgIgITvMfIavoWWQ0MNXuaTZei8YX2vyQECQIKqUesyo7wo="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.15.1_1570039209472_0.03791999639552701"},"_hasShrinkwrap":false},"0.15.2":{"name":"@creditkarma/thrift-client","version":"0.15.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.15.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.15.2","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.15.2","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-R+ZtOLyD5k5ZWfUy8pl3KfP/toDy3EU/utlkBw4QtVgiMABMuFC0BJzApv0yRVgj6u7yB2UKBKVUyB92OV8POA==","shasum":"c0786dbf18f9614302ea579af6f8508d725f41bb","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.15.2.tgz","fileCount":33,"unpackedSize":70774,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdpNIcCRA9TVsSAnZWagAABT4QAIskYi5+LGZiaUj5ESZw\n0xTy09A0O+xtoJ7F0+O+JE0vfyMCdFu0bTymK99fc3owMItftiYQ+8apQJH1\na8OuSotKD9BK9OYJ5mW/apMzLybW3dkGrK3ruRsBUQAgMW8VuKRSHbkUoakR\nooy/dfrefIgTsjtM9pS+0RVPAY6Jl7I0gGjTHwdekT3R6BRVkmWwg+2ydmHx\nogJvdot2B82NFOe5XR+H1NhBFREuK+05Bk+zK/F6B7s3/4kkgzANTc1bY+Dy\nU5BnPZJunn6haK/qfkR080Tlwdxvw1HvzaY8Zrfn7EgAD2j0P5hveV0KzNOi\n644rjomk5XqVeWeqsOHwSUwnGY45MeqoWglNMyoZLIgAormSQVjlQP5XaAG/\nJbA8c0kjQkaF1XX9vfLZE/vDkvLP0WHKOOkm+rg9bO+ickZjniKKw5dGhDv3\nLOPa1a2YuyIXE/hQRPJsqV0RMTGCgly+tfEIcmzcuwH02S7xIAZRHQrHwVb9\nPCR9fWk2/Qp2mqPcDCoSiv225JnmvvfK2JcdOAaq1byhehXcXXXJ28fTiGym\n9OXMqBNKtvV43MQXksWdNXJAY7RnZh6Gv0WnoJ+wV8TfFAA6OS51n4NlPtAo\nvh1waTHu2vkiQR0h18+bVxamWsI2mnsuEps5+p30Q+MPz1DLoCG+H1m/jTTz\nCUtM\r\n=9Njx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHy1+4UsDtnZiMxeQPYmuY84po5XJHC2qlOqeTp3hjLjAiA5HwcZlYVlMUQWqrBq2qU7qg//PFHeEWAzMHcWIYMVbg=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.15.2_1571082778175_0.48834572306613366"},"_hasShrinkwrap":false},"0.15.3":{"name":"@creditkarma/thrift-client","version":"0.15.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.15.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.15.3","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.15.3","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-CqgYlwG0crh7ZM34j6CHCe6pRr7AmMQKPja+LR7Pz7D/pokypQprWRpqnoUHxXwvegcKL6DeXx/TyQk0WFQq5A==","shasum":"442852cb9d9f11e89603a195a0990a0dc40f700d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.15.3.tgz","fileCount":33,"unpackedSize":70774,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdpSN1CRA9TVsSAnZWagAAeroP+QHq1QOk+xjRFgb2KqGm\n7HIK4a9Yzqi7K90bOHiy4ky5qLsqSXv4RQGx+phDbEgpL4owkzr5eCuyyhii\nBl3Nry37CRIyupjYG8IeZGBWuv/1FZ//NdrFonzFPZE4ef/yu8sBs6R6eegW\n9pvhYJHtLCx/eCJ8kMU6FhwVTOzInB6QxHk39piY1DiMpLMFiCXdyeAWkQLj\nRcWcJCbUFtj+bbGkX1d7BjKSdF0LGrU4ceXV8WgPe3SLPLQg0J5pU9eGTyP9\nbslR2YeLgrAIXODWP43PPr6iSWFUEAZ0DgGBdnqTpGmz5rR3zBNZKgdGiRSi\nhAXr1ktSTwqkEqE2Kay4TxVsaYv3lciuAXpDgFS11ANxm60ZAWQX4plqWPaY\ncDwVK90fWH8nrkfkrGT+HA2Ae3Ja+eDpRsQDPSiIez713fHZkJmIUJC4M5QK\nhskkh9dtwvpFHfBXe1GIWhju0VhWw1nkcSwYU+qysGmbD7Ka/0sSipwVOL0g\nPV7+odURXpc1pb3oa3DHcodanzjked1lLZNlOnutUTv2iQ2c2Kos5YgFSzlE\ncEzx8DZTQcQVW9qwPECgoocQ1Efijl8mBaiRu5tM7b0C4wNDYKqMo2ebFXGD\nSGIQb7cFJEtdat0O58/Ek2Km+gwR1lT8Fq1bGRXwB+uctwzwMb0suEvoAHHu\nSte8\r\n=itPS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA2VcFtiZBJruVALmqPLHMEgSctQG9f/lVyMK2pTIEzUAiARV0TEAQd/VD8LDeAqi0R9HOsnuinaebZyjZF87nO81w=="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.15.3_1571103604422_0.23601682616616704"},"_hasShrinkwrap":false},"0.16.0":{"name":"@creditkarma/thrift-client","version":"0.16.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.16.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.16.0","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.16.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},"dist":{"integrity":"sha512-Pk7CGcFmqKjsA59Lf1bUXJYgu1oTAZlHN7P4c4YUBWJMfvO3+dsrcJsvQ0SKxkD4twRpQtInNWzodrvjelxixg==","shasum":"1bd316409de0ccdd820c1600003396f0b946a275","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.16.0.tgz","fileCount":33,"unpackedSize":70774,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeJ3iVCRA9TVsSAnZWagAA70kP/A2cJMhlWhaqcktNf8RD\n7jLVf/PSvyJY3hD1TgneIeqsj1Qk7fqf8tDm71tWlitDNmvT4iT2eqZ2YeIs\n5ngddNLBAQkKOcJkRVW9fXgC/bTJGGndvtTZl6fbf7V+hNdQTALFYgKwEs6J\nvkpkCbYWz0GtURGWVoZTzZ8QV80bPfnoht9jVET2mYOig85SGA3mA+9zGWdM\nbcUXGbc2nzo9+mTjP+MIQhcQ4n4EujAlZaRSh6tHszFxT4ef/3HWFzV9E4gM\nmSa2kNiGqnkLl0sPEnoUNeXA55d0Tvc9vq+UNHhimTUut/6CANnWg0rG13fV\ny5GW05EZc/cxq7YRl7UQijXRwqd08snef08ltPDr64nYe786dP60M0RoAZeU\nPSRqU3OZC8DCfvXQONpQbEa4zBrgYD098v7LcTJ0Hlx6CWV4VFtHD6TDcVeW\n3/1dO/8hgRZ6rAOm1fIsdAj2UD/YrG7ou2G5epjYzOfLKp+3FzQdIFg0lwdV\nCJcaRMNGQ8PATrIcAzhtVA/wKjkGQsKDmuu3IWhA00Zo5ZeuGOkDWbaRhIah\nmVfhIqU4IzqqYEQb7meiYbkoTeggJ/VqzQfxe9lwzgh+08mHkJocvmo28iee\nhAqKLI7c+hGWANccZyXYXKPBFqCOdzh2B643mNan5tAev2mnKdDcknlIxpd3\nektA\r\n=dYxl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC5qz3LRrkDvMYWMmr75/oh/qCdCYfS0aIhftgsf+PyNwIgeNAo0MupbkmUjCuk9cy0IrgSfsqQqtnz8PR5F2P7G9I="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.16.0_1579645077399_0.007232453268672723"},"_hasShrinkwrap":false},"0.16.1":{"name":"@creditkarma/thrift-client","version":"0.16.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.16.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.16.1","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.16.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"dist":{"integrity":"sha512-oTlz6dNGj0nQjPyTB+eLwMDE2DAsbsfgz4xmPt7yf8tMd4lazFY7eVzEK0slh6zj9KYD/wuS21wz3Bmofp3pQw==","shasum":"4d4cb01e7b74c8617396a99ab94e448653a6ea89","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.16.1.tgz","fileCount":33,"unpackedSize":71084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezrjlCRA9TVsSAnZWagAApaYP/2pm2dWfVSfARWslL1/+\nnkF+dXQTGH9FRTi1sU7elFQXOV4E9Vi8+EpxZlOkvRfnkoX2Vsey0zMzmdVl\nalt9G04ARzKf/V5DZEMJF9E3T70OTSUUM9lDbFFDtPzm9RQAPOjGIMQrjGDq\nN8UGaJ4IeoAFnqvsymAypmyvvqOLhZ9sKZtXEJ3tJA2nhuwkgqPQt6Sp5yZs\nqI05TFOATAAzip9AdxSypef8UpDrXXKlmfPlHxZh/EU5QwTysRJtjgeZLyOQ\ni/trm0sZrHv7D6/QMXnejmPsr03fxNy3L/p+mnHbTbGXgR+azl42BbFqXzh7\nIDUdv4GAr1RGEk+W7gyEyM6HL1fgq8sOyzaMSCvv31MY7uhnuhbaTgjq1xRx\noJBYt3OHKrgiyH14+GUrFjt8Cuk2AM01tP5If0ecx1pR4w16UZqFwYzYQKZk\nfHUbHfsSbY+Iag37vho4Y/W2ldvEpQ4mSLSLKohY6z9RvGZbV7K1oDFZkHic\nMf6FOsyLYWzC4OrN0w7K3naWKUZ7vtbfVRI0Ib/wkWnanUvF2iUxroN/+GBz\n2SHTJgnZO6oUgckP2s3sLjjzmWn7XyerKAxFoNDpy/F9XGRIIfGcmwqgSS4w\nFbN3l+COFEbPHqkuSGr+CxkyxyTC4Q/Tpy1JYKfnBdwjQ1dMjNSh2vPOLScq\nVz2N\r\n=ztOJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDp0H1wz4ocUov6Fw/R8oYgDfXyKMiryJTF0G7iHyL/eQIgV3vISDi5PN561estny60AHDQ5fKC5KHcpok24wT6HiQ="}]},"maintainers":[{"email":"pie@creditkarma.com","name":"ck-npm"},{"email":"hightimesteddy@gmail.com","name":"hightimesteddy"},{"email":"nick.nance@creditkarma.com","name":"nnanceck"},{"email":"UGAPiro@gmail.com","name":"ouranosskia"},{"email":"riley.stroud@creditkarma.com","name":"riley-stroud-ck"},{"email":"samuel.breed@gmail.com","name":"wookiehangover"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.16.1_1590606052980_0.8804907393807699"},"_hasShrinkwrap":false},"0.17.0-alpha.0":{"name":"@creditkarma/thrift-client","version":"0.17.0-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.16.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.17.0-alpha.0","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","_id":"@creditkarma/thrift-client@0.17.0-alpha.0","_nodeVersion":"12.9.0","_npmVersion":"6.10.2","dist":{"integrity":"sha512-htfTiIjsrpHjrDYItakurVD6JLFL/oZBTJNd3v0gbjQsvaiwMWchMcxGvL6F/ph2o5GV5qfzmgufghzhj2oR/A==","shasum":"763369305ca74c7d635a6a46700d9522363e388b","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.17.0-alpha.0.tgz","fileCount":33,"unpackedSize":71100,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZfNcCRA9TVsSAnZWagAASkwP/1GL2EIgHtgxSZxAkv9i\nKO4sS+gYWjZE4LsrjdlLo0x3PvL5PGD2fGUXtvb+1ZvG8wpeEB+8ypzOPOd+\nYz0aJkpcX+8lZDa5YaIntJWCJvoDOdaELjyzO+IXZ65lZlA996UfJcT7NIRQ\nUtZaWyUPJx20jbRFyRyBYia/xNRHGZq10G0CVNxAnGrVOAm85cNxEfJnwK/z\n8h0hJDc/FcCQyOzPjbjkRCUxchh1HnN7YD2fzoRkEKXf1weA51wPAxKjfLjY\n8HhO6r0F3b6yuptaz5pj0PZR2a19RtKxnsigE6/ASvjnfm8wz3FFR5LnNf7X\nDaOT/SoepkF3JyMkUEtLOlzLPXPW14gpGh/GTp8uKG1R7Mguf2arhNtJrJ7U\nAzuceo7iZ5UjhYL5M8gR9ghI3L6/SWdEeShJLy7pC2ODOqee9q34EGsjYD35\n5ibl2RJUgJmUPPwzV/qoKcvKpTu5FcqI8aNKbZjIpwsCc0Wy3PguGfJEOtSl\naf3yX0tY9ND7M+XMxBUgSqhbCXYN0Jg9Br1/NMtLr1shCY5vyl3bP9dYc3EM\nRWuRQlWChJ05Pdt9Oz15H1yiGvGt+sneTel9fREqen7LrD972WmFgQkuQ0kJ\ngkYo7CfIw0ejELIcjrgZVZXmtvpG7/RFdPp/dYYp17nytrIuGatXIFE0CSPg\n2vMc\r\n=D5cz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDI3CnuWqSTKz3gt7Ivy/57ivyXekLzGvBHnO8CwfpqHwIhANerf6vlAcc08TalfEWBt64iEqrtbmgrkQ0mmbzJ8Y+u"}]},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.17.0-alpha.0_1617294171937_0.39756145417581923"},"_hasShrinkwrap":false},"0.17.1":{"name":"@creditkarma/thrift-client","version":"0.17.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":">0.16.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.17.1","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.17.1","_nodeVersion":"12.9.0","_npmVersion":"6.10.2","dist":{"integrity":"sha512-4v1d/ywya9aZymkFJxE+l8AJ3L638HYWbucLfiMem3eKvgdSmwEH+EAup92Un6HBn93uDTJa7NakYu+vLemPJA==","shasum":"6d41f059ef6f32f56bd1e7bc1699ebc76b0c1ff2","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.17.1.tgz","fileCount":33,"unpackedSize":71085,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZ6nACRA9TVsSAnZWagAA2oQP/jV7+9Nos4uGMThbWx3j\nF83KycdXl6+rnoP4mLdxG8smmvO4NO2D9sIou5/dG7771ZKwhCZM0dUURuVJ\nXZH+iQk8KfrImn+MhX/ZqDKs1J245aLrm/Ub9B50etCRi5UsipDVXG562cU3\nPT1Ubtmu9uxHtQ5XqTB/HYTMMjtzDMbAwxww1L0oOmH6w1bJSyKhvdI45Sw7\nQ3Wmu2SQ515OychYT5LgxLJGRgA6fuBtIqnoQFM6YeDt88Ly/4LFLhEAsmTG\nKxGYUrU5HMetux6jXw/30R+1cjlvewEIeMwEsuFZmI1X0vpLvN5cpKibw0lP\nCr6D4nonNJIHwfaveWEcbhHQe4qgx62ftbpAdTtsdWLZUBOpqYEZdZdTy2ye\nsJkXai94SzxFg9X8d+VLCqf+RdeW5JdrSFNyXfdBLhPc2QZpchpLArIgtIcj\n8poCvRqndBv+qbFjOP/FMBcAXkJ5ahJwBDODZqWiWIVjzukc6g4gCI9KLuB0\namON6FfafkPwfpqG2kuDwP1q7nJBybpEoceV7sfC8gnKeAjUXGLitpM5BAch\ng1qUDM6MEBTBEOK+t3lLuk4kqjbgyDU7Uv8ixC4dgOOGjevGQjPPYYnqc7Ie\n9tJRmbuUGCwLGriHorMMdRBJ3mgt3tsBgpVkn3suP8tDyZ+dlmBeHPuJUpBe\nQz9f\r\n=kPWz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCBymFGtkFB95rACuh5R4TMMGEZxZEoLamCg1npzY25uwIhALuKTKHDUEyUXenjUTtHSTC6GADBntFTvciSFybSV/hk"}]},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.17.1_1617406400480_0.8577834988765893"},"_hasShrinkwrap":false},"0.17.2":{"name":"@creditkarma/thrift-client","version":"0.17.2","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.17.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.17.2","@types/node":"^8.10.38","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"3.5.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"_id":"@creditkarma/thrift-client@0.17.2","_nodeVersion":"12.9.0","_npmVersion":"6.10.2","dist":{"integrity":"sha512-xel9rz1bu01SPlHZEntJ7nzJsBlkyDRvLXaEAipGWFJjjDlYGcc+OjFsmoBuOC6L6lc3uA3waceg8jhZvpp53A==","shasum":"20c7a637948660e60cedfa3ce751d6d0d3fdcfce","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.17.2.tgz","fileCount":33,"unpackedSize":71084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZ89nCRA9TVsSAnZWagAAwG4QAIRKRNBRmw7E5utryRPb\nGTW4pTBrPDx9ZrzJ+JRD4W4rTMn9GiMOy9YzG1+wxrRRSFxjcHS2pP0NP8I2\nOMbRWNEqyV4VQnJsvY8l04sq/8pBjZmDOjOCbvWRnNS2CtIP3ignVgB5LOx0\nVAyd5DCQzQKZEdOJHKxBF8jH5dOIyrIjCjOr1Rzr8CJo5KEIzE+jWjbOPAGN\nFO22IbYD0bU0jzvnGgUONe+Mz97qlcrCFk04gWqmBs3KOpB2Za6D6t0dHd+3\nt9Qxl9JJmI3J/cCxr/DrIxM61cChRN07ROelNy92AzfcBnIlHdgiYWeaXMG4\n0YeLMLWiSsqsmAynzP7twmkjnPMubN+aigTy8ytwtIdb5SEdnxB73FSTKYVG\ncnEYc8xM6fvGOoYRr5ISsK+J4wooj5CzaGh+9mNUrdYpIVDGpWeBtA3AW2HZ\neZGlekzdqlRP9q6owOO8IxAwFgZWtel4Z12Iuls6e4rlIWcFQnBLXJkEsg8k\nCdA0Ta9AD0NLhx/EZcA/JPclFcf6S0aRuNKI9TUzo+W79XmoUFUgEKXRZP5c\nUbTukUUqgqm5E15sCV0mnb7mbh5iUbLVgAx0BbRgoyNQcROJudr00o+AQ98M\n21TWJNJEJ5Wb6oYYq6CJD3loydvPVhMIeTM6ARy8/1amxfAa7mgfVr1/WQWY\nJNLY\r\n=qNJF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGYTduaVruJ6ricyXxBQ/U83B9JelHFKZ9EZ+oYhuHyLAiBryERkt2E3AZ4kkXTJ99YIMCcyqmz+0ts+7wDT2otkXA=="}]},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.17.2_1617416039178_0.5200026568341258"},"_hasShrinkwrap":false},"0.18.0-alpha.0":{"name":"@creditkarma/thrift-client","version":"0.18.0-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.17.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.0-alpha.0","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"1a3cd5ca4efeb0919049b47c3b5aca4747ffa0b9","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.0-alpha.0","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-z5m/YYn5m7B/ZLRUG2Tua3ysQ7DQg8VkczAJosikOQdheYfax9brwGja1v9mdv/l+ELJk5elWv1EQzPZcCQCVg==","shasum":"0e83ae0f5db8264b0e82081cb6e1ff6e69d62a14","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.0-alpha.0.tgz","fileCount":33,"unpackedSize":73116,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDYe3Td+cGliTukG6qq3fcAh7SE13LwSofO5XpT73CLtAIhALjg3WyDHZPvV0nsQq8GUTh3t6R5S0MnaTzCZtpPsUVh"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJifobrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqPOhAAgw5HuEjxzEHcQMch8kPDQMeqRWRkcoI8AQA52/FfBInip7cS\r\n55tJlKl8BaokmXOct6q1pGPco8/+gWgHoMK56/lJi6HmGD6yOy//npeeT/7o\r\nDedKkTE+OSWGCqmfM71xhplwEP8YN/3mLV8NtT9sXbFfw/aPIz0HJAPnc22O\r\nYGqgF8hgsuE/c6N6wT46u5DWJlZ2Wf7OrmApBKXXqk5CRYUQCk9n/7AlSpnw\r\nxFwYwZEI9LMDHHQDWS21AdXnSdwZnyzedAhm62CurooADYDZAMtFhRPLDch/\r\n9Ckc3nEotNdb+eB4PEaduiR8JNm0D0lZ/V+LNTzgWr56X9XMCO2o/M5TXJmI\r\nziOu3Y+xXTcqoANFcD8SqodcndTiA2W7VWRfQHHPySHYH7Qx99HsjNC+2OpZ\r\naDKG4t5weTWB8M169wt/qVEGw9EFC4NlljLmjDfjEORP5VjmV+qZyal388Yy\r\nNqISQz7Z9ntsf9FyZcfuUtxsePathyF2wjTfjG+dpoIKAXjjE+x57q+Uv355\r\nFjKpsnyIdFhwIGz1WsZvtauaC5Wmo3n7Qp4d9Q/aV3Ed7KdVR03Bmsd643+f\r\nfhcFwcIjHEVmwnQBVGipzb4bwpB9sHQ64AFUsnYsT8zqOn5NyOgHX2cwQPSI\r\n5xUgmQbVcGTP6ll6JNaf4WDbj6EpMmRmWqM=\r\n=sMqf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.0-alpha.0_1652459243749_0.18258804829921704"},"_hasShrinkwrap":false},"0.18.0-alpha.1":{"name":"@creditkarma/thrift-client","version":"0.18.0-alpha.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":">=0.17.x"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.0-alpha.1","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"936f7fc6ccf32ea9155eb008004359ac23343b6b","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.0-alpha.1","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-0HUf7B3DVi5nPa5kVyjMTgYx14vXQkeWoZWp7Wbe0v0Yr1nW6TdPRKY1fS0vKLgyg2e/cWePi8ZuHE8nAAJp4w==","shasum":"0ed554c3cb204415288199e28b8e1c74b6df6ec3","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.0-alpha.1.tgz","fileCount":33,"unpackedSize":73118,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDXpc0nDJmtMOrcD2AG+0GzX8f6i0FYapPB5Dyjw9FE/gIhAOZeryRFa5X13Oxs89YH6GJ3+EmdNGoRF0n3O3k8AlQs"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJignQWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoCmw//RLxOgf5S7BZne6tpVTRlbfhYYiYcIyWNG2dicjSwA0yAjN7J\r\n1NaAmBF0tThuVq7TEQxD6Byge7d6aIudXJYxpp0LRc7nX4VjhouryV3BYAkT\r\nwg42p8jEy8nqL4mwyNkIWG6SetSXU532mA2HLtRznq+MdZrdh1BATLO1C2/o\r\n5iOedAGrTLvg/iITBzGD0L9ygfhAMM0SnCdSxucVpV0d5GBctWvRloex22IX\r\n4StCJ155OEdd1zGdwHmFrUalcLRfeio0F/ol8mla2i/SxRguzAKJuQjegE+M\r\nP7amStdmVT1XbhTOExshjejmv837d+xXwdgtEQpdzVpb80RPc8OQhh+sk3fe\r\nQUy0U8CTyWubqSY3+LQy7iSFUcNL9WgnouH/t7xf09uN8ln8hfb5+bD8VQYy\r\nLdYtf8wZDLVyja0Y3+O7R9X+C0Ucx/DthEQwhvFEq6claRLp1tA94RVd7UZ7\r\n06qoqaRTUsw6ga/cIrWYsVdOAohPS+YfsmrsEbZk0tsv454NYoZdnuL+Z2i0\r\nrlppuIUwGjzMtTgY/lifCofcDot1J4j+iStdzHAPdAQJbOL1pNZ7LiG5lH/Z\r\n2ISRI66N2mGZzDdd25eYDISK2EAD8zRBQY1SuEgnkcJimhNfZvprHTOY9Wqq\r\nuK6XRiUlfNr3DdRY7TnJL3Zpg8cG2aSMEOo=\r\n=Lriv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.0-alpha.1_1652716566384_0.7044376467446558"},"_hasShrinkwrap":false},"0.18.0-alpha.5":{"name":"@creditkarma/thrift-client","version":"0.18.0-alpha.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.0-alpha.5"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.0-alpha.5","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"1eaa8fc1016d0ade8d38ac610eb497837a8be680","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.0-alpha.5","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-WTpNZH9ly0J7y0KFDjfoLnbxovvVUoIwA4L9dRAvOqMiGyWSjBgQ5sM96PYZkAuJfUBHzd5eSk84Gn3hrkQPmg==","shasum":"d70c4c60343ed776806314548c8dc40cada70c4d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.0-alpha.5.tgz","fileCount":3,"unpackedSize":28624,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD0iR1uah8CODsbrLzKrFLBKFW9XwEHRcxVTV9o6HCJnAIgWMp3m8kEBQkPI2FKXfwSHtuS2ZwyVM/eHjVoZ158A9k="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJigrUFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrpOhAAgpNnEJBkkQ2eJMrPZgdcLBCYhfLRMpni+d4opkEA9cHp8lFA\r\nkWRRxB8a4EBxXxdWIaSkgTA8PtABNJ9rYF+0Mtf+kE8r89hZtBabfj5ND1ZF\r\nVBC2n6D2F90z4JLCATJQMqLQg/uerPkSkgkqDFAzc3wo2wcg+rsBsEnx1DcN\r\nTeWPbUNfKz89q7fVrowoa3khg+TA13e0gKepcu4x4+ojnvS9tKRk1ICl2Htj\r\n6ipXB+JH2dv5AQV8Y4MzD2lKyzVwDVwscUlqn+FbQU0G4Bih9s8xagyKgGBU\r\nH591tKeuxVpno+PsqhO6utF7za6NzXPY0eSlcfKJsjPO27LJEi8G2lUGe7Wo\r\nWhkOhEoHy59QwFwRZDG18zAFG/E4c9jHFX00UHcdBKDQ2c6dZfOpKnKXpOj8\r\nFUl6hti/zevOV09csqJgWX3bH4+fwshTHtWj/4GVDopyd7cif1BIZ5pcA0b8\r\nFZIFCwCbgiEKkl8pEFwkIXZP7lA52VfC5H5yip0GJsOZeXaT+RjIqvG9u5we\r\ncPpi2M5uQn8j8h3Pq5pI/hWKPWmZ/K8tYOKchnysgHm68pQz8j8O1yMW3ALR\r\noRrxNoh0hoBOQJ8uDPFMMLThHMt/CAc6oTihL/n1dnnKJ6KA8LuoX1+X85g+\r\nNDtPEJiAJkN7TYFSz28n7xcnAsHcd1ccTmQ=\r\n=TIgt\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.0-alpha.5_1652733189414_0.013858368738867366"},"_hasShrinkwrap":false},"0.18.1-alpha.0":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.0-alpha.5"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.0","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"806fde6a64d9304a38d5e90ee61c93c06432aae1","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.0","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-RPHaNwfjYnyzFyHKDo/wP3k5qCDIgSCARKHOE5soFnZKUDe0JhP5Blar6lt0zZuY5wpmnMQrwfFjbe2L5DR6iA==","shasum":"9a00b0baa093bacc45e3ca98f71f5eb43363053a","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.0.tgz","fileCount":3,"unpackedSize":28624,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXb5mfCcS35cU2qkuwSEF72owGCMAoMq1xWspsZnAwkgIgb+oDZoni99dTH+5C9vvuVPi26UgwwvXictHr1PXkVLw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihC+iACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpVzQ//U3yP1Smh0rrRQGWsER0KEu492B86yIEy4udy/5bqBXZ8Wgea\r\nvi/5f7/m/wTNLQepN4JOvu3PNRKglbZ06lnH8NUQjnF5Zh85UBUo2Q5e+3Q3\r\nzi3MkpA/LPM/X0HUQdBL4kgC45OyurjF8gtmE8vGB6ducDcY9joWWnkeOiW+\r\nJtxqbGRDkXWmr3G8aHl/i/EQGkzPUpbjYx3kB+ucbau4Pu/GpshaEHWf0Pl6\r\naH/VrLGP3g7kdjasN6v71p4akhUpkB9pziqgmLDFPAmbGcj/A8FO85IixZe0\r\nQd5zSzngObUmI61C/jItnwqYAlCohu/xYvgwIXatBD+EDDMpdubN06Ybb69m\r\noZu7Jjp12YJ9y7D/whWSMnH2GrcZmDY8K8K7TsX4apVXNAQ95lPdvROkDXNr\r\nKxWcuinKk/QHpnnWwKeaeanDW3gYGnCE47azG9GxN2ZVzo8GEJnxsEYhcIPG\r\nOD43kxPjo8n15iiP4YvhSF50QcURFK2lyP+AzRZa/x543NxNihMdrARibTpG\r\nce/1RVulZ+pl31i0kUSV0r/BBapV68DcuDzEUv3y6I86MeA2OKvWOVQ3DOrF\r\nXKRsupoMZHMKj5LmDL0ysULYl9xzs5HWpwkFyNxghc7FN5p30J+dezooLokB\r\nixNuSsP5VtZcZVMUhTKbOA6M148PJGk+Q0o=\r\n=1PIo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.0_1652830113899_0.6788756048276929"},"_hasShrinkwrap":false},"0.18.1-alpha.3":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.2"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.3","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"cca6d2eace0ca1cf84dc2f80a11a01fc99f0f625","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.3","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-X6ZIw+w4Uy8Xdu4f+4N1p0B3Oi6CmfV6REpGoRhtFrY4+JPOmxzsKlwuyw8SQ6zrRMfZ6JEOsug0WNXJwBnOsg==","shasum":"7c5d6285875935cb8041728c2abc63b555386b0a","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.3.tgz","fileCount":33,"unpackedSize":73124,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1Y9hS4KCaLM3EKyMfjD0o4Pg8qEB+Gq0pkpYGDHKStwIgR+24g+qRtIhTqpXEZZt2JDCsnAPofOjiHjB/fDP0QkM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihDLYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrQPhAAgcqdAyh+B8tI1/iSNM8QN2++8T7e+H5Sl60gY1V54k+oUOsB\r\nxbFK4kxTupnT4PdOVjsUwOMJ8vDLx8cQyo0QNYOBFqkXlEB74DvxDT5jygqK\r\nXreYq75a9aUzJX6UYf83fS09vxPyQfKXpHHeSNWJNbHZ7eKcG2Rw6WSSVHkG\r\nx84hQ/Um0l3Eg7p9pOWIN/7GqtSIGb4k3z51tsaSQgcZgo05GzvRPY+trtRJ\r\nKnA0bhT6FAEeQah8DbkUfxrMZ0ncBYwUPUbqxZjwpeKR2PoZM5N+2iacoizu\r\nXMKWRlbjxk74BxYMEEkCqgQvPm12Fh1TYNJbFefNyx1XSnadIFVMtdG9zJ/J\r\neG3OhvFYp6KfkJVgx8YfgF37uJ0hhWWO4YEqALQbYeiYq8Hs+n9WuNxyiXVL\r\nRJhVIPJZw8eGiDWTxdQfEeyIgSL6gJuwQmWY/4bNNTBLaNYmwzst4Ae3yGCM\r\nowFbOyaw1c6XFI5Tmf9kf9HBmGjqBOoDm1tQaL9NP25aZxi3tGjLTvHqquHL\r\nAhZyRI9M35ovTaHzwBd4oaD1XCXHDdxVPQWSdbXS4v4piEuXnJEN+Wp3L5il\r\nyd4qD70z148zaigIRqP0RwRfG9JgCaOaTqHYyTr4PVWBr/ElgwXeBi16NJUJ\r\ndxQKczjIRNUNumQWvXh3hRvhyKnIvYRWf6c=\r\n=yAY+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.3_1652830936534_0.1286283897149747"},"_hasShrinkwrap":false},"0.18.1-alpha.4":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.4"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.4","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"3f291032836e710508d829df5a0e2dd04a37b375","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.4","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-04aluJO6Dsrg6e7kXv3t7TEABy4jebWkRJGV7lupm+5Z0tJbEJunZ/nc5p8CPnwRsM3wkPG2hDGMH+wA4Ythxw==","shasum":"0a117e34298dd33f4123cdd923d2f73f4f8c099f","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.4.tgz","fileCount":33,"unpackedSize":73124,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHFNNW4jb7qkCKVrDvgcSMy5nuUNP8xluhFuLgtnuvWtAiEAp68DAkaC20Wt+fohfzHGYIVQI1EyL2v6MVQ70bSlnR0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihDSbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp5Fw/9F5lk8wTejX8oboSy4hE9waJCe4XIeSgNW2eN9Z5vWTFILUy+\r\nrGCaO9lNUD41j0UGTrGvrRqs7yff+ciYCpbnaY/C4qPaoIo2lbe92NH1nK0r\r\nfD5EXdtC6X4E7I1uVt6NJZ3TmN5KvKiv3s6BH8aC7j9iRV17KjC9PIRU1tkR\r\ncz4PUPSu1mLzgEMtrdADUaGjQPqvI+3b9c+cJUtfjzBd5/Cllgt0T9RviFsu\r\nClpZfmaDXcIJ+QzRcJVHmhKTzLgaMu+JviGtGhKwGEFoIGGky5AeRwzGK7/l\r\nx/ymdnxOFrmgAHimjJRIKqoRo1q/8OP1Gsd4RzYAWNSMN5+CeLrI9YfexgL1\r\nR6v450j4ZHzFLoA0ttrVxTmeo7bBaM62VpC9lY6sQa63mtA/7f3r+J315mDH\r\n1iz1f84fg7g9cCtCKfxbW/MFUEclLNBhZXBZxvB4hwgnX1rkej+p46HI97eA\r\n5BRziq+W0Yi2nBnmwS4VD6V5YUXfonS3NSPB5bjDeU9pW8kBcl48f0ld9NWu\r\nXxqUirLwCgJJIuzBZvSrQyoch0Q4z4TWO6gXwEb9/dHeUuffuWvNRSjydaNY\r\nUnEr5DDHkHisUsDh954TMSAXb0gseIDEQVpsFZQ7QNodrAN6R82johCJf48+\r\nzPTRHxWeLAlLAMXE9CakJgJcOI8VKZqBBLA=\r\n=DCnm\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.4_1652831387434_0.8584706127720461"},"_hasShrinkwrap":false},"0.18.1-alpha.5":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.5","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.5"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.5","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { CoreOptions } from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<CoreOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<CoreOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (CoreOptions). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<CoreOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<CoreOptions>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { CoreOptions } from 'request'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<CoreOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // CoreOptions to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `CoreOptions` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: CoreOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `CoreOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<CoreOptions>, next: NextFunction<CoreOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"438ee54d27c7234d0a7f5b4ac13bfccbf4b881c1","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.5","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-OcZY0G7GmIZ2ASYxo8hGBjfFB3m2kdxI401ykwbke0uSORj94cPqWz5asn1o0ytnlPVB4swmI2u1Eb6PZkGxog==","shasum":"ed6154f510fcb212867238057815d1d518c8e06d","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.5.tgz","fileCount":33,"unpackedSize":73124,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWhGXZ6doemum2YGvg3o4+rcIZmOZF6l0uTzOyA1lYwgIgYynYCpp7P3LJQ3yZoYkJ352y9kMTuCoSIEnkNJj2m08="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJimU21ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpi4A/9F7F4iWDs7sVI1SYQvW0Q5L5mqR2l7zXNgiCpvAu+AEUObpbl\r\nl/nGBD/E+KoRagVn6e61ehPxafCxT8djQAfxRB76tgUs/IfXpe7cVTisT3/C\r\nqh9lP7XEl7cxEQf1ypdA4rR/JMw/NGe05iPC5jJ0zew6Vb24IzJ+OJ67mZdJ\r\nC+3d4EGzNwczZ9D0I/B4nc1DKDYQwh752lj5cWIq9JumbYJPY1l2thQetY7L\r\n7XRYR3wjEYdW7dx6DiU9dAi4P1QPDAtgrGrlgroF2voSEVMzdO3B55kKCl+G\r\nfSyNkAzJecozL4Ip2RXHd/8UQOUkdcojKEYsuRt8pbBZOwsZkro0ZMDjJ28T\r\nsHowNklndqxXYocaDP1e/GVBRhfxzLqktABZFuJbeOOBts6FzKoPIGyvPz0C\r\nq0VU2XLrX22RcYIFACf/5hh/2sGDWT9akapP2b4+yzPw1rI+H+5s4JDOpc7B\r\n62lMXqYFxJ0IZxnPfvVmUgr1KIFF1cG6kuXUrdxJEuWTSAbuv7Ddo2QkR6v+\r\nirhbGXKzE2X1260ca0Rj+irHv8lhyojDmwpSCxUMT9NUMjMyQ6oB+TpfSmui\r\nEJwvcBYL1uIKhykeQ3d4BB2Btt+glvWvwFHNAqk1HWKGe9mAVftM54zv1C5L\r\nwG5Tv8YVVbUAjmtlmAmtuiGAzF59Yz1zpOk=\r\n=x3tw\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.5_1654214068943_0.23533842972986574"},"_hasShrinkwrap":false},"0.18.1-alpha.6":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.6","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.5"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.6","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { OptionsOfBufferResponseBody } from 'got'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // OptionsOfBufferResponseBody to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { OptionsOfBufferResponseBody } from 'got'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (OptionsOfBufferResponseBody). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<OptionsOfBufferResponseBody>>`. This type parameter refers to the type of the context, here the `ThriftContext<OptionsOfBufferResponseBody>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { OptionsOfBufferResponseBody } from 'got'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<OptionsOfBufferResponseBody>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // OptionsOfBufferResponseBody to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: OptionsOfBufferResponseBody = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `OptionsOfBufferResponseBody` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: OptionsOfBufferResponseBody = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `OptionsOfBufferResponseBody`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"9c77845a0b15395f2c219d7844ce2963eb8df773","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.6","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-Bf+t7MTRHbszNLc5lJn9JOp1IXV3iAWN+O+KJx6oPYkTSKTMDWVwOqzFWaDnSTwnI3Kg3VODIAO6DkFVNa2eWw==","shasum":"091dc6ae5b1f96ac83598f17724c28901b77a4da","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.6.tgz","fileCount":33,"unpackedSize":77400,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBgFdkA3RPsazDUN9WBqvH3coOX7LMNMSabb6EGtYjEaAiBY0WDEf7wj9txHkchhUfEXSuiNsj6spAUygtJNf0qaVw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJioOhKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq9Ug//cLDkpDSkKaeZeRDDFjg8GiN1rtLEcaLd3g+4ChpIeHpA5q80\r\ncOdEnaw0tnCxIOLV5ZIMPq+S28eU3hYO81g3TTJ2yisbOiMIWB+il/qIenkI\r\npwKhRodgAyU0mRjMiHTNZx8NA7cjEQCl6EycvmdQogi2uAI2lx0sPru41xh/\r\njlOyAorN4ivK6w8tFrzqxkvlZ8zhglbNIzvey935DpBUJEj4klxi5pV/enRb\r\nBCFRlcXQABI+9S+Os9zlCylQtfPAWYVzzcDNXgEaPmdBKcavIOQH3XyY0ZQE\r\nM63cyZPcQkAm3HLNO301MFata26/5vXIgnMmRwf7iEQs9X4uY1cg7YbwRHE9\r\nGt78Egwe4fkjT7p4PdXTe3IH0OFosSboPNcqloSb80x3Ue4/McDtQflYJO4j\r\nSjbgzWoAZ30y1I10klP6VXw3NEIilsrrC4/CB3td1J+idDTBpdaUUwFYQRx4\r\n0Esse1pkXPSPlNDT8LE2GyvuoLDQJ0JnfBCh2wOS15iEC+VDPiPVq2aSLuAW\r\nlj0Q6AROld2h/dHGbYLcl2iKBJyknro+Vp2n+zb+JMOUyXW7AlTrQPHNHX1m\r\n/pR5e5E0ja84iNKehmNPgL7TEgQFMyGpJT8EhzGCUpUh6OLbxHm2S939rVyZ\r\nJsJa8CJmGE5+IE6DFPVkbEMnq3BJRZm5EkE=\r\n=ykcb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.6_1654712394540_0.4704512733622077"},"_hasShrinkwrap":false},"0.18.1-alpha.7":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.7","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.7"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.7","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { OptionsOfBufferResponseBody } from 'got'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // OptionsOfBufferResponseBody to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { OptionsOfBufferResponseBody } from 'got'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (OptionsOfBufferResponseBody). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<OptionsOfBufferResponseBody>>`. This type parameter refers to the type of the context, here the `ThriftContext<OptionsOfBufferResponseBody>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { OptionsOfBufferResponseBody } from 'got'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<OptionsOfBufferResponseBody>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // OptionsOfBufferResponseBody to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: OptionsOfBufferResponseBody = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `OptionsOfBufferResponseBody` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: OptionsOfBufferResponseBody = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `OptionsOfBufferResponseBody`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"833898a2c75c4b9088a533ebf8008d392eef7b26","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.7","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-DNPe8/TdmqyLdCMXr0jSkLDH7TMgGhdpwA/VSMhdmvYtWgEkTmElZNfyjh/XaW75vd5QXOW932oUL/tdPG72Dg==","shasum":"74e649f5257b4463c80f2b22929bd531ad3d7a3f","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.7.tgz","fileCount":33,"unpackedSize":77400,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDyZCNLj6IA08FRpi1ByxzVtlzStXb5/XxnzQYbe6EthAiABXebGvLD6LA4BvGlnZtKO2IZiB2mL8ypcUEVIuXgWQw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJioO7lACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpqGRAAhng91n9pwOLwFAzxs2YIdSFeHV4jEDJsNLqDocz+yiN22CSy\r\nB6dgdQpssI3nxItPX4KyCqArbjBdAIbFWmXWZUVsmoWsy1UvsCK6O3meswJ2\r\n7+dS562Lh3Mt1gM2oj4KDvUF0Vyb19D2L14cDCYlR1twHj5gZ0aMa/wnFk89\r\nIQvwFSUGaOVXJr/5UuSHGsIg+HT2iiMDW/g8iNkw0T5E7tf91tSkv8ZolWR3\r\n7S1pV3h40tDIg52IyGMftahbMMmgDJQpB9S+1L3KvCOHiNw+N+4UR6k7B/kO\r\nuxKMzRBdxJJy9qA5bGHFNqPgDSQS9OOcoru4zE6g0hdkKVklNcuCvFe+mgh/\r\nae1UztaAwT+Ec1OI71eOnVLPH2tPuPC81RcQp+FK2s5n5WILFm/xv3pVygei\r\n2pW+Mt5YkUuco+tNdmcRcgrzhwLLiO38kbOnDv44GNfpH3sd6dbeOu/BHcaO\r\n/k7iF3A+3uWzfiJ4BH7xt0VpynjHgb4fiaC17/KtUUmy/RHb2ZhRvog8YNtF\r\nLW7UaDu2QX7YetVS5bY02L5FQe34KjS1q4AhrFo4h2NFUXLAbH1tG0Clq+EV\r\n2/QL7VsyM+RXB9g3+hAUNmJSY0OFfk4uKU8hXeHSLRMHsqpo5pzJYUV9VCBV\r\nZ8wdMnICGA4eoS/5yCS8BV56O6FgXdlSmwY=\r\n=wctK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.7_1654714085705_0.007760294514449928"},"_hasShrinkwrap":false},"0.18.1-alpha.8":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.8","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.8"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.8","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [Request library](https://github.com/request/request) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { OptionsOfBufferResponseBody } from 'got'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // OptionsOfBufferResponseBody to pass to Request\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [Request library](https://github.com/request/request#requestoptions-callback). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\nimport { OptionsOfBufferResponseBody } from 'got'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<OptionsOfBufferResponseBody> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for Request library (OptionsOfBufferResponseBody). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<OptionsOfBufferResponseBody>>`. This type parameter refers to the type of the context, here the `ThriftContext<OptionsOfBufferResponseBody>` which extends the options interface from the Request library.\n\n```typescript\nimport {\n    createHttpClient\n} from '@creditkarma/thrift-client'\n\nimport { OptionsOfBufferResponseBody } from 'got'\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<OptionsOfBufferResponseBody>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // OptionsOfBufferResponseBody to pass to Request\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: OptionsOfBufferResponseBody = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `OptionsOfBufferResponseBody` for the underlying request library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: OptionsOfBufferResponseBody = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `OptionsOfBufferResponseBody`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<OptionsOfBufferResponseBody>, next: NextFunction<OptionsOfBufferResponseBody>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"608135313f757a77824ce29de90264d9388acab3","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.8","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-y01uvZmPk0moh+mUwBPGNssz9oSHLu0+N0Zev0Bir9m2OOGfvckLGzU+lXLaJHvm0ZTe9CWanh+FFmJPW+lHsw==","shasum":"5970afe94bb5d03f9cf8320db3b128661063dc63","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.8.tgz","fileCount":33,"unpackedSize":77400,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBBPep9LqdHu6pf838r1rLlX5Eyt1+xGiDp9XrTp0ZA1AiEA2XwhdNOMxA6mJadEgJHsqmUEBc5ayHCiqwFs9RVRNQI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJioQamACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrYeQ/7BUHlHBCrFg2NhAllVZnCDlA8jbaTCBjMfVA7k1+QNP+e4TCv\r\nzvAK5zlSVC4r8iSDvd5PwTFSzu7X6E9sUfkOxd4uQXHb6vuHjfhk5PZNm6zd\r\nkoja4VnytfnSrkvOjGV3GvOADqpN1cuD1PTYbIsxE9B7QAqMxWMB+ErPxhmG\r\nVtQDVC4HF+q42g1dZTAdJfa5tgD5cjcwXZmqOM87wGqba67GJmWFeVG+5aGs\r\nKYvHqEmwo7aGT09Qs6MIx7haRDyjdD8bq7JDngZfvtzS2zz1rPR6/vEkCko2\r\nbnaA8vrkrr8RdaUwuRmBeVjbgcV+xd62+O9+0tk3GWV8nYFcp5aA7F0cNpcW\r\nNysHFnW8a67feISAiArkAubz4LKknTGbyNVTZaSToyKUgjcjjrpnfwtd9QO2\r\nMbv5Q4pdsBp2nkf0MbXO7ffCMZcaZs9wrWDPjgbFvQkRrG6UHz+R9n6XxSQg\r\nBGWJ3lwahgwqlreCkHGzjeV1MKDG/IzpAGW4QGnmfTatPHD5XXbK7Pe7b8h+\r\nQW+2E3xwgarIbQ1xqq4FP7Y3SMnst4amm6vKue7TdaSpRSWu1vc/ePGv3o13\r\n51TLpQJbx90zIHvl2Zngw4+nTrlQGtSACaAhlI68+5MOwbmQ9s7uEmmsj80q\r\nvq+YkpCzC357odSUjVJ1gSsaUKNhi1kCprw=\r\n=IoXX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.8_1654720165828_0.6696657735229141"},"_hasShrinkwrap":false},"0.18.1-alpha.9":{"name":"@creditkarma/thrift-client","version":"0.18.1-alpha.9","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"0.18.1-alpha.8"},"devDependencies":{"@creditkarma/thrift-server-core":"^0.18.1-alpha.9","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [got library](https://github.com/sindresorhus/got) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient,\n    RequestOptions,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<RequestOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // RequestOptions to pass to got\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [got library](https://github.com/sindresorhus/got). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n    RequestOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<RequestOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<RequestOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<RequestOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for got library (OptionsOfBufferResponseBody). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<RequestOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<RequestOptions>` which extends the options interface from the got library.\n\n```typescript\nimport {\n    createHttpClient,\n    RequestOptions\n} from '@creditkarma/thrift-client'\n\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<RequestOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // RequestOptions to pass to got\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: RequestOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `RequestOptions` for the underlying got library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: RequestOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `RequestOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"b0c9fec3b7735e268f02163e7d1dec86ddf78acd","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@0.18.1-alpha.9","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-JWlcP9iAGr8KonYfdgLXxJR2cOLQpS5m1dGC7iS7THiR7vLqKzOTpF1zgKFGiND9oO8OwN7fbRI1DTeG5IrE0A==","shasum":"6ef6f8289f1f0ab8f4389fe4d9897e94f95a7980","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-0.18.1-alpha.9.tgz","fileCount":33,"unpackedSize":76623,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC37aeIu4e+yzY5rMXdjXuUcg1Xmt3miOUdY5C250rMjQIhAMMScxx1HQsPROyHf/Uo8K2bBuuXT0JYH5wFlxTSAqPK"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJip3naACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHHw//bSOEQ6+J+I38RprElxcTCjVewxdH+JCDhg9WdI+/T7/Z2Axp\r\nl3UR2EtA+GL5xudDUBZvrfHoZx9gYuHBZb9Lrk4b9tnwxjYriLVjRMtVz82r\r\nklQLX1qJEZ1dS4dYeduhGv6kfqhg+AupBxdAZSlZkcSd9X0zdtDAXMeQbXRh\r\nNCE0UsQ+oVxRDY/GUCOyzXxJ9eXiXyDRQv32HO53OwK5n5SKlSP5tiSbfjl6\r\nB3pIRoWsqYmpeuxCRiZmL/e86uE/4NbZMadHZhCO40OzmvFtvraQNHu4j1G0\r\ny8zJwZjOC2dKDMmW0CGIipATJ51cZE3QS2lWxScPCiXt2tHe4PFsb1gulx0f\r\n1UGUcdfsk4ckQ6pYuNlUmKOha8ad6XWZLMfYHimXe/fwHQmQasprB37GxZYB\r\nZ3zq0CzBt/sur/Ryyas1ye8iSWKIIU2fCa35oxpptVXCedhJ6eTP1lYfwG8y\r\nXfEito6fwi/tHY2Bth+KynKKgeE2+62sbQEIm6mxzQrUihCQ9b2NbCiyJjAd\r\nc1S2uj+6/L0RFZlQJZSn+BUBvBaatY21B0thqiq1Q66p8TsjN0ybO0wCIKAO\r\n1MvxleuLK91N2LksL2Qkn3btsYkXLWmLO7X0kjTrNAn8kbqXjGAwunstnW97\r\not2r74LnzNPrlhRFXE3nUMsqcr3GOQ3DEr4=\r\n=vovX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_0.18.1-alpha.9_1655142874112_0.17810481634476916"},"_hasShrinkwrap":false},"1.0.3":{"name":"@creditkarma/thrift-client","version":"1.0.3","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"^1.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^1.0.3","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"gitHead":"d55fafa26ad389b578428abb3cd6bf1463269b10","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@1.0.3","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-LowKEKkwZhk474f+eu2/dgqxIGwB5MHg2DDNz+Stl5nlhCckdhau3iDneKHow2ypnTDqHqM161q3WxExF0KLpg==","shasum":"a8623599f3a78a1113509f1cae86de64964eb300","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-1.0.3.tgz","fileCount":33,"unpackedSize":76597,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCNo5neXCM8m5NB6AiMouQh+868ZAUaEAb6ONwxULzeeAIhAKRvAHaChHQZvkWACzYL5CXJC1HrSD6zb0jtK8Y1S00R"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJitkZLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr6+w/+I/VA26HOoedROtX+rTkbOxyeep6kek8yiAo00Kaghpe7Ml12\r\n1jF2Dqc/fdEWORzxiInl93DqeE/pEQ6+PNSBEniQh/rKr9BMjgLfayLmEDOQ\r\nikOTW82RnQln9INXRqvjMMdanubfN8GyaR4vIiu0Otf+QG3WKggFo2yX7lyl\r\nsTxZ6mN6ccN2w3Gjc7OzHFy4W5Dcbo7W727RhjAQohEC6haGjfL9tPiGFB1M\r\nhvVEX9HFYPno4Q555iib8mPuvE5TmcDBvX8i1roWTYWNDEBS8DAfXCxCpPy/\r\nE1fY3SOikYvMViEk+33X9PSssD0c71fKlDR76LX7HE/gWdybJYWHEFFDIX+s\r\nghHMfd/Uncm195lOb/G9jeoBjxWI7lk97/2ZKplQAzAXeDdvPjhqPo6/1RpV\r\n2jRcFNpmXE5ySGeR9+LwOSnsxBMXgiD5nxbnpf+TlaS8ewFkxXnZZvhRiowU\r\n+8tX2oW8VTTsz6DdW7iRqJZuWhvMN3qb7cWzCVHwXWTB0OWylbhD87ceFdTa\r\nnynG+eYTGuPDs0TJ9t4E0hZmYdELUYZOXkX4bSmpD1bdHzekTw1QjcvQKbCD\r\ny7oStTy/A8WWh0Ily1Vmg+bluobTBOtlUlnqKiis836lj7z/bffK6xU5Shzs\r\n115J+DsLoGOp8cgDhyNyFScU9ZUWMLl0ltc=\r\n=y6gz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_1.0.3_1656112715693_0.3648516562294548"},"_hasShrinkwrap":false},"1.0.4":{"name":"@creditkarma/thrift-client","version":"1.0.4","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"^1.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^1.0.4","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"gitHead":"e3f1e620734155b7f7d3391a5e0c87a1a24744ed","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@1.0.4","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-CK2HarQKhzYXEKQeqYSEWdOQYcMz0o7HB7Q4c08prL0bb6EXOE0Qim5FsCvCwYkrkoEHLKSwuD795AJ48yuaNg==","shasum":"1b0dd1ceffefeff23df1b833b9c23e275cba6c88","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-1.0.4.tgz","fileCount":33,"unpackedSize":76597,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEk1pFdOh0M74FrNDeCJo7YxOoViCGGIXkni4goXq+umAiBCfKzVsEVtjRkyuSF7/OAtqb0f6TLiexxCbZZk/AGoxA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJitkgDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqGzA//SEBlmX/j8e9wLHFXZP+0Y46UIaW27IzCDV/qAo3QhGlA6mK9\r\nw/V1v7J+DT4XimnYy+mafasWS47nfEdOIUw+m9k3IhRI/8EIXuMKv/AB1IBb\r\ndViE4XhzsudPDTL+/rJ4s15m/VEXWQ8eCIiB5fNJizjzAoSbTNCHlM0+nlJ8\r\n+6FpWh+XlSxnxzt5fZgmdoQ3MUf03O5iSuxWWd3g3dEAoHF0Y8vGQtMPF9Ih\r\nqyswqu+QSgrmBCgG2iGOnRxA4fYESMYl2KtPFrA2sS6m6GJdVjLO7G5pXqiM\r\n1iJyWzZ2eQ0hQxUVCHH3kBjlamLBWcFmGzd0HJjZy5odMRqDxwA0s0pzOQND\r\nOeQC6qsFPAJhJ9v9zThzUERQlXREq8IqD+YDPqWTn3BkPE5cNLB3BMuBDske\r\nw2ecYb/+UGtDNOPKFPZEVlE7DcAWIHBIEFmfkdRl26oeO29vNVEoRtfc4Jr8\r\nW7HAaQuX2TaDOcITZPU7oKvL2/8mDS+WhSj56GfbfQBGOZPJ5aF5yWot/NoG\r\nSAsy5+H8WYOWtZnTY8HVKGjz4+IEE4XE8YjnJ7wyPanXi7qlhlkUlTpiI/UI\r\nf5CF698uSOhUW2kXQJAPaIU9hzSZ/LlxbIORwANdh9xqY3yhSURzVkXmhgFM\r\n3D6e1+5JOW7QnLUo3UFojeHQSy+DvP5vWPQ=\r\n=Tl3q\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_1.0.4_1656113155305_0.7993880455684812"},"_hasShrinkwrap":false},"1.0.6-alpha.0":{"name":"@creditkarma/thrift-client","version":"1.0.6-alpha.0","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"^1.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^1.0.6-alpha.0","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","@types/request":"^2.48.1","generic-pool":"^3.4.2","request":"^2.88.0"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [got library](https://github.com/sindresorhus/got) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient,\n    RequestOptions,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<RequestOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // RequestOptions to pass to got\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [got library](https://github.com/sindresorhus/got). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n    RequestOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<RequestOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<RequestOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<RequestOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for got library (OptionsOfBufferResponseBody). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<RequestOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<RequestOptions>` which extends the options interface from the got library.\n\n```typescript\nimport {\n    createHttpClient,\n    RequestOptions\n} from '@creditkarma/thrift-client'\n\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<RequestOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // RequestOptions to pass to got\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: RequestOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `RequestOptions` for the underlying got library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: RequestOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `RequestOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"1e1eb36bbe546c9325be1a5174d7290ff142c328","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@1.0.6-alpha.0","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-n+o6f3XUqdmIJZIqntJEvY3jRWcslGV38evjdnhBP/KSm+k8VRIiFntsLQ6aGzzfpScFft6Zc4PO1WwRp7KzyA==","shasum":"7ac5d99ef9494e3d20d5d081a6e0e275a52a7a49","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-1.0.6-alpha.0.tgz","fileCount":33,"unpackedSize":73046,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxSral202E3HDhqkRzfZ2WFLqUyp43ACurJ0VX92VGXAIgTuWaCp/yZUfbi3AGLg1xm2nMqcd0ziapoDo7dhU+khY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkCP56ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoSdA/+IThvINjUWrcOkIAo4FcTUbeXsKs+DGo12F859BKlzMYj7xLH\r\nKMETIv3swhQMfe+UvcH1QggTEdFizhqv/9n3QFK6XwJ6GlNGzwTG15KYO27F\r\nwJ69njJkrf1Mnbb1xbWgkr2KM2nwxDrnOQwwzEsx4+jOg7TA+3uEWimgDjpc\r\n/TEtp06HoxPnc3mTvyU+bPr7/Dby7odcv/wC0HH4GNN++RxWuYyTZWCpJpKN\r\nRk4Bv7WgxIk9oOAr4aMYPJHEcaNuPoh6og4ezsr8czfYoZiceFB/0His4d1B\r\nS4byyypPzz3fsxo/Ke0okXdoY0Y8v7FmEb8nK80rg6LjdR1jX4Ig9AfdgbNw\r\nYRPC93Kc1V7SuqHIvjZndCLMJZ70LK0n/leBLu16unKIwMnv2X6/yHy1raqV\r\nsl3gp5MMAZNkCVWvKojO/Ug12cnrmUClOAAC+YKrNV4xPXKtK/ArDlUu/mgH\r\nsfsR/45o8K+M37WSJCc1Z/KxVjiueY0KNJ6/wZ7eudFVlIcPfadvbF1L1YJi\r\ng5LRDpAANzoCdjTDflfGqe1t1+FeXUgm1thY2CxApDwm33NnfeCQakfrCwRE\r\nHOVIHpIPxMWJj8amKmVjwvIPg70EeHI+B4TctpT+IVv47oBOSZc7A369lEht\r\nrNaWbklCL7kTTOxCQIH6KL2+Tkiu5HYcHuo=\r\n=ZshK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_1.0.6-alpha.0_1678311034790_0.34367405179679555"},"_hasShrinkwrap":false},"1.1.0-alpha.1":{"name":"@creditkarma/thrift-client","version":"1.1.0-alpha.1","description":"Thrift client library for NodeJS written in TypeScript.","main":"dist/main/index.js","types":"dist/main/index.d.ts","directories":{"example":"example"},"keywords":["thrift","typescript","rpc","microservices","http client","framework"],"scripts":{"clean":"rimraf ./dist","lint":"tslint --fix './src/**/*.ts'","format":"prettier --write 'src/**/*.ts'","prebuild":"npm run clean && npm run lint && npm run format","build":"tsc","test":"npm run test:only","test:only":"echo 'No tests for thrift-client'; exit 0;"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"peerDependencies":{"@creditkarma/thrift-server-core":"^1.0.0"},"devDependencies":{"@creditkarma/thrift-server-core":"^1.1.0-alpha.1","@types/node":"^16.11.0","prettier":"^1.18.2","rimraf":"^2.6.2","tslint":"^5.11.0","tslint-config-prettier":"^1.15.0","tslint-plugin-prettier":"^2.0.0","typescript":"4.6.x"},"dependencies":{"@types/generic-pool":"^3.1.4","generic-pool":"^3.4.2","got":"^11.8.3"},"publishConfig":{"access":"public"},"readme":"# Thrift Client\n\nThrift client library for NodeJS written in TypeScript.\n\nSupports communicating with Thrift services over HTTP or TCP.\n\n## Usage\n\nWe're going to go through this step-by-step.\n\n* Install dependencies\n* Define our service\n* Run codegen on our Thrift IDL\n* Create a client\n* Make service calls with our client\n\n### Install\n\nAll Thrift Server libraries define inter-dependencies as peer dependencies to avoid type collisions.\n\n```sh\n$ npm install --save-dev @creditkarma/thrift-typescript\n$ npm install --save @creditkarma/thrift-server-core\n$ npm install --save @creditkarma/thrift-client\n$ npm install --save request\n$ npm install --save @types/request\n```\n\n### Example Service\n\n```c\nservice Calculator {\n  i32 add(1: i32 left, 2: i32 right)\n  i32 subtract(1: i32 left, 2: i32 right)\n}\n```\n\n### Codegen\n\nRequires @creditkarma/thrift-typescript >= v3.0.0\n\nAdd a script to your package.json to codegen. The 'target' option is important to make thrift-typescript generate for this library instead of the Apache libraries.\n\n```json\n\"scripts\": {\n  \"codegen\": \"thrift-typescript --target thrift-server --sourceDir thrift --outDir codegen\"\n}\n```\n\nThen you can run codegen:\n\n```sh\n$ npm run codegen\n```\n\n### Creating an HTTP Client\n\nThere are two ways to create HTTP clients with the public API.\n\n* Use the `createHttpClient` factory function.\n* Manually create your own `HttpConnection` object\n\n#### `createHttpClient`\n\nUsing the `createHttpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying HTTP connection.\n\nWhen creating a client using this method Thrift Client uses the [got library](https://github.com/sindresorhus/got) for making HTTP requests.\n\n```typescript\nimport {\n    createHttpClient,\n    RequestOptions,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<RequestOptions> = createHttpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // RequestOptions to pass to got\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* path (optional): The path on which the Thrift service is listening. Defaults to '/thrift'.\n* https (optional): Boolean value indicating whether to use https. Defaults to false.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* requestOptions (optional): Options to pass to the underlying [got library](https://github.com/sindresorhus/got). Defaults to {}.\n* register (optional): A list of filters to apply to your client. More on this later.\n* requestImpl (optional): Provide a request implementation. Defaults to 'request' module.\n\nCurrently `@creditkarma/thrift-server-core\"` only supports buffered transport and binary or compact protocols.\n\n```typescript\ntype TransportType = 'buffered'\n```\n\nThe possible protocol types are:\n\n```typescript\ntype ProtocolType = 'binary' | 'compact'\n```\n\n#### Manual Creation\n\nManually creating your Thrift client allows you to choose the use of another HTTP client library or to reuse a previously created instance of Request.\n\n```typescript\nimport {\n    RequestInstance,\n    HttpConnection,\n    IHttpConnectionOptions,\n    RequestOptions,\n} from '@creditkarma/thrift-client'\nimport * as request from 'request'\n\nimport { Calculator } from './codegen/calculator'\n\nconst clientConfig: IHttpConnectionOptions = {\n    hostName: 'localhost',\n    port: 3000,\n    path: '/',\n    transport: 'buffered',\n    protocol: 'binary',\n}\n\n// Create Thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconst thriftClient: Calculator.Client<RequestOptions> = new Calculator.Client(connection)\n```\n\nHere `HttpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\nAlso of note here is that the type `IHttpConnectionOptions` does not accept the `requestOptions` parameter. Options to `Request` here would be passed directly to the call to `request.defaults({})`.\n\n### Creating a TCP Client\n\nCreating a TCP client is much like creating an HTTP client.\n\n* Use the `createTcpClient` factory function.\n* Manually create your own `TcpConnection` object\n\n*Note: Our TcpConnection object uses an underlying connection pool instead of all client requests reusing the same connection. This pool is configurable. We use [GenericPool](https://github.com/coopernurse/node-pool) for managing our connection pool. Pool options are passed directly through to GenericPool.*\n\n#### `createTcpClient`\n\nUsing the `createTcpClient` function you pass in two arguments, the first is your Thrift service client class and the second is a map of options to configure the underlying TCP connection.\n\n```typescript\nimport {\n    createTcpClient\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<RequestOptions> = createTcpClient(Calculator.Client, {\n    serviceName: 'calculator-service',\n    hostName: 'localhost',\n    port: 8080,\n})\n```\n\n##### Options\n\nThe available options are:\n\n* serviceName (optional): The name of your service. Used for logging.\n* hostName (required): The name of the host to connect to.\n* port (required): The port number to attach to on the host.\n* timeout (optional): Connection timeout in milliseconds. Defaults to 5000.\n* transport (optional): Name of the Thrift transport type to use. Defaults to 'buffered'.\n* protocol (optional): Name of the Thrift protocol type to use. Defaults to 'binary'.\n* pool (optional): Options to configure the underlying connection pool.\n* register (optional): A list of filters to apply to your client. More on this later.\n\n#### Manual Creation\n\n```typescript\nimport {\n    TcpConnection,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst connection: TcpConnection = new TcpConnection({\n    hostName: 'localhost',\n    port: 3000,\n    transport: 'buffered',\n    protocol: 'binary',\n})\n\nconst thriftClient: Calculator.Client<RequestOptions> = new Calculator.Client(connection)\n```\n\nHere `TcpConnection` is a class that extends the `ThriftConnection` abstract class. You could create custom connections, for instance TCP, by extending the same class.\n\n### Making Service Calls with our Client\n\nHowever we chose to make our client, we use them in the same way.\n\nNotice the optional context parameter. All service client methods can take an optional context parameter. This context refers to the request options for got library (OptionsOfBufferResponseBody). These options will be deep merged with any default options (passed in on instantiation) before sending a service request. This context can be used to do useful things like tracing or authentication. Usually this will be used for changing headers on a per-request basis.\n\nRelated to context you will notice that our Thrift service client is a generic `Calculator.Client<ThriftContext<RequestOptions>>`. This type parameter refers to the type of the context, here the `ThriftContext<RequestOptions>` which extends the options interface from the got library.\n\n```typescript\nimport {\n    createHttpClient,\n    RequestOptions\n} from '@creditkarma/thrift-client'\n\nimport * as express from 'express'\n\nimport { Calculator } from './codegen/calculator'\n\nconst serverConfig = {\n    hostName: 'localhost',\n    port: 8080,\n}\n\n// Create Thrift client\nconst thriftClient: Calculator.Client<ThriftContext<RequestOptions>> = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    requestOptions: {} // RequestOptions to pass to got\n})\n\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: RequestOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n\napp.listen(serverConfig.port, () => {\n    console.log(`Web server listening at http://${serverConfig.hostName}:${serverConfig.port}`)\n})\n```\n\n### Client Filters\n\nSometimes you'll want to universally filter or modify requests and/or responses. This is done with filters. If you've used many server libraries you are probably used to the idea of plugins or middleware.\n\nA filter is an object that consists of a handler function and an optional list of client method names to apply the filter to.\n\nFilters are applied in the order in which they are registered.\n\n```typescript\ninterface IRequestResponse {\n    statusCode: number\n    headers: IRequestHeaders\n    body: Buffer\n}\n\ntype NextFunction<Options> =\n    (data?: Buffer, options?: Options) => Promise<IRequestResponse>\n\ninterface IThriftClientFilterConfig<Options> {\n    methods?: Array<string>\n    handler(request: IThriftRequest<Options>, next: NextFunction<Options>): Promise<IRequestResponse>\n}\n```\n\nThe `handler` function receives as its arguments the `IThriftRequest` object and the next `RequestHandler` in the chain. When you are done applying your filter you `return` the call to `next`. When calling `next` you can optionally pass along a modified Thrift data `Buffer` or new options to apply to the request. `Options` is almost always going to be `RequestOptions` for the underlying got library.\n\n#### IThriftRequest\n\nThe `IThriftRequest` object wraps the outgoing data with some useful metadata about the current request.\n\n```typescript\nexport interface IThriftRequest<Context> {\n    data: Buffer\n    methodName: string\n    uri: string\n    context: Context\n}\n```\n\nThe `data` attribute is the outgoing Thrift payload. The `methodName` is the name of the Thrift service method being called.\n\nThe other interesting one is `context`. The context is the data passed through in the service method call.\n\nIf we look back at our previous client example we find this:\n\n```typescript\n// This receives a query like \"http://localhost:8080/add?left=5&right=3\"\napp.get('/add', (req: express.Request, res: express.Response): void => {\n    // Request contexts allow you to do tracing and auth\n    const context: RequestOptions = {\n        headers: {\n            'x-trace-id': 'my-trace-id'\n        }\n    }\n\n    // Client methods return a Promise of the expected result\n    thriftClient.add(req.query.left, req.query.right, context).then((result: number) => {\n        res.send(result)\n    }, (err: any) => {\n        res.status(500).send(err)\n    })\n})\n```\n\nWhere the context passed through is an instance of `RequestOptions`. These options are passed through to modify the outgoing request. Any filter in the filter chain can modify this data.\n\nTo modify this context one needs to pass the updated context to the `next` function.\n\n```typescript\nreturn next(request.data, updatedContext)\n```\n\n#### Applying Filters to Outgoing Requests\n\nSomething you may want to do with middlware is to apply some common HTTP headers to every outgoing request from your service. Maybe there is a token your service should attach to every outgoing request.\n\nYou could do something like this:\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest,\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n            return next(request.data, {\n                headers: {\n                    'x-fake-token': 'fake-token',\n                },\n            })\n        },\n    } ]\n})\n```\n\nThis sends data along unaltered, but adds a header `x-fake-token` to the outgoing request. When you send along options, the options are deep merged with any previous options that were applied.\n\n#### Applying Filters to Incoming Responses\n\nTo apply filters to the response you would call `.then` on the `next` function. This would allow you to inspect or modify the response before allowing it to proceed up the chain.\n\n```typescript\nimport {\n    createHttpClient,\n    IThriftRequest\n} from '@creditkarma/thrift-client'\n\nimport { Calculator } from './codegen/calculator'\n\nconst thriftClient: Calculator.Client = createHttpClient(Calculator.Client, {\n    hostName: 'localhost',\n    port: 8080,\n    register: [ {\n        handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n            return next().then((res: IRequestResponse) => {\n                if (validateResponse(res.body)) {\n                    return res\n                } else {\n                    throw new Error('Invalid data returned')\n                }\n            })\n        },\n    } ]\n})\n```\n\n#### Adding Filters to HttpConnection Object\n\nWhen you're not using `createHttpClient` you can add filters directly to the connection instance.\n\n```typescript\n// Create thrift client\nconst requestClient: RequestInstance = request.defaults({})\n\nconst connection: HttpConnection =\n    new HttpConnection(requestClient, clientConfig)\n\nconnection.register({\n    handler(request: IThriftRequest<RequestOptions>, next: NextFunction<RequestOptions>): Promise<IRequestResponse> {\n        return next(request.data, {\n            headers: {\n                'x-fake-token': 'fake-token',\n            },\n        })\n    },\n})\n\nconst thriftClient: Calculator.Client = new Calculator.Client(connection)\n```\n\nThe optional `register` option takes an array of filters to apply. Unsurprisingly they are applied in the order you pass them in.\n\n#### Available Filters\n\nThese client filters are maintained as part of this repository:\n\n* [ThriftClientContextFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-context-filter) - This is useful for TCP clients. It is a filter for appending Thrift objects onto an existing Thrift payload.\n* [ThriftClientTTwitterFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-ttwitter-filter) - This is for appending a TTwitter context onto an existing Thrift payload. This is for compatibility with Twitter's [Finagle](https://twitter.github.io/finagle/) framework.\n* [ThriftClientZipkinFilter](https://github.com/creditkarma/thrift-server/tree/master/packages/thrift-client-zipkin-filter) - This is for supporting distributed tracing with [Zipkin](https://github.com/openzipkin/zipkin-js).\n\n## Contributing\n\nFor more information about contributing new features and bug fixes, see our [Contribution Guidelines](../../CONTRIBUTING.md).\nExternal contributors must sign Contributor License Agreement (CLA)\n\n## License\n\nThis project is licensed under [Apache License Version 2.0](./LICENSE)\n","readmeFilename":"README.md","gitHead":"d213bbef402a85ec849adaf93bae2c953d7c11dc","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"},"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","_id":"@creditkarma/thrift-client@1.1.0-alpha.1","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-YR0Wr/qlv6QAv2QJZPO+MKxUSJySdVocqvsd0qd+kzrdunM6swVzwbFEKKiHNBW/lE3dFghsuxlC/Q6iYyZr0Q==","shasum":"15123d4a475a032fce27db52da86e527706f3da7","tarball":"https://registry.npmjs.org/@creditkarma/thrift-client/-/thrift-client-1.1.0-alpha.1.tgz","fileCount":33,"unpackedSize":76613,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBe3mxD9Pqp3dQH7FG7oe44WjduyUBZ99vGWMmmuG3ErAiEA4+7EbMQP97JTNKkYoTL3hhvQjmO3og5RYs0eSi4SZW4="}]},"_npmUser":{"name":"ck-npm","email":"pie@creditkarma.com"},"maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/thrift-client_1.1.0-alpha.1_1685987281631_0.6828263722335082"},"_hasShrinkwrap":false}},"readme":"","maintainers":[{"name":"ouranosskia","email":"UGAPiro@gmail.com"},{"name":"ck-npm","email":"pie@creditkarma.com"},{"name":"hightimesteddy","email":"hightimesteddy@gmail.com"},{"name":"nnanceck","email":"nick.nance@creditkarma.com"},{"name":"wookiehangover","email":"samuel.breed@gmail.com"},{"name":"riley-stroud-ck","email":"riley.stroud@creditkarma.com"}],"time":{"modified":"2023-06-05T17:48:01.975Z","created":"2017-10-16T16:52:44.179Z","0.0.12":"2017-10-16T16:52:44.179Z","0.0.13":"2017-10-16T17:20:55.704Z","0.0.14":"2017-10-16T18:13:11.060Z","0.0.15":"2017-10-16T19:09:33.964Z","0.0.16":"2017-10-16T19:14:07.688Z","0.0.17":"2017-10-16T19:22:27.053Z","0.0.18":"2017-10-16T19:34:58.883Z","0.0.19":"2017-10-16T19:45:12.826Z","0.0.20":"2017-10-16T20:00:59.128Z","0.0.21":"2017-10-16T20:23:53.603Z","0.0.22":"2017-10-16T20:34:24.013Z","0.0.23":"2017-10-16T20:50:50.390Z","0.0.24":"2017-10-16T21:01:37.330Z","0.0.27":"2017-10-16T21:25:14.676Z","0.0.28":"2017-10-16T22:36:16.489Z","0.0.30":"2017-10-16T22:57:34.569Z","0.0.31":"2017-10-16T23:48:39.685Z","0.0.32":"2017-10-17T16:48:35.848Z","0.0.34":"2017-10-19T22:57:42.113Z","0.0.35":"2017-10-25T17:54:15.080Z","0.0.36":"2017-11-02T22:26:29.294Z","0.0.37":"2017-11-28T19:31:14.606Z","0.1.1":"2017-12-06T00:02:33.939Z","0.1.2":"2017-12-08T22:43:43.461Z","0.1.3":"2017-12-11T22:34:10.954Z","0.2.0":"2017-12-19T06:54:46.006Z","0.3.3":"2018-01-02T19:01:10.682Z","0.3.5":"2018-01-12T00:58:45.613Z","0.3.6":"2018-01-12T19:25:00.237Z","0.4.0":"2018-01-25T19:10:01.950Z","0.4.1":"2018-01-31T04:52:04.758Z","0.4.2":"2018-02-01T21:24:25.268Z","0.4.3":"2018-02-02T05:31:09.349Z","0.5.0-0":"2018-02-21T00:49:41.676Z","0.5.0-1":"2018-02-21T22:18:45.772Z","0.5.0":"2018-03-12T20:57:59.915Z","0.5.1":"2018-03-12T22:20:59.257Z","0.6.0":"2018-03-13T17:43:58.863Z","0.6.1":"2018-03-13T18:02:25.332Z","0.6.2":"2018-03-13T19:55:49.370Z","0.6.3":"2018-03-19T17:04:23.520Z","0.6.4":"2018-03-20T18:59:30.819Z","0.6.5-2":"2018-03-20T20:39:54.838Z","0.6.5":"2018-03-21T17:35:57.517Z","0.6.6-0":"2018-03-21T21:05:27.840Z","0.6.6-1":"2018-03-27T21:58:51.165Z","0.6.6":"2018-03-28T17:14:28.521Z","0.4.5":"2018-03-29T17:06:56.749Z","0.7.0-0":"2018-04-05T15:44:49.796Z","0.7.0-1":"2018-04-05T15:58:02.253Z","0.7.0-2":"2018-04-05T17:54:26.250Z","0.6.7":"2018-04-10T17:02:40.991Z","0.6.8":"2018-04-17T17:50:20.327Z","0.6.9":"2018-04-29T19:22:15.531Z","0.7.0-3":"2018-05-06T01:15:29.213Z","0.6.10":"2018-05-09T16:40:54.819Z","0.6.11":"2018-05-09T23:15:39.802Z","0.6.12":"2018-05-11T15:20:22.722Z","0.6.13-0":"2018-05-15T15:21:57.077Z","0.6.13-1":"2018-05-15T20:20:05.533Z","0.6.13-2":"2018-05-15T20:32:06.597Z","0.6.13":"2018-05-15T21:07:29.857Z","0.6.14-0":"2018-05-17T23:11:50.576Z","0.6.14-1":"2018-05-17T23:27:26.156Z","0.6.14":"2018-05-17T23:46:29.529Z","0.6.15":"2018-05-18T23:10:47.730Z","0.6.16":"2018-05-24T01:54:55.442Z","0.6.17":"2018-05-24T18:11:44.333Z","0.6.18":"2018-05-25T05:53:58.861Z","0.7.0-4":"2018-06-01T17:48:20.142Z","0.6.19":"2018-06-04T18:33:59.531Z","0.7.0":"2018-06-04T20:34:09.673Z","0.6.21":"2018-06-15T17:16:31.039Z","0.7.3":"2018-07-09T18:48:06.008Z","0.8.0-1":"2018-08-16T16:26:47.100Z","0.8.1":"2018-08-16T21:54:36.429Z","0.8.2":"2018-08-22T21:45:02.074Z","0.9.0-alpha.2":"2018-08-28T16:16:54.235Z","0.6.22":"2018-08-30T18:47:27.429Z","0.6.23":"2018-08-30T20:27:31.593Z","0.8.3-alpha.0":"2018-09-04T18:47:01.863Z","0.8.3-alpha.1":"2018-09-04T20:22:40.401Z","0.8.3-alpha.2":"2018-09-05T19:00:10.799Z","0.8.3-alpha.3":"2018-09-05T21:28:27.948Z","0.8.3-alpha.4":"2018-09-06T19:29:14.736Z","0.6.24":"2018-09-07T18:34:11.612Z","0.6.25":"2018-09-07T18:41:06.409Z","0.9.0-alpha.3":"2018-09-11T22:54:07.480Z","0.9.0-alpha.4":"2018-09-12T17:31:14.573Z","0.9.0-alpha.5":"2018-09-12T18:04:32.933Z","0.6.27":"2018-09-12T19:10:44.758Z","0.6.28":"2018-09-12T21:23:05.823Z","0.6.29":"2018-09-13T04:55:46.729Z","0.9.0-alpha.6":"2018-09-13T18:35:41.296Z","0.9.0-alpha.7":"2018-09-14T16:29:53.803Z","0.6.30":"2018-09-25T00:07:13.878Z","0.9.0-alpha.8":"2018-10-06T04:54:16.099Z","0.9.0-alpha.9":"2018-10-06T05:02:57.138Z","0.9.0-alpha.10":"2018-10-11T17:20:59.458Z","0.9.1":"2018-10-12T20:32:08.454Z","0.10.0-alpha.1":"2018-10-25T19:52:28.143Z","0.10.0-alpha.2":"2018-10-25T20:12:23.371Z","0.9.2":"2018-10-29T23:07:40.480Z","0.6.31":"2018-10-29T23:21:38.323Z","0.8.3":"2018-10-29T23:33:58.243Z","0.8.4":"2018-11-05T23:19:49.086Z","0.9.3":"2018-11-08T21:00:23.210Z","0.10.0":"2018-11-16T23:10:15.626Z","0.10.1":"2018-11-16T23:36:33.361Z","0.10.2":"2018-11-19T02:56:38.627Z","0.10.3":"2018-11-19T17:39:04.127Z","0.10.4":"2018-11-19T21:06:53.100Z","0.8.5":"2018-11-29T23:20:10.198Z","0.11.0-alpha.0":"2018-11-30T02:57:28.520Z","0.11.0-alpha.1":"2018-12-04T21:58:27.778Z","0.11.0-alpha.2":"2018-12-05T21:36:26.610Z","0.6.32":"2018-12-07T20:54:01.758Z","0.6.33":"2018-12-13T17:22:32.302Z","0.11.1":"2018-12-18T23:38:36.219Z","0.11.2":"2019-01-07T22:27:29.843Z","0.6.34":"2019-01-10T23:43:32.257Z","0.12.1":"2019-01-11T22:51:32.359Z","0.12.2":"2019-01-11T22:58:54.261Z","0.12.3-alpha.0":"2019-01-14T04:24:21.002Z","0.12.3":"2019-01-14T04:48:27.280Z","0.12.4":"2019-01-14T19:38:04.349Z","0.12.5":"2019-01-14T22:16:45.888Z","0.6.35":"2019-02-22T01:39:03.744Z","0.13.2":"2019-03-05T05:22:13.341Z","0.13.3":"2019-03-05T05:25:13.327Z","0.13.4":"2019-03-05T15:54:11.399Z","0.13.5":"2019-03-29T05:54:31.064Z","0.13.6":"2019-04-12T22:26:45.763Z","0.13.7":"2019-06-19T02:17:59.294Z","0.13.8":"2019-08-07T20:48:36.613Z","0.14.1":"2019-08-09T23:49:05.816Z","0.14.2":"2019-08-13T17:31:10.430Z","0.14.3":"2019-08-13T20:28:02.197Z","0.14.4":"2019-08-16T04:13:15.936Z","0.14.5":"2019-08-22T15:15:01.519Z","0.14.6":"2019-09-05T19:03:47.214Z","0.15.1":"2019-10-02T18:00:09.609Z","0.15.2":"2019-10-14T19:52:58.287Z","0.15.3":"2019-10-15T01:40:04.529Z","0.16.0":"2020-01-21T22:17:57.608Z","0.16.1":"2020-05-27T19:00:53.172Z","0.17.0-alpha.0":"2021-04-01T16:22:52.051Z","0.17.1":"2021-04-02T23:33:20.596Z","0.17.2":"2021-04-03T02:13:59.353Z","0.18.0-alpha.0":"2022-05-13T16:27:23.954Z","0.18.0-alpha.1":"2022-05-16T15:56:06.602Z","0.18.0-alpha.5":"2022-05-16T20:33:09.605Z","0.18.1-alpha.0":"2022-05-17T23:28:34.118Z","0.18.1-alpha.3":"2022-05-17T23:42:16.712Z","0.18.1-alpha.4":"2022-05-17T23:49:47.650Z","0.18.1-alpha.5":"2022-06-02T23:54:29.190Z","0.18.1-alpha.6":"2022-06-08T18:19:54.737Z","0.18.1-alpha.7":"2022-06-08T18:48:05.890Z","0.18.1-alpha.8":"2022-06-08T20:29:26.101Z","0.18.1-alpha.9":"2022-06-13T17:54:34.308Z","1.0.3":"2022-06-24T23:18:35.894Z","1.0.4":"2022-06-24T23:25:55.491Z","1.0.6-alpha.0":"2023-03-08T21:30:34.910Z","1.1.0-alpha.1":"2023-06-05T17:48:01.775Z"},"repository":{"type":"git","url":"git+https://github.com/creditkarma/thrift-server.git#master"},"author":{"name":"Credit Karma"},"license":"Apache-2.0","readmeFilename":"","keywords":["thrift","typescript","rpc","microservices","http client","framework"],"homepage":"https://github.com/creditkarma/thrift-server/tree/master#readme","bugs":{"url":"https://github.com/creditkarma/thrift-server/issues"}}