From 31d1cc43cd5f828fec19f35c286396f859fa47cc Mon Sep 17 00:00:00 2001 From: Joe Skeen Date: Wed, 7 Oct 2015 09:41:45 -0600 Subject: [PATCH] Change request-promise to use full 'request' API --- request-promise/request-promise-tests.ts | 453 ++++++++++++++++++++++- request-promise/request-promise.d.ts | 25 +- request/request-tests.ts | 2 +- request/request.d.ts | 54 +-- 4 files changed, 486 insertions(+), 48 deletions(-) diff --git a/request-promise/request-promise-tests.ts b/request-promise/request-promise-tests.ts index 41a5eb80d..ad2f8f61f 100644 --- a/request-promise/request-promise-tests.ts +++ b/request-promise/request-promise-tests.ts @@ -1,17 +1,466 @@ /// import rp = require('request-promise'); +import nodeRequest = require('request'); rp('http://www.google.com') .then(console.dir) .catch(console.error); -var options: rp.Options = { +var options: nodeRequest.Options = { uri : 'http://posttestserver.com/post.php', - method : 'POST' + method : 'POST', + json: true, + body: { some: 'payload' } }; rp(options) .then(console.dir) .catch(console.error); +// --> Displays length of response from server after post + +// Get full response after DELETE +options = { + method: 'DELETE', + uri: 'http://my-server/path/to/resource/1234' +}; + +rp(options) + .then(function (response) { + console.log("DELETE succeeded with status %d", response.statusCode); + }) + .catch(console.error); + +//The following examples from https://github.com/request/request +import fs = require('fs'); +import http = require('http'); +var request = rp; + +//The following examples from https://github.com/request/request +request('http://www.google.com', function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log(body); // Show the HTML for the Google homepage. + } +}); + +request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')); + +fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')); + +request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png')); + +request + .get('http://google.com/img.png') + .on('response', function(response) { + console.log(response.statusCode); // 200 + console.log(response.headers['content-type']); // 'image/png' + }) + .pipe(request.put('http://mysite.com/img.png')); + +request + .get('http://mysite.com/doodle.png') + .on('error', function(err) { + console.log(err); + }) + .pipe(fs.createWriteStream('doodle.png')); + +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + if (req.method === 'PUT') { + req.pipe(request.put('http://mysite.com/doodle.png')); + } else if (req.method === 'GET' || req.method === 'HEAD') { + request.get('http://mysite.com/doodle.png').pipe(resp); + } + } +}); + +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + var x = request('http://mysite.com/doodle.png'); + req.pipe(x); + x.pipe(resp); + } +}); + +var resp: http.ServerResponse; +var req: nodeRequest.Request; +req.pipe(request('http://mysite.com/doodle.png')).pipe(resp); + +var r = request; +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + r.get('http://google.com/doodle.png').pipe(resp); + } +}); + +request.post('http://service.com/upload', {form:{key:'value'}}); +// or +request.post('http://service.com/upload').form({key:'value'}); +// or +request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ /* ... */ }); + +var data = { + // Pass a simple key-value pair + my_field: 'my_value', + // Pass data via Buffers + my_buffer: new Buffer([1, 2, 3]), + // Pass data via Streams + my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), + // Pass multiple values /w an Array + attachments: [ + fs.createReadStream(__dirname + '/attachment1.jpg'), + fs.createReadStream(__dirname + '/attachment2.jpg') + ], + // Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS} + // Use case: for some types of streams, you'll need to provide "file"-related information manually. + // See the `form-data` README for more information about options: https://github.com/felixge/node-form-data + custom_file: { + value: fs.createReadStream('/dev/urandom'), + options: { + filename: 'topsecret.jpg', + contentType: 'image/jpg' + } + } +}; +request.post({url:'http://service.com/upload', formData: data}, function optionalCallback(err, httpResponse, body) { + if (err) { + return console.error('upload failed:', err); + } + console.log('Upload successful! Server responded with:', body); +}); + +var requestMultipart = request.post('http://service.com/upload', function optionalCallback(err, httpResponse, body) {}); +var form = requestMultipart.form(); +form.append('my_field', 'my_value'); +form.append('my_buffer', new Buffer([1, 2, 3])); +form.append('custom_file', fs.createReadStream(__dirname + '/unicycle.jpg'), {filename: 'unicycle.jpg'}); + +request({ + method: 'PUT', + preambleCRLF: true, + postambleCRLF: true, + uri: 'http://service.com/upload', + multipart: { + chunked: false, + data: [ + { + 'content-type': 'application/json', + body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + }, + { body: 'I am an attachment' } + ] + } + }, + function (error, response, body) { + if (error) { + return console.error('upload failed:', error); + } + console.log('Upload successful! Server responded with:', body); + }); +request({ + method: 'PUT', + preambleCRLF: true, + postambleCRLF: true, + uri: 'http://service.com/upload', + multipart: [ + { + 'content-type': 'application/json', + body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + }, + { body: 'I am an attachment' }, + { body: fs.createReadStream('image.png') } + ] + }, + function (error, response, body) { + if (error) { + return console.error('upload failed:', error); + } + console.log('Upload successful! Server responded with:', body); + }); + +request.get('http://some.server.com/').auth('username', 'password', false); +// or +request.get('http://some.server.com/', { + 'auth': { + 'user': 'username', + 'pass': 'password', + 'sendImmediately': false + } +}); +// or +request.get('http://some.server.com/').auth(null, null, true, 'bearerToken'); +// or +request.get('http://some.server.com/', { + 'auth': { + 'bearer': 'bearerToken' + } +}); + +var username = 'username', + password = 'password', + url = 'http://' + username + ':' + password + '@some.server.com'; + +request({url: url}, function (error, response, body) { + // Do more stuff with 'body' here +}); + +options = { + url: 'https://api.github.com/repos/request/request', + headers: { + 'User-Agent': 'request' + } +}; + +function callback(error, response, body) { + if (!error && response.statusCode == 200) { + var info = JSON.parse(body); + console.log(info.stargazers_count + " Stars"); + console.log(info.forks_count + " Forks"); + } +} + +request(options, callback); + +// OAuth1.0 - 3-legged server side flow (Twitter example) +// step 1 +import qs = require('querystring'); +const CONSUMER_KEY = 'key'; +const CONSUMER_SECRET = 'secret'; +var oauth = + { callback: 'http://mysite.com/callback/' + , consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + } + , url = 'https://api.twitter.com/oauth/request_token' + ; +request.post({url:url, oauth:oauth}, function (e, r, body) { + // Ideally, you would take the body in the response + // and construct a URL that a user clicks on (like a sign in button). + // The verifier is only available in the response after a user has + // verified with twitter that they are authorizing your app. + + // step 2 + var req_data = qs.parse(body); + var uri = 'https://api.twitter.com/oauth/authenticate' + + '?' + qs.stringify({oauth_token: req_data.oauth_token}); + // redirect the user to the authorize uri + + // step 3 + // after the user is redirected back to your server + var auth_data = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: auth_data.oauth_token + , token_secret: req_data.oauth_token_secret + , verifier: auth_data.oauth_verifier + } + , url = 'https://api.twitter.com/oauth/access_token' + ; + request.post({url:url, oauth:oauth}, function (e, r, body) { + // ready to make signed requests on behalf of the user + var perm_data = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: perm_data.oauth_token + , token_secret: perm_data.oauth_token_secret + } + , url = 'https://api.twitter.com/1.1/users/show.json' + , qs = + { screen_name: perm_data.screen_name + , user_id: perm_data.user_id + } + ; + request.get({url:url, oauth:oauth, qs:qs, json:true}, function (e, r, user) { + console.log(user); + }); + }); +}); + +var path = require('path') + , certFile = path.resolve(__dirname, 'ssl/client.crt') + , keyFile = path.resolve(__dirname, 'ssl/client.key') + , caFile = path.resolve(__dirname, 'ssl/ca.cert.pem'); + +options = { + url: 'https://api.some-server.com/', + cert: fs.readFileSync(certFile), + key: fs.readFileSync(keyFile), + passphrase: 'password', + ca: fs.readFileSync(caFile) +}; + +request.get(options); + +var path = require('path') + , certFile = path.resolve(__dirname, 'ssl/client.crt') + , keyFile = path.resolve(__dirname, 'ssl/client.key'); + +options = { + url: 'https://api.some-server.com/', + agentOptions: { + cert: fs.readFileSync(certFile), + key: fs.readFileSync(keyFile), + // Or use `pfx` property replacing `cert` and `key` when using private key, certificate and CA certs in PFX or PKCS12 format: + // pfx: fs.readFileSync(pfxFilePath), + passphrase: 'password', + securityOptions: 'SSL_OP_NO_SSLv3' + } +}; + +request.get(options); + +request.get({ + url: 'https://api.some-server.com/', + agentOptions: { + secureProtocol: 'SSLv3_method' + } +}); + +request.get({ + url: 'https://api.some-server.com/', + agentOptions: { + ca: fs.readFileSync('ca.cert.pem') + } +}); + + +request({ + // will be ignored + method: 'GET', + uri: 'http://www.google.com', + + // HTTP Archive Request Object + har: { + url: 'http://www.mockbin.com/har', + method: 'POST', + headers: [ + { + name: 'content-type', + value: 'application/x-www-form-urlencoded' + } + ], + postData: { + mimeType: 'application/x-www-form-urlencoded', + params: [ + { + name: 'foo', + value: 'bar' + }, + { + name: 'hello', + value: 'world' + } + ] + } + } + }); + +//requests using baseRequest() will set the 'x-token' header +var baseRequest = request.defaults({ + headers: {'x-token': 'my-token'} +}); + +//requests using specialRequest() will include the 'x-token' header set in +//baseRequest and will also include the 'special' header +var specialRequest = baseRequest.defaults({ + headers: {special: 'special value'} +}); + +request.put(url); +request.patch(url); +request.post(url); +request.head(url); +request.del(url); +request.get(url); +request.cookie('key1=value1'); +request.jar(); +request.debug = true; + +request.get('http://10.255.255.1', {timeout: 1500}, function(err) { + console.log(err.code === 'ETIMEDOUT'); + // Set to `true` if the timeout was a connection timeout, `false` or + // `undefined` otherwise. + console.log(err.connect === true); + process.exit(0); +}); + +var rand = Math.floor(Math.random()*100000000).toString(); + request( + { method: 'PUT' + , uri: 'http://mikeal.iriscouch.com/testjs/' + rand + , multipart: + [ { 'content-type': 'application/json' + , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + } + , { body: 'I am an attachment' } + ] + } + , function (error, response, body) { + if(response.statusCode == 201){ + console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand) + } else { + console.log('error: '+ response.statusCode) + console.log(body) + } + } + ); + +request( + { method: 'GET' + , uri: 'http://www.google.com' + , gzip: true + } + , function (error, response, body) { + // body is the decompressed response body + console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity')) + console.log('the decoded data is: ' + body) + } + ).on('data', function(data) { + // decompressed data as it is received + console.log('decoded chunk: ' + data) + }) + .on('response', function(response) { + // unmodified http.IncomingMessage object + response.on('data', function(data) { + // compressed data as it is received + console.log('received ' + data.length + ' bytes of compressed data') + }) + }); + +var requestWithJar = request.defaults({jar: true}) +requestWithJar('http://www.google.com', function () { + requestWithJar('http://images.google.com'); +}); + +var j = request.jar() +requestWithJar = request.defaults({jar:j}) +requestWithJar('http://www.google.com', function () { + requestWithJar('http://images.google.com'); +}); + +var j = request.jar(); +var cookie = request.cookie('key1=value1'); +var url = 'http://www.google.com'; +j.setCookie(cookie, url); +request({url: url, jar: j}, function () { + request('http://images.google.com'); +}); + +//TODO: add definitions for tough-cookie-filestore +//var FileCookieStore = require('tough-cookie-filestore'); +// NOTE - currently the 'cookies.json' file must already exist! +//var j = request.jar(new FileCookieStore('cookies.json')); +requestWithJar = request.defaults({ jar : j }) +request('http://www.google.com', function() { + request('http://images.google.com'); +}); + +var j = request.jar() +request({url: 'http://www.google.com', jar: j}, function () { + var cookie_string = j.getCookieString(url); // "key1=value1; key2=value2; ..." + var cookies = j.getCookies(url); + // [{key: 'key1', value: 'value1', domain: "www.google.com", ...}, ...] +}); diff --git a/request-promise/request-promise.d.ts b/request-promise/request-promise.d.ts index 246f1e5d9..67b82ebd8 100644 --- a/request-promise/request-promise.d.ts +++ b/request-promise/request-promise.d.ts @@ -1,31 +1,20 @@ // Type definitions for request-promise v0.4.2 // Project: https://www.npmjs.com/package/request-promise -// Definitions by: Christopher Glantschnig +// Definitions by: Christopher Glantschnig , Joe Skeen // Definitions: https://github.com/borisyankov/DefinitelyTyped // Change [0]: 2015/08/20 - Aya Morisawa -/// -/// /// /// declare module 'request-promise' { import request = require('request'); - import stream = require('stream'); - import http = require('http'); - import FormData = require('form-data'); - - export = RequestPromiseAPI; - - function RequestPromiseAPI(options: RequestPromiseAPI.Options): Promise; - function RequestPromiseAPI(uri: string): Promise; - - module RequestPromiseAPI { - export interface Options extends request.Options { - simple?: boolean; - transform?: (body: any, response: http.IncomingMessage) => any; - resolveWithFullResponse?: boolean; - } + import http = require('http'); + + interface RequestPromise extends request.Request, Promise { } + + var requestPromise: request.RequestAPI; + export = requestPromise; } diff --git a/request/request-tests.ts b/request/request-tests.ts index 7f04be26a..99c7f566c 100644 --- a/request/request-tests.ts +++ b/request/request-tests.ts @@ -33,7 +33,7 @@ var bodyArr: request.RequestPart[] = [{ // --- --- --- --- --- --- --- --- --- --- --- --- -str = req.toJSON(); +obj = req.toJSON(); var cookieValue: request.CookieValue; str = cookieValue.name; diff --git a/request/request.d.ts b/request/request.d.ts index f3a2741fb..202adf955 100644 --- a/request/request.d.ts +++ b/request/request.d.ts @@ -1,6 +1,6 @@ // Type definitions for request // Project: https://github.com/mikeal/request -// Definitions by: Carlos Ballesteros Velasco , bonnici , Bart van der Schoor +// Definitions by: Carlos Ballesteros Velasco , bonnici , Bart van der Schoor , Joe Skeen // Definitions: https://github.com/borisyankov/DefinitelyTyped // Imported from: https://github.com/soywiz/typescript-node-definitions/d.ts @@ -16,40 +16,40 @@ declare module 'request' { import fs = require('fs'); namespace request { - export interface RequestAPI { - defaults(options: Options): RequestAPI; + export interface RequestAPI { + defaults(options: Options): RequestAPI; (uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void) - : Request; - (uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - (options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + : TRequest; + (uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + (options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - get(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - get(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - get(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + get(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + get(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + get(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - post(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - post(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - post(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + post(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + post(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + post(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - put(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - put(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - put(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + put(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + put(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + put(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - head(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - head(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - head(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + head(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + head(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + head(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - patch(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - patch(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - patch(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + patch(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + patch(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + patch(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - del(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - del(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; - del(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): Request; + del(uri: string, options?: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + del(uri: string, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; + del(options: Options, callback?: (error: any, response: http.IncomingMessage, body: any) => void): TRequest; - forever(agentOptions: any, optionsArg: any): Request; + forever(agentOptions: any, optionsArg: any): TRequest; jar(): CookieJar; cookie(str: string): Cookie; @@ -159,7 +159,7 @@ declare module 'request' { resume(): void; abort(): void; destroy(): void; - toJSON(): string; + toJSON(): Object; } export interface Headers { @@ -213,6 +213,6 @@ declare module 'request' { toString(): string; } } - var request: request.RequestAPI; + var request: request.RequestAPI; export = request; }