Comparing version 5.0.1 to 6.0.0
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var url_1 = require('url'); | ||
@@ -100,4 +101,4 @@ var querystring_1 = require('querystring'); | ||
if (Array.isArray(value)) { | ||
for (var _i = 0; _i < value.length; _i++) { | ||
var v = value[_i]; | ||
for (var _i = 0, value_1 = value; _i < value_1.length; _i++) { | ||
var v = value_1[_i]; | ||
this.rawHeaders.push(name, v); | ||
@@ -148,5 +149,5 @@ } | ||
return Base; | ||
})(); | ||
}()); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = Base; | ||
//# sourceMappingURL=base.js.map |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var Promise = require('any-promise'); | ||
@@ -11,3 +12,3 @@ var index_1 = require('./plugins/index'); | ||
} | ||
var xhr = request.raw = new XMLHttpRequest(); | ||
var xhr = request._raw = new XMLHttpRequest(); | ||
xhr.onload = function () { | ||
@@ -73,3 +74,3 @@ return resolve({ | ||
function abort(request) { | ||
request.raw.abort(); | ||
request._raw.abort(); | ||
} | ||
@@ -80,4 +81,4 @@ exports.abort = abort; | ||
var lines = headers.replace(/\r?\n$/, '').split(/\r?\n/); | ||
for (var _i = 0; _i < lines.length; _i++) { | ||
var header = lines[_i]; | ||
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) { | ||
var header = lines_1[_i]; | ||
var indexOf = header.indexOf(':'); | ||
@@ -84,0 +85,0 @@ var name_1 = header.substr(0, indexOf).trim(); |
@@ -0,2 +1,3 @@ | ||
"use strict"; | ||
module.exports = FormData; | ||
//# sourceMappingURL=form-data.js.map |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var CookieJar = (function () { | ||
@@ -6,4 +7,4 @@ function CookieJar() { | ||
return CookieJar; | ||
})(); | ||
}()); | ||
exports.CookieJar = CookieJar; | ||
//# sourceMappingURL=tough-cookie.js.map |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var extend = require('xtend'); | ||
@@ -2,0 +3,0 @@ var request_1 = require('./request'); |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var __extends = (this && this.__extends) || function (d, b) { | ||
@@ -16,5 +17,5 @@ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; | ||
return PopsicleError; | ||
})(makeErrorCause.BaseError); | ||
}(makeErrorCause.BaseError)); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = PopsicleError; | ||
//# sourceMappingURL=error.js.map |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var FormData = require('form-data'); | ||
@@ -2,0 +3,0 @@ function form(obj) { |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var http_1 = require('http'); | ||
@@ -28,2 +29,3 @@ var https_1 = require('https'); | ||
var requestCount = 0; | ||
var isStreaming = false; | ||
var confirmRedirect = typeof options.followRedirects === 'function' ? | ||
@@ -48,23 +50,23 @@ options.followRedirects : falsey; | ||
arg.key = options.key; | ||
var req = engine(arg); | ||
var requestProxy = new stream_1.PassThrough(); | ||
var responseProxy = new stream_1.PassThrough(); | ||
requestProxy.on('data', function (chunk) { | ||
request.uploadedBytes = request.uploadedBytes + chunk.length; | ||
var rawRequest = engine(arg); | ||
var requestStream = new stream_1.PassThrough(); | ||
var responseStream = new stream_1.PassThrough(); | ||
requestStream.on('data', function (chunk) { | ||
request.uploadedBytes += chunk.length; | ||
}); | ||
requestProxy.on('end', function () { | ||
requestStream.on('end', function () { | ||
request.uploadedBytes = request.uploadLength; | ||
}); | ||
responseProxy.on('data', function (chunk) { | ||
request.downloadedBytes = request.downloadedBytes + chunk.length; | ||
responseStream.on('data', function (chunk) { | ||
request.downloadedBytes += chunk.length; | ||
}); | ||
responseProxy.on('end', function () { | ||
responseStream.on('end', function () { | ||
request.downloadedBytes = request.downloadLength; | ||
}); | ||
function response(res) { | ||
var status = res.statusCode; | ||
function response(rawResponse) { | ||
var status = rawResponse.statusCode; | ||
var redirect = REDIRECT_STATUS[status]; | ||
if (followRedirects && redirect != null && res.headers.location) { | ||
var newUrl = urlLib.resolve(url, res.headers.location); | ||
res.resume(); | ||
if (followRedirects && redirect != null && rawResponse.headers.location) { | ||
var newUrl = urlLib.resolve(url, rawResponse.headers.location); | ||
rawResponse.resume(); | ||
request.remove('Cookie'); | ||
@@ -79,3 +81,3 @@ if (redirect === REDIRECT_TYPE.FOLLOW_WITH_GET) { | ||
} | ||
if (confirmRedirect(req, res)) { | ||
if (confirmRedirect(rawRequest, rawResponse)) { | ||
return get(newUrl, method, body); | ||
@@ -85,36 +87,47 @@ } | ||
} | ||
request.downloadLength = num(res.headers['content-length'], 0); | ||
res.pipe(responseProxy); | ||
request.downloadLength = num(rawResponse.headers['content-length'], 0); | ||
isStreaming = true; | ||
rawResponse.pipe(responseStream); | ||
return Promise.resolve({ | ||
body: responseProxy, | ||
body: responseStream, | ||
status: status, | ||
statusText: res.statusMessage, | ||
headers: res.headers, | ||
rawHeaders: res.rawHeaders, | ||
statusText: rawResponse.statusMessage, | ||
headers: rawResponse.headers, | ||
rawHeaders: rawResponse.rawHeaders, | ||
url: url | ||
}); | ||
} | ||
req.once('response', function (message) { | ||
return resolve(setCookies(request, message).then(function () { return response(message); })); | ||
function emitError(error) { | ||
rawRequest.abort(); | ||
if (isStreaming) { | ||
responseStream.emit('error', error); | ||
} | ||
else { | ||
reject(error); | ||
} | ||
} | ||
rawRequest.once('response', function (message) { | ||
resolve(setCookies(request, message).then(function () { return response(message); })); | ||
}); | ||
req.once('abort', function () { | ||
return reject(request.error('Request aborted', 'EABORT')); | ||
rawRequest.once('error', function (error) { | ||
emitError(request.error("Unable to connect to \"" + url + "\"", 'EUNAVAILABLE', error)); | ||
}); | ||
req.once('error', function (error) { | ||
return reject(request.error("Unable to connect to \"" + url + "\"", 'EUNAVAILABLE', error)); | ||
rawRequest.once('clientAborted', function () { | ||
emitError(request.error('Request aborted', 'EABORT')); | ||
}); | ||
requestProxy.once('error', reject); | ||
request.raw = req; | ||
request.uploadLength = num(req.getHeader('content-length'), 0); | ||
requestProxy.pipe(req); | ||
request._raw = rawRequest; | ||
request.uploadLength = num(rawRequest.getHeader('content-length'), 0); | ||
requestStream.pipe(rawRequest); | ||
requestStream.once('error', emitError); | ||
if (body) { | ||
if (typeof body.pipe === 'function') { | ||
body.pipe(requestProxy); | ||
body.pipe(requestStream); | ||
body.once('error', emitError); | ||
} | ||
else { | ||
requestProxy.end(body); | ||
requestStream.end(body); | ||
} | ||
} | ||
else { | ||
requestProxy.end(); | ||
requestStream.end(); | ||
} | ||
@@ -128,3 +141,4 @@ }); | ||
function abort(request) { | ||
request.raw.abort(); | ||
request._raw.emit('clientAborted'); | ||
request._raw.abort(); | ||
} | ||
@@ -131,0 +145,0 @@ exports.abort = abort; |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var tough_cookie_1 = require('tough-cookie'); | ||
@@ -2,0 +3,0 @@ function cookieJar(store) { |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
function __export(m) { | ||
@@ -2,0 +3,0 @@ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; |
@@ -0,4 +1,7 @@ | ||
import Promise = require('any-promise'); | ||
import Request from '../request'; | ||
export declare function headers(): (request: Request) => void; | ||
export declare function stringify(): (request: Request) => void; | ||
export declare function parse(): (request: Request) => void; | ||
import Response from '../response'; | ||
export declare function wrap<T>(value: T): () => T; | ||
export declare const headers: () => (request: Request, next: () => Promise<Response>) => Promise<Response>; | ||
export declare const stringify: () => (request: Request, next: () => Promise<Response>) => Promise<Response>; | ||
export declare const parse: () => (request: Request, next: () => Promise<Response>) => Promise<{}>; |
@@ -0,4 +1,6 @@ | ||
"use strict"; | ||
var Promise = require('any-promise'); | ||
var FormData = require('form-data'); | ||
var querystring_1 = require('querystring'); | ||
var index_1 = require('./is-host/index'); | ||
var form_1 = require('../form'); | ||
@@ -8,23 +10,7 @@ var JSON_MIME_REGEXP = /^application\/(?:[\w!#\$%&\*`\-\.\^~]*\+)?json$/i; | ||
var FORM_MIME_REGEXP = /^multipart\/form-data$/i; | ||
var isHostObject; | ||
if (process.browser) { | ||
isHostObject = function (object) { | ||
var str = Object.prototype.toString.call(object); | ||
switch (str) { | ||
case '[object File]': | ||
case '[object Blob]': | ||
case '[object FormData]': | ||
case '[object ArrayBuffer]': | ||
return true; | ||
default: | ||
return false; | ||
} | ||
}; | ||
function wrap(value) { | ||
return function () { return value; }; | ||
} | ||
else { | ||
isHostObject = function (object) { | ||
return typeof object.pipe === 'function' || Buffer.isBuffer(object); | ||
}; | ||
} | ||
function defaultHeaders(request) { | ||
exports.wrap = wrap; | ||
exports.headers = wrap(function (request, next) { | ||
if (!request.get('Accept')) { | ||
@@ -34,11 +20,12 @@ request.set('Accept', '*/*'); | ||
request.remove('Host'); | ||
} | ||
function stringifyRequest(request) { | ||
return next(); | ||
}); | ||
exports.stringify = wrap(function (request, next) { | ||
var body = request.body; | ||
if (Object(body) !== body) { | ||
request.body = body == null ? null : String(body); | ||
return; | ||
return next(); | ||
} | ||
if (isHostObject(body)) { | ||
return; | ||
if (index_1.default(body)) { | ||
return next(); | ||
} | ||
@@ -67,43 +54,30 @@ var type = request.type(); | ||
} | ||
} | ||
function parseResponse(response) { | ||
var body = response.body; | ||
if (typeof body !== 'string') { | ||
return; | ||
} | ||
if (body === '') { | ||
response.body = null; | ||
return; | ||
} | ||
var type = response.type(); | ||
try { | ||
if (JSON_MIME_REGEXP.test(type)) { | ||
response.body = body === '' ? null : JSON.parse(body); | ||
return next(); | ||
}); | ||
exports.parse = wrap(function (request, next) { | ||
return next() | ||
.then(function (response) { | ||
var body = response.body; | ||
if (typeof body !== 'string') { | ||
return response; | ||
} | ||
else if (QUERY_MIME_REGEXP.test(type)) { | ||
response.body = querystring_1.parse(body); | ||
if (body === '') { | ||
response.body = null; | ||
return response; | ||
} | ||
} | ||
catch (err) { | ||
return Promise.reject(response.error('Unable to parse response body: ' + err.message, 'EPARSE', err)); | ||
} | ||
} | ||
function headers() { | ||
return function (request) { | ||
request.before(defaultHeaders); | ||
}; | ||
} | ||
exports.headers = headers; | ||
function stringify() { | ||
return function (request) { | ||
request.before(stringifyRequest); | ||
}; | ||
} | ||
exports.stringify = stringify; | ||
function parse() { | ||
return function (request) { | ||
request.after(parseResponse); | ||
}; | ||
} | ||
exports.parse = parse; | ||
var type = response.type(); | ||
try { | ||
if (JSON_MIME_REGEXP.test(type)) { | ||
response.body = body === '' ? null : JSON.parse(body); | ||
} | ||
else if (QUERY_MIME_REGEXP.test(type)) { | ||
response.body = querystring_1.parse(body); | ||
} | ||
} | ||
catch (err) { | ||
return Promise.reject(request.error('Unable to parse response body: ' + err.message, 'EPARSE', err)); | ||
} | ||
return response; | ||
}); | ||
}); | ||
//# sourceMappingURL=common.js.map |
@@ -0,6 +1,8 @@ | ||
import Promise = require('any-promise'); | ||
export * from './common'; | ||
import Request, { Middleware } from '../request'; | ||
export declare function unzip(): (request: Request) => void; | ||
export declare function concatStream(encoding: string): (request: Request) => void; | ||
export declare function headers(): (request: Request) => void; | ||
import Response from '../response'; | ||
export declare const unzip: () => (request: Request, next: () => Promise<Response>) => Promise<Response>; | ||
export declare function concatStream(encoding: string): (request: Request, next: () => Promise<Response>) => Promise<{}>; | ||
export declare function headers(): (request: Request, next: () => Promise<Response>) => Promise<Response>; | ||
export declare const defaults: Middleware[]; |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
function __export(m) { | ||
@@ -10,32 +11,27 @@ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
var common_2 = require('./common'); | ||
function unzipResponse(response) { | ||
if (['gzip', 'deflate'].indexOf(response.get('Content-Encoding')) > -1) { | ||
var unzip_1 = zlib_1.createUnzip(); | ||
response.body.pipe(unzip_1); | ||
response.body = unzip_1; | ||
} | ||
} | ||
function unzipHeaders(request) { | ||
exports.unzip = common_2.wrap(function (request, next) { | ||
if (!request.get('Accept-Encoding')) { | ||
request.set('Accept-Encoding', 'gzip,deflate'); | ||
} | ||
} | ||
function unzip() { | ||
return function (request) { | ||
request.before(unzipHeaders); | ||
request.after(unzipResponse); | ||
}; | ||
} | ||
exports.unzip = unzip; | ||
return next() | ||
.then(function (response) { | ||
var enc = response.get('Content-Encoding'); | ||
if (enc === 'gzip' || enc === 'deflate') { | ||
var unzip_1 = zlib_1.createUnzip(); | ||
response.body.pipe(unzip_1); | ||
response.body = unzip_1; | ||
} | ||
return response; | ||
}); | ||
}); | ||
function concatStream(encoding) { | ||
return function (request) { | ||
request.after(function (response) { | ||
return function (request, next) { | ||
return next() | ||
.then(function (response) { | ||
return new Promise(function (resolve, reject) { | ||
var stream = concat({ | ||
encoding: encoding | ||
}, function (data) { | ||
var stream = concat({ encoding: encoding }, function (data) { | ||
response.body = data; | ||
return resolve(); | ||
return resolve(response); | ||
}); | ||
response.body.once('error', reject); | ||
response.body.on('error', reject); | ||
response.body.pipe(stream); | ||
@@ -47,54 +43,53 @@ }); | ||
exports.concatStream = concatStream; | ||
function defaultHeaders(request) { | ||
if (!request.get('User-Agent')) { | ||
request.set('User-Agent', 'https://github.com/blakeembrey/popsicle'); | ||
} | ||
if (request.body instanceof FormData) { | ||
request.set('Content-Type', 'multipart/form-data; boundary=' + request.body.getBoundary()); | ||
return new Promise(function (resolve, reject) { | ||
request.body.getLength(function (err, length) { | ||
if (err) { | ||
request.set('Transfer-Encoding', 'chunked'); | ||
function headers() { | ||
var common = common_2.headers(); | ||
return function (request, next) { | ||
return common(request, function () { | ||
if (!request.get('User-Agent')) { | ||
request.set('User-Agent', 'https://github.com/blakeembrey/popsicle'); | ||
} | ||
if (request.body instanceof FormData) { | ||
request.set('Content-Type', 'multipart/form-data; boundary=' + request.body.getBoundary()); | ||
return new Promise(function (resolve, reject) { | ||
request.body.getLength(function (err, length) { | ||
if (err) { | ||
request.set('Transfer-Encoding', 'chunked'); | ||
} | ||
else { | ||
request.set('Content-Length', String(length)); | ||
} | ||
return resolve(next()); | ||
}); | ||
}); | ||
} | ||
var length = 0; | ||
var body = request.body; | ||
if (body && !request.get('Content-Length')) { | ||
if (Array.isArray(body)) { | ||
for (var i = 0; i < body.length; i++) { | ||
length += body[i].length; | ||
} | ||
} | ||
else if (typeof body === 'string') { | ||
length = Buffer.byteLength(body); | ||
} | ||
else { | ||
length = body.length; | ||
} | ||
if (length) { | ||
request.set('Content-Length', String(length)); | ||
} | ||
return resolve(); | ||
}); | ||
else if (typeof body.pipe === 'function') { | ||
request.set('Transfer-Encoding', 'chunked'); | ||
} | ||
else { | ||
return Promise.reject(request.error('Argument error, `options.body`', 'EBODY')); | ||
} | ||
} | ||
return next(); | ||
}); | ||
} | ||
var length = 0; | ||
var body = request.body; | ||
if (body && !request.get('Content-Length')) { | ||
if (Array.isArray(body)) { | ||
for (var i = 0; i < body.length; i++) { | ||
length += body[i].length; | ||
} | ||
} | ||
else if (typeof body === 'string') { | ||
length = Buffer.byteLength(body); | ||
} | ||
else { | ||
length = body.length; | ||
} | ||
if (length) { | ||
request.set('Content-Length', String(length)); | ||
} | ||
else if (typeof body.pipe === 'function') { | ||
request.set('Transfer-Encoding', 'chunked'); | ||
} | ||
else { | ||
return Promise.reject(request.error('Argument error, `options.body`', 'EBODY')); | ||
} | ||
} | ||
} | ||
function headers() { | ||
var defaults = common_2.headers(); | ||
return function (request) { | ||
defaults(request); | ||
request.before(defaultHeaders); | ||
}; | ||
} | ||
exports.headers = headers; | ||
exports.defaults = [common_2.stringify(), headers(), unzip(), concatStream('string'), common_2.parse()]; | ||
exports.defaults = [common_2.stringify(), headers(), common_2.parse(), concatStream('string'), exports.unzip()]; | ||
//# sourceMappingURL=index.js.map |
@@ -12,6 +12,3 @@ import Promise = require('any-promise'); | ||
use?: Middleware[]; | ||
before?: RequestPluginFunction[]; | ||
after?: ResponsePluginFunction[]; | ||
always?: RequestPluginFunction[]; | ||
progress?: RequestPluginFunction[]; | ||
progress?: ProgressFunction[]; | ||
transport?: TransportOptions; | ||
@@ -35,5 +32,4 @@ } | ||
} | ||
export declare type Middleware = (request?: Request) => any; | ||
export declare type RequestPluginFunction = (request?: Request) => any; | ||
export declare type ResponsePluginFunction = (response?: Response) => any; | ||
export declare type Middleware = (request: Request, next: () => Promise<Response>) => Response | Promise<Response>; | ||
export declare type ProgressFunction = (request: Request) => any; | ||
export declare type OpenHandler = (request: Request) => Promise<ResponseOptions>; | ||
@@ -46,10 +42,5 @@ export declare type AbortHandler = (request: Request) => any; | ||
options: any; | ||
response: Response; | ||
raw: any; | ||
errored: PopsicleError; | ||
transport: TransportOptions; | ||
opened: boolean; | ||
aborted: boolean; | ||
timedout: boolean; | ||
opened: boolean; | ||
started: boolean; | ||
uploadLength: number; | ||
@@ -59,9 +50,9 @@ downloadLength: number; | ||
private _downloadedBytes; | ||
_raw: any; | ||
_use: Middleware[]; | ||
_progress: ProgressFunction[]; | ||
private _promise; | ||
private _before; | ||
private _after; | ||
private _always; | ||
private _progress; | ||
private _resolve; | ||
private _reject; | ||
constructor(options: RequestOptions); | ||
use(fn: Middleware | Middleware[]): this; | ||
error(message: string, code: string, original?: Error): PopsicleError; | ||
@@ -74,7 +65,7 @@ then(onFulfilled: (response?: Response) => any, onRejected?: (error?: PopsicleError) => any): Promise<any>; | ||
clone(): Request; | ||
progress(fn: RequestPluginFunction | RequestPluginFunction[]): Request; | ||
before(fn: RequestPluginFunction | RequestPluginFunction[]): Request; | ||
after(fn: ResponsePluginFunction | ResponsePluginFunction[]): Request; | ||
always(fn: RequestPluginFunction | RequestPluginFunction[]): Request; | ||
use(fns: Middleware | Middleware[]): this; | ||
progress(fns: ProgressFunction | ProgressFunction[]): this; | ||
abort(): this; | ||
private _emit(); | ||
private _handle(); | ||
uploaded: number; | ||
@@ -81,0 +72,0 @@ downloaded: number; |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var __extends = (this && this.__extends) || function (d, b) { | ||
@@ -9,2 +10,3 @@ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; | ||
var Promise = require('any-promise'); | ||
var throwback_1 = require('throwback'); | ||
var base_1 = require('./base'); | ||
@@ -18,6 +20,4 @@ var response_1 = require('./response'); | ||
_super.call(this, options); | ||
this.opened = false; | ||
this.aborted = false; | ||
this.timedout = false; | ||
this.opened = false; | ||
this.started = false; | ||
this.uploadLength = null; | ||
@@ -27,25 +27,26 @@ this.downloadLength = null; | ||
this._downloadedBytes = null; | ||
this._before = []; | ||
this._after = []; | ||
this._always = []; | ||
this._use = []; | ||
this._progress = []; | ||
this.timeout = Number(options.timeout) || 0; | ||
this.timeout = (options.timeout | 0); | ||
this.method = (options.method || 'GET').toUpperCase(); | ||
this.body = options.body; | ||
this.options = extend(options.options); | ||
this._promise = new Promise(function (resolve, reject) { | ||
process.nextTick(function () { return start(_this).then(resolve, reject); }); | ||
var promised = new Promise(function (resolve, reject) { | ||
_this._resolve = resolve; | ||
_this._reject = reject; | ||
}); | ||
this._promise = new Promise(function (resolve) { | ||
process.nextTick(function () { | ||
var handle = throwback_1.compose(_this._use); | ||
var cb = function () { | ||
_this._handle(); | ||
return promised; | ||
}; | ||
return resolve(handle(_this, cb)); | ||
}); | ||
}); | ||
this.transport = extend(options.transport); | ||
this.use(options.use || this.transport.use); | ||
this.before(options.before); | ||
this.after(options.after); | ||
this.always(options.always); | ||
this.progress(options.progress); | ||
} | ||
Request.prototype.use = function (fn) { | ||
var _this = this; | ||
arrify(fn).forEach(function (fn) { return fn(_this); }); | ||
return this; | ||
}; | ||
Request.prototype.error = function (message, code, original) { | ||
@@ -58,3 +59,3 @@ return new error_1.default(message, code, original, this); | ||
Request.prototype.catch = function (onRejected) { | ||
return this.then(null, onRejected); | ||
return this._promise.then(null, onRejected); | ||
}; | ||
@@ -71,3 +72,2 @@ Request.prototype.exec = function (cb) { | ||
options: this.options, | ||
use: [], | ||
body: this.body, | ||
@@ -77,6 +77,4 @@ transport: this.transport, | ||
rawHeaders: this.rawHeaders, | ||
before: this._before, | ||
after: this._after, | ||
progress: this._progress, | ||
always: this._always | ||
use: this._use, | ||
progress: this._progress | ||
}; | ||
@@ -97,23 +95,24 @@ }; | ||
}; | ||
Request.prototype.progress = function (fn) { | ||
return pluginFunction(this, '_progress', fn); | ||
Request.prototype.use = function (fns) { | ||
for (var _i = 0, _a = arrify(fns); _i < _a.length; _i++) { | ||
var fn = _a[_i]; | ||
this._use.push(fn); | ||
} | ||
return this; | ||
}; | ||
Request.prototype.before = function (fn) { | ||
return pluginFunction(this, '_before', fn); | ||
Request.prototype.progress = function (fns) { | ||
for (var _i = 0, _a = arrify(fns); _i < _a.length; _i++) { | ||
var fn = _a[_i]; | ||
this._progress.push(fn); | ||
} | ||
return this; | ||
}; | ||
Request.prototype.after = function (fn) { | ||
return pluginFunction(this, '_after', fn); | ||
}; | ||
Request.prototype.always = function (fn) { | ||
return pluginFunction(this, '_always', fn); | ||
}; | ||
Request.prototype.abort = function () { | ||
if (this.completed === 1 || this.aborted) { | ||
return this; | ||
return; | ||
} | ||
this.aborted = true; | ||
this.errored = this.errored || this.error('Request aborted', 'EABORT'); | ||
this._reject(this.error('Request aborted', 'EABORT')); | ||
if (this.opened) { | ||
emitProgress(this); | ||
this._progress = null; | ||
this._emit(); | ||
if (this.transport.abort) { | ||
@@ -125,2 +124,36 @@ this.transport.abort(this); | ||
}; | ||
Request.prototype._emit = function () { | ||
var fns = this._progress; | ||
try { | ||
for (var _i = 0, fns_1 = fns; _i < fns_1.length; _i++) { | ||
var fn = fns_1[_i]; | ||
fn(this); | ||
} | ||
} | ||
catch (err) { | ||
this._reject(err); | ||
this.abort(); | ||
} | ||
}; | ||
Request.prototype._handle = function () { | ||
var _this = this; | ||
var _a = this, timeout = _a.timeout, url = _a.url; | ||
var timer; | ||
if (this.aborted) { | ||
return; | ||
} | ||
this.opened = true; | ||
if (/^https?\:\/*(?:[~#\\\?;\:]|$)/.test(url)) { | ||
this._reject(this.error("Refused to connect to invalid URL \"" + url + "\"", 'EINVALID')); | ||
return; | ||
} | ||
if (timeout > 0) { | ||
timer = setTimeout(function () { | ||
_this._reject(_this.error("Timeout of " + timeout + "ms exceeded", 'ETIMEOUT')); | ||
_this.abort(); | ||
}, timeout); | ||
} | ||
return this.transport.open(this) | ||
.then(function (res) { return _this._resolve(new response_1.default(res)); }, function (err) { return _this._reject(err); }); | ||
}; | ||
Object.defineProperty(Request.prototype, "uploaded", { | ||
@@ -168,3 +201,3 @@ get: function () { | ||
this._uploadedBytes = bytes; | ||
emitProgress(this); | ||
this._emit(); | ||
} | ||
@@ -182,3 +215,3 @@ }, | ||
this._downloadedBytes = bytes; | ||
emitProgress(this); | ||
this._emit(); | ||
} | ||
@@ -190,84 +223,5 @@ }, | ||
return Request; | ||
})(base_1.default); | ||
}(base_1.default)); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = Request; | ||
function pluginFunction(request, property, fns) { | ||
if (request.started) { | ||
throw new TypeError('Plugins can not be used after the request has started'); | ||
} | ||
for (var _i = 0, _a = arrify(fns); _i < _a.length; _i++) { | ||
var fn = _a[_i]; | ||
if (typeof fn !== 'function') { | ||
throw new TypeError("Expected a function, but got " + fn + " instead"); | ||
} | ||
; | ||
request[property].push(fn); | ||
} | ||
return request; | ||
} | ||
function start(request) { | ||
var req = request; | ||
var timeout = request.timeout, url = request.url; | ||
var timer; | ||
request.started = true; | ||
if (request.errored) { | ||
return Promise.reject(request.errored); | ||
} | ||
if (/^https?\:\/*(?:[~#\\\?;\:]|$)/.test(url)) { | ||
return Promise.reject(request.error("Refused to connect to invalid URL \"" + url + "\"", 'EINVALID')); | ||
} | ||
return chain(req._before, request) | ||
.then(function () { | ||
if (request.errored) { | ||
return; | ||
} | ||
if (timeout) { | ||
timer = setTimeout(function () { | ||
var error = request.error("Timeout of " + request.timeout + "ms exceeded", 'ETIMEOUT'); | ||
request.errored = error; | ||
request.timedout = true; | ||
request.abort(); | ||
}, timeout); | ||
} | ||
req.opened = true; | ||
return req.transport.open(request) | ||
.then(function (options) { | ||
var response = new response_1.default(options); | ||
response.request = request; | ||
request.response = response; | ||
return chain(req._after, response); | ||
}); | ||
}) | ||
.then(function () { return chain(req._always, request); }, function (error) { return chain(req._always, request).then(function () { return Promise.reject(error); }); }) | ||
.then(function () { | ||
if (request.errored) { | ||
return Promise.reject(request.errored); | ||
} | ||
return request.response; | ||
}, function (error) { | ||
request.errored = request.errored || error; | ||
return Promise.reject(request.errored); | ||
}); | ||
} | ||
function chain(fns, arg) { | ||
return fns.reduce(function (p, fn) { | ||
return p.then(function () { return fn(arg); }); | ||
}, Promise.resolve()); | ||
} | ||
function emitProgress(request) { | ||
var fns = request._progress; | ||
if (!fns || request.errored) { | ||
return; | ||
} | ||
try { | ||
for (var _i = 0; _i < fns.length; _i++) { | ||
var fn = fns[_i]; | ||
fn(request); | ||
} | ||
} | ||
catch (err) { | ||
request.errored = err; | ||
request.abort(); | ||
} | ||
} | ||
//# sourceMappingURL=request.js.map |
import Base, { BaseOptions, Headers, RawHeaders } from './base'; | ||
import Request from './request'; | ||
import PopsicleError from './error'; | ||
export interface ResponseOptions extends BaseOptions { | ||
@@ -21,7 +19,5 @@ body: any; | ||
body: any; | ||
request: Request; | ||
constructor(options: ResponseOptions); | ||
statusType(): number; | ||
error(message: string, type: string, error?: Error): PopsicleError; | ||
toJSON(): ResponseJSON; | ||
} |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var __extends = (this && this.__extends) || function (d, b) { | ||
@@ -18,5 +19,2 @@ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; | ||
}; | ||
Response.prototype.error = function (message, type, error) { | ||
return this.request.error(message, type, error); | ||
}; | ||
Response.prototype.toJSON = function () { | ||
@@ -33,5 +31,5 @@ return { | ||
return Response; | ||
})(base_1.default); | ||
}(base_1.default)); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = Response; | ||
//# sourceMappingURL=response.js.map |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var test = require('blue-tape'); | ||
@@ -53,3 +54,3 @@ var methods = require('methods'); | ||
var req = popsicle.get(REMOTE_URL + '/echo'); | ||
t.plan(15); | ||
t.plan(13); | ||
return req | ||
@@ -66,5 +67,3 @@ .then(function (res) { | ||
t.equal(typeof res.statusType, 'function'); | ||
t.equal(typeof res.error, 'function'); | ||
t.equal(typeof res.toJSON, 'function'); | ||
t.equal(res.request, req); | ||
t.deepEqual(Object.keys(req.toJSON()), ['url', 'headers', 'body', 'options', 'timeout', 'method']); | ||
@@ -80,6 +79,5 @@ t.deepEqual(Object.keys(res.toJSON()), ['url', 'headers', 'rawHeaders', 'body', 'status', 'statusText']); | ||
var req = popsicle.get(REMOTE_URL + '/echo/header/x-example'); | ||
req.use(function (self) { | ||
self.before(function (req) { | ||
req.set('X-Example', 'foobar'); | ||
}); | ||
req.use(function (self, next) { | ||
self.set('X-Example', 'foobar'); | ||
return next(); | ||
}); | ||
@@ -482,6 +480,6 @@ return Promise.all([req, req.clone()]) | ||
if (!process.browser) { | ||
var fs = require('fs'); | ||
var concat = require('concat-stream'); | ||
var filename = require('path').join(__dirname, '../../scripts/server.js'); | ||
var filecontents = fs.readFileSync(filename, 'utf-8'); | ||
var fs_2 = require('fs'); | ||
var concat_1 = require('concat-stream'); | ||
var filename_1 = require('path').join(__dirname, '../../scripts/server.js'); | ||
var filecontents_1 = fs_2.readFileSync(filename_1, 'utf-8'); | ||
t.test('stream the response body', function (t) { | ||
@@ -495,3 +493,3 @@ return popsicle.request({ | ||
return new Promise(function (resolve) { | ||
res.body.pipe(concat(function (data) { | ||
res.body.pipe(concat_1(function (data) { | ||
t.equal(data.toString(), '{"username":"blakeembrey"}'); | ||
@@ -506,6 +504,6 @@ return resolve(); | ||
url: REMOTE_URL + '/echo', | ||
body: fs.createReadStream(filename) | ||
body: fs_2.createReadStream(filename_1) | ||
}) | ||
.then(function (res) { | ||
t.equal(res.body, filecontents); | ||
t.equal(res.body, filecontents_1); | ||
}); | ||
@@ -517,3 +515,3 @@ }); | ||
body: popsicle.form({ | ||
file: fs.createReadStream(filename) | ||
file: fs_2.createReadStream(filename_1) | ||
}) | ||
@@ -528,3 +526,3 @@ }) | ||
'', | ||
filecontents, | ||
filecontents_1, | ||
'--' + boundary + '--' | ||
@@ -537,7 +535,7 @@ ].join('\r\n')); | ||
url: REMOTE_URL + '/echo/zip', | ||
body: fs.createReadStream(filename) | ||
body: fs_2.createReadStream(filename_1) | ||
}) | ||
.then(function (res) { | ||
t.equal(res.get('Content-Encoding'), 'deflate'); | ||
t.equal(res.body, filecontents); | ||
t.equal(res.body, filecontents_1); | ||
}); | ||
@@ -548,3 +546,3 @@ }); | ||
url: REMOTE_URL + '/echo/zip', | ||
body: fs.createReadStream(filename), | ||
body: fs_2.createReadStream(filename_1), | ||
headers: { | ||
@@ -556,3 +554,3 @@ 'Accept-Encoding': 'gzip' | ||
t.equal(res.get('Content-Encoding'), 'gzip'); | ||
t.equal(res.body, filecontents); | ||
t.equal(res.body, filecontents_1); | ||
}); | ||
@@ -634,4 +632,5 @@ }); | ||
t.plan(1); | ||
req.use(function (self) { | ||
req.use(function (self, next) { | ||
t.equal(self, req); | ||
return next(); | ||
}); | ||
@@ -646,5 +645,6 @@ return req; | ||
t.plan(2); | ||
req.before(function (self) { | ||
req.use(function (self, next) { | ||
t.equal(self, req); | ||
t.notOk(req.response); | ||
t.equal(typeof next, 'function'); | ||
return next(); | ||
}); | ||
@@ -656,3 +656,3 @@ return req; | ||
t.plan(1); | ||
req.before(function () { | ||
req.use(function () { | ||
throw new Error('Hello world!'); | ||
@@ -666,5 +666,9 @@ }); | ||
t.test('accept a promise to delay the request', function (t) { | ||
var req = popsicle.request(REMOTE_URL + '/echo'); | ||
t.plan(1); | ||
req.before(function (self) { | ||
var req = popsicle.request({ | ||
url: REMOTE_URL + '/echo', | ||
method: 'POST', | ||
body: 'success' | ||
}); | ||
t.plan(2); | ||
req.use(function (self, next) { | ||
return new Promise(function (resolve) { | ||
@@ -675,5 +679,8 @@ setTimeout(function () { | ||
}, 10); | ||
}); | ||
}).then(next); | ||
}); | ||
return req; | ||
return req | ||
.then(function (res) { | ||
t.equal(res.body, 'success'); | ||
}); | ||
}); | ||
@@ -684,22 +691,8 @@ }); | ||
var req = popsicle.request(REMOTE_URL + '/echo'); | ||
t.plan(4); | ||
req.before(function () { | ||
t.notOk(req.response); | ||
}); | ||
req.after(function (response) { | ||
t.ok(response instanceof popsicle.Response); | ||
t.equal(req.response, response); | ||
t.equal(response.request, req); | ||
}); | ||
return req; | ||
}); | ||
t.test('accept a promise', function (t) { | ||
var req = popsicle.request(REMOTE_URL + '/echo'); | ||
t.plan(1); | ||
req.after(function (response) { | ||
return new Promise(function (resolve) { | ||
setTimeout(function () { | ||
t.equal(response, req.response); | ||
resolve(); | ||
}, 10); | ||
req.use(function (self, next) { | ||
return next() | ||
.then(function (res) { | ||
t.ok(res instanceof popsicle.Response); | ||
return res; | ||
}); | ||
@@ -710,41 +703,2 @@ }); | ||
}); | ||
test('always', function (t) { | ||
t.test('run all together in order', function (t) { | ||
var req = popsicle.request(REMOTE_URL + '/echo'); | ||
var before = false; | ||
var after = false; | ||
var always = false; | ||
t.plan(6); | ||
req.before(function () { | ||
before = true; | ||
t.notOk(after); | ||
t.notOk(always); | ||
}); | ||
req.after(function () { | ||
after = true; | ||
t.ok(before); | ||
t.notOk(always); | ||
}); | ||
req.always(function (request) { | ||
always = true; | ||
t.ok(before); | ||
t.ok(after); | ||
}); | ||
return req; | ||
}); | ||
t.test('run on error', function (t) { | ||
var req = popsicle.request(REMOTE_URL + '/echo'); | ||
t.plan(2); | ||
req.before(function () { | ||
throw new Error('Testing'); | ||
}); | ||
req.always(function (self) { | ||
t.equal(self, req); | ||
}); | ||
return req | ||
.catch(function (err) { | ||
t.equal(err.message, 'Testing'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -751,0 +705,0 @@ if (!process.browser) { |
{ | ||
"name": "popsicle", | ||
"version": "5.0.1", | ||
"version": "6.0.0", | ||
"description": "Simple HTTP requests for node and the browser", | ||
@@ -17,3 +17,4 @@ "main": "dist/common.js", | ||
"./dist/index.js": "./dist/browser.js", | ||
"./dist/plugins/index.js": "./dist/plugins/browser.js" | ||
"./dist/plugins/index.js": "./dist/plugins/browser.js", | ||
"./dist/plugins/is-host/index.js": "./dist/plugins/is-host/browser.js" | ||
}, | ||
@@ -63,7 +64,6 @@ "scripts": { | ||
"istanbul": "^0.4.0", | ||
"pre-commit": "^1.0.10", | ||
"tap-spec": "^4.1.1", | ||
"tape-run": "2.1.0", | ||
"typescript": "^1.7.3", | ||
"typings": "^0.6.7" | ||
"typescript": "^1.8.9", | ||
"typings": "^0.7.12" | ||
}, | ||
@@ -75,4 +75,6 @@ "dependencies": { | ||
"form-data": "^0.2.0", | ||
"koa-compose": "^3.1.0", | ||
"make-error-cause": "^1.0.1", | ||
"methods": "^1.1.1", | ||
"throwback": "^1.0.2", | ||
"tough-cookie": "^2.0.0", | ||
@@ -79,0 +81,0 @@ "xtend": "^4.0.0" |
@@ -8,3 +8,3 @@ # ![Popsicle](https://cdn.rawgit.com/blakeembrey/popsicle/master/logo.svg) | ||
**Popsicle** is the easiest way to make HTTP requests - offering a consistent, intuitive and light-weight API that works on node and the browser. | ||
> **Popsicle** is the easiest way to make HTTP requests - offering a consistent, intuitive and light-weight API that works on node and the browser. | ||
@@ -258,3 +258,3 @@ ```js | ||
If you live on the edge, try using it with generators (see [co](https://www.npmjs.com/package/co)) or ES7's `async`. | ||
If you live on the edge, try using it with generators (see [co](https://www.npmjs.com/package/co)) or ES7 `async`/`await`. | ||
@@ -335,8 +335,9 @@ ```js | ||
Plugins must be a function that accepts configuration and returns another function. For example, here's a basic URL prefix plugin. | ||
Plugins must be a function that accept config and return a middleware function. For example, here's a basic URL prefix plugin. | ||
```js | ||
function prefix (url) { | ||
return function (self) { | ||
request.url = url + req.url | ||
return function (self, next) { | ||
self.url = url + self.url | ||
return next() | ||
} | ||
@@ -352,10 +353,4 @@ } | ||
Popsicle also has a way modify the request and response lifecycle, if needed. Any registered function can return a promise to defer the request or response resolution. This makes plugins such as rate-limiting and response body concatenation possible. | ||
Middleware functions accept two arguments - the current request and a function to proceed to the next middleware function (a la Koa `2.x`). | ||
* **before(fn)** Register a function to run before the request is made | ||
* **after(fn)** Register a function to receive the response object | ||
* **always(fn)** Register a function that always runs on `resolve` or `reject` | ||
**Tip:** Use the lifecycle hooks (above) when you want re-use (E.g. re-use when the request is cloned or options re-used). | ||
#### Checking The Environment | ||
@@ -369,7 +364,7 @@ | ||
Creating a custom transportation layer is just a matter creating an object with `open`, `abort` and `use` options set. The open method should set any request information required between called as `request.raw`. Abort must abort the current request instance, while `open` must **always** resolve the promise. You can set `use` to an empty array if no plugins should be used by default. However, it's recommended you keep `use` set to the defaults, or as close as possible using your transport layer. | ||
Creating a custom transportation layer is just a matter creating an object with `open`, `abort` and `use` options set. The open method should set any request information required between called as `request._raw`. Abort must abort the current request instance, while `open` must **always** resolve to a promise. You can set `use` to an empty array if no plugins should be used by default. However, it's recommended you keep `use` set to the defaults, or as close as possible using your transport layer. | ||
## TypeScript | ||
This project is written using [TypeScript](https://github.com/Microsoft/TypeScript) and [typings](https://github.com/typings/typings). From version `1.3.1`, you can install the type definition using `typings`. | ||
This project is written using [TypeScript](https://github.com/Microsoft/TypeScript) and [typings](https://github.com/typings/typings). Since version `1.3.1`, you can install the type definition using `typings`. | ||
@@ -376,0 +371,0 @@ ``` |
{ | ||
"devDependencies": { | ||
"blue-tape": "github:typings/typed-blue-tape#a4e41a85d6f760e7c60088127968eae7d3a556fa" | ||
"blue-tape": "registry:npm/blue-tape#0.1.0+20160322235613" | ||
}, | ||
"ambientDependencies": { | ||
"node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#8cf8164641be73e8f1e652c2a5b967c7210b6729" | ||
"node": "registry:dt/node#4.0.0+20160330064709" | ||
}, | ||
"dependencies": { | ||
"any-promise": "github:typings/typed-any-promise#74ba6cf22149ff4de39c2338a9cb84f9ded6f042", | ||
"arrify": "github:typings/typed-arrify#32383d5fd3e6a8614abb6dba254a3aab07cd7424", | ||
"concat-stream": "github:typings/typed-concat-stream#099a88b57dcc9968246e8b1b3651e914a1a2c324", | ||
"form-data": "github:typings/typed-form-data#edc32200ec6065d98bfaa7ff9cfd104e17c5d3e4", | ||
"any-promise": "registry:npm/any-promise#1.0.0+20160211003958", | ||
"arrify": "registry:npm/arrify#1.0.0+20160211003958", | ||
"concat-stream": "registry:npm/concat-stream#1.0.0+20160211003958", | ||
"form-data": "registry:npm/form-data#1.0.0+20160211003958", | ||
"koa-compose": "registry:npm/koa-compose#3.0.0+20160404233803", | ||
"make-error-cause": "npm:make-error-cause", | ||
"methods": "github:typings/typed-methods#b902fa13683e95d54b2bb69188f68ea3525ec430", | ||
"tough-cookie": "github:typings/typed-tough-cookie#3e37dc2e6d448130d2fa4be1026e195ffda2b398", | ||
"xtend": "github:typings/typed-xtend#63cccadf3295b3c15561ee45617ac006edcca9e0" | ||
"methods": "registry:npm/methods#1.0.0+20160211003958", | ||
"throwback": "npm:throwback", | ||
"tough-cookie": "registry:npm/tough-cookie#2.2.0+20160211003958", | ||
"xtend": "registry:npm/xtend#4.0.0+20160211003958" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11
56
159318
10
2036
396
+ Addedkoa-compose@^3.1.0
+ Addedthrowback@^1.0.2
+ Addedkoa-compose@3.2.1(transitive)
+ Addedthrowback@1.1.1(transitive)