├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── examples ├── methods.js └── simple.js ├── index.js ├── package.json └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.11" 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Dennis Leukhin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | co-request 2 | ========== 3 | 4 | Simple wrapper to the request library for co-like interface (node.js generator based code). 5 | You can use it with koa or co 6 | 7 | To install simply run: 8 | ```bash 9 | npm install co-request 10 | ``` 11 | 12 | Require co first, also it will work on node v0.11.7 and newest only. 13 | 14 | You must run node with --harmony flag (--harmony-generators as well) 15 | 16 | ```bash 17 | node --harmony simple.js 18 | ``` 19 | 20 | Simple example: 21 | 22 | ```js 23 | "use strict"; 24 | 25 | let co = require("co"); 26 | let request = require("co-request"); 27 | 28 | co(function* () { 29 | // You can also pass options object, see http://github.com/mikeal/request docs 30 | let result = yield request("http://google.com"); 31 | let response = result; 32 | let body = result.body; 33 | 34 | console.log("Response: ", response); 35 | console.log("Body: ", body); 36 | }).catch(function (err) { 37 | console.error(err); 38 | }); 39 | ``` 40 | 41 | POST example: 42 | 43 | ```js 44 | "use strict"; 45 | 46 | co(function* () { 47 | let result = yield request({ 48 | uri: "http://google.com", 49 | method: "POST" 50 | }); 51 | })(); 52 | ``` 53 | 54 | To pipe request you should use small helper (thanks to [greim](https://github.com/greim)): 55 | 56 | ```js 57 | function pipeRequest(readable, requestThunk){ 58 | return function(cb){ 59 | readable.pipe(requestThunk(cb)); 60 | } 61 | } 62 | 63 | //..and then: 64 | 65 | var value = yield pipeRequest(this.req, request({...})); 66 | ``` 67 | 68 | All methods of request listed in [Request docs](https://github.com/mikeal/request/blob/master/README.md) 69 | 70 | ##Gratitude## 71 | 72 | Thanks for Tj's [Co library](http://github.com/visionmedia/co) 73 | 74 | Thanks for Mikeal's [Request library](http://github.com/mikeal/request) 75 | -------------------------------------------------------------------------------- /examples/methods.js: -------------------------------------------------------------------------------- 1 | //Shows thunked methods in acion (se moore at https://github.com/mikeal/request/blob/master/README.md) 2 | 3 | "use strict"; 4 | 5 | let co = require('co'); 6 | let request = require('../'); 7 | 8 | co(function* () { 9 | //Get method 10 | let getResponse = yield request.get('http://nodejs.org'); 11 | let body = getResponse.body; 12 | 13 | console.log('Get Response: ', getResponse); 14 | console.log('Get Body: ', body); 15 | 16 | //Post method 17 | let postResponse = yield request.post('http://nodejs.org'); 18 | 19 | console.log('Post Response: ', postResponse); 20 | 21 | }).catch(function (err) { 22 | console.err(err); 23 | }); 24 | -------------------------------------------------------------------------------- /examples/simple.js: -------------------------------------------------------------------------------- 1 | //Shows entire HTTP response and its body 2 | 3 | "use strict"; 4 | 5 | let co = require('co'); 6 | let request = require('../'); 7 | 8 | co(function* () { 9 | let response = yield request('http://google.com'); 10 | let body = response.body; 11 | 12 | console.log('Response: ', response); 13 | console.log('Body: ', body); 14 | }).catch(function (err) { 15 | console.err(err); 16 | }); 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let request = require("request"); 4 | let __slice = Array.prototype.slice; 5 | 6 | /** 7 | * Promisify a request method. 8 | * 9 | * @param {Function} fn 10 | * @return {Function} 11 | */ 12 | let promisifyRequestMethod = function (fn) { 13 | let context = this; 14 | 15 | return function () { 16 | let args = __slice.call(arguments); //Array.from(arguments) is not available. 17 | 18 | return new Promise(function (resolve, reject) { 19 | 20 | // Concatenate the callback manually to avoid array arguments from co. 21 | return fn.apply(context, args.concat(function (err) { 22 | if (err) { 23 | reject(err); 24 | } else { 25 | resolve.apply(this, __slice.call(arguments, 1)); 26 | } 27 | })); 28 | }); 29 | } 30 | }; 31 | 32 | /** 33 | * Promisify a request function. 34 | * 35 | * @param {Function} request 36 | * @return {Function} 37 | */ 38 | let promisifyRequest = function (request) { 39 | let fn = promisifyRequestMethod(request); 40 | 41 | // Regular request methods that don't need be promisified. 42 | fn.jar = request.jar; 43 | fn.cookie = request.cookie; 44 | 45 | // Export the defaults method and return a promisified request instance. 46 | fn.defaults = function () { 47 | return promisifyRequest(request.defaults.apply(request, arguments)); 48 | }; 49 | 50 | // Export the forever agent method and return a promisified request instance. 51 | fn.forever = function () { 52 | return promisifyRequest(request.forever.apply(request, arguments)); 53 | }; 54 | 55 | // Attach all request methods. 56 | ["get", "patch", "post", "put", "head", "del"].forEach(function (method) { 57 | fn[method] = promisifyRequestMethod.call(request, request[method]); 58 | }); 59 | 60 | return fn; 61 | }; 62 | 63 | /** 64 | * Export a promisified request function. 65 | * 66 | * @type {Function} 67 | */ 68 | exports = module.exports = promisifyRequest(request); 69 | 70 | /** 71 | * Export the Request instance. 72 | * 73 | * @type {Function} 74 | */ 75 | exports.Request = request.Request; 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "co-request", 3 | "description": "co-request promisify wrapper for request", 4 | "main": "./", 5 | "author": { 6 | "name": "Dennis Leukhin", 7 | "email": "dennis.leukhin@gmail.com", 8 | "url": "leukhin.org" 9 | }, 10 | "version": "1.0.0", 11 | "scripts": { 12 | "test": "node_modules/.bin/mocha --harmony test/test.js" 13 | }, 14 | "keywords": [ 15 | "request", 16 | "rest", 17 | "koa", 18 | "co", 19 | "generators" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/leukhin/co-request.git" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/leukhin/co-request/issues" 27 | }, 28 | "dependencies": { 29 | "request": "*" 30 | }, 31 | "licenses": [ 32 | { 33 | "type": "MIT", 34 | "url": "https://github.com/leukhin/co-request/raw/master/LICENSE" 35 | } 36 | ], 37 | "devDependencies": { 38 | "co": "~3.0.2", 39 | "nock": "~0.27.1", 40 | "chai": "~1.8.1", 41 | "mocha": "~1.16.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var request = require('../'); 2 | var co = require('co'); 3 | 4 | var assert = require('chai').assert; 5 | var nock = require('nock'); 6 | 7 | describe('get', function() { 8 | describe('json body', function() { 9 | var server = nock("http://example.com") 10 | .persist() 11 | .get("/") 12 | .reply(200, {key: 'value'}); 13 | 14 | it('should allow passing options', function(done) { 15 | co(function* () { 16 | var result = yield request.get({ url: "http://example.com/" }); 17 | assert.equal(result.statusCode, 200); 18 | assert.isObject(result); 19 | assert.isString(result.body); 20 | assert.equal(result.body, '{"key":"value"}'); 21 | done(); 22 | })(); 23 | }); 24 | 25 | it('should get the json body as a string', function(done) { 26 | co(function* () { 27 | var result = yield request("http://example.com/"); 28 | assert.equal(result.statusCode, 200); 29 | assert.isObject(result); 30 | assert.isString(result.body); 31 | assert.equal(result.body, '{"key":"value"}'); 32 | done(); 33 | })(); 34 | }) 35 | 36 | it('should get the json body as an object', function(done) { 37 | co(function* () { 38 | var result = yield request({ 39 | url: "http://example.com/", 40 | json: true 41 | }); 42 | assert.equal(result.statusCode, 200); 43 | assert.isObject(result); 44 | assert.isObject(result.body); 45 | assert.deepEqual(result.body, {key:"value"}); 46 | done(); 47 | })(); 48 | }) 49 | }) 50 | 51 | describe('error response', function() { 52 | it('should handle 404 error', function(done) { 53 | var server = nock("http://example.com") 54 | .get("/notfound") 55 | .reply(404); 56 | co(function* () { 57 | var result = yield request("http://example.com/notfound"); 58 | assert.equal(result.statusCode, 404); 59 | assert.isObject(result); 60 | assert.isString(result.body); 61 | assert.equal(result.body, ''); 62 | done(); 63 | })(); 64 | }) 65 | 66 | it('should throw exceptions', function(done) { 67 | co(function* () { 68 | try { 69 | yield request("invalid url"); 70 | } catch(err) { 71 | assert.match(err.message, /Invalid URI/); 72 | } 73 | 74 | done(); 75 | })(); 76 | }) 77 | }) 78 | }); 79 | --------------------------------------------------------------------------------