New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

electron-fetch

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

electron-fetch - npm Package Compare versions

Comparing version 1.2.1 to 1.3.0

index.d.ts

4

CHANGELOG.md

@@ -7,2 +7,6 @@

## V1.3.0
- Fix TypeScript typings & add tests so they cannot break again
- Updating dependencies
## V1.2.0

@@ -9,0 +13,0 @@ - Adding TypeScript typings (thanks @BurningEnlightenment)

799

lib/index.es.js

@@ -0,1 +1,3 @@

import * as https from 'https';
import { Z_SYNC_FLUSH, createGunzip, createInflate, createInflateRaw } from 'zlib';
import { convert } from 'encoding';

@@ -6,12 +8,8 @@ import Stream, { PassThrough } from 'stream';

import { format, parse, resolve } from 'url';
import * as https from 'https';
import { Z_SYNC_FLUSH, createGunzip, createInflate, createInflateRaw } from 'zlib';
// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
// (MIT licensed)
const BUFFER = Symbol('buffer');
const TYPE = Symbol('type');
const CLOSED = Symbol('closed');
class Blob {

@@ -25,9 +23,6 @@ constructor() {

});
this[CLOSED] = false;
this[TYPE] = '';
const blobParts = arguments[0];
const options = arguments[1];
const buffers = [];

@@ -38,5 +33,7 @@

const length = Number(a.length);
for (let i = 0; i < length; i++) {
const element = a[i];
let buffer;
if (element instanceof Buffer) {

@@ -53,2 +50,3 @@ buffer = element;

}
buffers.push(buffer);

@@ -59,4 +57,4 @@ }

this[BUFFER] = Buffer.concat(buffers);
let type = options && options.type !== undefined && String(options.type).toLowerCase();
let type = options && options.type !== undefined && String(options.type).toLowerCase();
if (type && !/[^\u0020-\u007E]/.test(type)) {

@@ -81,6 +79,6 @@ this[TYPE] = type;

const size = this.size;
const start = arguments[0];
const end = arguments[1];
let relativeStart, relativeEnd;
if (start === undefined) {

@@ -93,2 +91,3 @@ relativeStart = 0;

}
if (end === undefined) {

@@ -101,7 +100,9 @@ relativeEnd = size;

}
const span = Math.max(relativeEnd - relativeStart, 0);
const buffer = this[BUFFER];
const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
const blob = new Blob([], { type: arguments[2] });
const blob = new Blob([], {
type: arguments[2]
});
blob[BUFFER] = slicedBuffer;

@@ -115,4 +116,4 @@ blob[CLOSED] = this[CLOSED];

}
}
Object.defineProperty(Blob.prototype, Symbol.toStringTag, {

@@ -139,3 +140,2 @@ value: 'BlobPrototype',

*/
const netErrorMap = {

@@ -148,24 +148,25 @@ 'ERR_CONNECTION_REFUSED': 'ECONNREFUSED',

};
function FetchError(message, type, systemError) {
Error.call(this, message);
const regex = /^.*net::(.*)/;
if (regex.test(message)) {
let errorCode = regex.exec(message)[1];
// istanbul ignore else
let errorCode = regex.exec(message)[1]; // istanbul ignore else
if (netErrorMap.hasOwnProperty(errorCode)) errorCode = netErrorMap[errorCode];
systemError = { code: errorCode };
systemError = {
code: errorCode
};
}
this.message = message;
this.type = type;
this.type = type; // when err.type is `system`, err.code contains system error code
// when err.type is `system`, err.code contains system error code
if (systemError) {
this.code = this.errno = systemError.code;
}
} // hide custom error implementation details from end-users
// hide custom error implementation details from end-users
Error.captureStackTrace(this, this.constructor);
}
FetchError.prototype = Object.create(Error.prototype);

@@ -180,5 +181,3 @@ FetchError.prototype.constructor = FetchError;

*/
const DISTURBED = Symbol('disturbed');
/**

@@ -193,10 +192,7 @@ * Body class

*/
function Body(body) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$size = _ref.size;
let size = _ref$size === undefined ? 0 : _ref$size;
var _ref$timeout = _ref.timeout;
let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
function Body(body, {
size = 0,
timeout = 0
} = {}) {
if (body == null) {

@@ -210,2 +206,3 @@ // body is undefined or null

}
this.body = body;

@@ -216,3 +213,2 @@ this[DISTURBED] = false;

}
Body.prototype = {

@@ -229,5 +225,3 @@ get bodyUsed() {

arrayBuffer() {
return consumeBody.call(this).then(function (buf) {
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
});
return consumeBody.call(this).then(buf => buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
},

@@ -242,11 +236,8 @@

let ct = this.headers && this.headers.get('content-type') || '';
return consumeBody.call(this).then(function (buf) {
return Object.assign(
// Prevent copying
new Blob([], {
type: ct.toLowerCase()
}), {
[BUFFER]: buf
});
});
return consumeBody.call(this).then(buf => Object.assign( // Prevent copying
new Blob([], {
type: ct.toLowerCase()
}), {
[BUFFER]: buf
}));
},

@@ -260,5 +251,3 @@

json() {
return consumeBody.call(this).then(function (buffer) {
return JSON.parse(buffer.toString());
});
return consumeBody.call(this).then(buffer => JSON.parse(buffer.toString()));
},

@@ -272,5 +261,3 @@

text() {
return consumeBody.call(this).then(function (buffer) {
return buffer.toString();
});
return consumeBody.call(this).then(buffer => buffer.toString());
},

@@ -294,7 +281,3 @@

textConverted() {
var _this = this;
return consumeBody.call(this).then(function (buffer) {
return convertBody(buffer, _this.headers);
});
return consumeBody.call(this).then(buffer => convertBody(buffer, this.headers));
}

@@ -305,3 +288,16 @@

Body.mixIn = function (proto) {
for (const name of Object.getOwnPropertyNames(Body.prototype)) {
for (var _iterator = Object.getOwnPropertyNames(Body.prototype), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
const name = _ref;
// istanbul ignore else

@@ -314,3 +310,2 @@ if (!(name in proto)) {

};
/**

@@ -321,5 +316,5 @@ * Decode buffers into utf-8 string

*/
function consumeBody() {
var _this2 = this;
if (this[DISTURBED]) {

@@ -329,52 +324,48 @@ return Promise.reject(new Error(`body used already for: ${this.url}`));

this[DISTURBED] = true;
this[DISTURBED] = true; // body is null
// body is null
if (this.body === null) {
return Promise.resolve(Buffer.alloc(0));
}
} // body is string
// body is string
if (typeof this.body === 'string') {
return Promise.resolve(Buffer.from(this.body));
}
} // body is blob
// body is blob
if (this.body instanceof Blob) {
return Promise.resolve(this.body[BUFFER]);
}
} // body is buffer
// body is buffer
if (Buffer.isBuffer(this.body)) {
return Promise.resolve(this.body);
}
} // istanbul ignore if: should never happen
// istanbul ignore if: should never happen
if (!(this.body instanceof Stream)) {
return Promise.resolve(Buffer.alloc(0));
}
} // body is stream
// get ready to actually consume the body
// body is stream
// get ready to actually consume the body
const accum = [];
let accumBytes = 0;
let abort = false;
return new Promise((resolve$$1, reject) => {
let resTimeout; // allow timeout on slow response body
return new Promise(function (resolve$$1, reject) {
let resTimeout;
// allow timeout on slow response body
if (_this2.timeout) {
resTimeout = setTimeout(function () {
if (this.timeout) {
resTimeout = setTimeout(() => {
abort = true;
reject(new FetchError(`Response timeout while trying to fetch ${_this2.url} (over ${_this2.timeout}ms)`, 'body-timeout'));
}, _this2.timeout);
}
reject(new FetchError(`Response timeout while trying to fetch ${this.url} (over ${this.timeout}ms)`, 'body-timeout'));
}, this.timeout);
} // handle stream error, such as incorrect content-encoding
// handle stream error, such as incorrect content-encoding
_this2.body.on('error', function (err) {
reject(new FetchError(`Invalid response body while trying to fetch ${_this2.url}: ${err.message}`, 'system', err));
this.body.on('error', err => {
reject(new FetchError(`Invalid response body while trying to fetch ${this.url}: ${err.message}`, 'system', err));
});
_this2.body.on('data', function (chunk) {
this.body.on('data', chunk => {
if (abort || chunk === null) {

@@ -384,5 +375,5 @@ return;

if (_this2.size && accumBytes + chunk.length > _this2.size) {
if (this.size && accumBytes + chunk.length > this.size) {
abort = true;
reject(new FetchError(`content size at ${_this2.url} over limit: ${_this2.size}`, 'max-size'));
reject(new FetchError(`content size at ${this.url} over limit: ${this.size}`, 'max-size'));
return;

@@ -394,4 +385,3 @@ }

});
_this2.body.on('end', function () {
this.body.on('end', () => {
if (abort) {

@@ -406,3 +396,2 @@ return;

}
/**

@@ -416,21 +405,21 @@ * Detect buffer encoding and convert to target encoding

*/
function convertBody(buffer, headers) {
const ct = headers.get('content-type');
let charset = 'utf-8';
let res, str;
let res, str; // header
// header
if (ct) {
res = /charset=([^;]*)/i.exec(ct);
}
} // no charset in content type, peek at response body for at most 1024 bytes
// no charset in content type, peek at response body for at most 1024 bytes
str = buffer.slice(0, 1024).toString();
// html5
str = buffer.slice(0, 1024).toString(); // html5
if (!res && str) {
res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
}
} // html4
// html4
if (!res && str) {

@@ -442,24 +431,22 @@ res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);

}
}
} // xml
// xml
if (!res && str) {
res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
}
} // found charset
// found charset
if (res) {
charset = res.pop();
charset = res.pop(); // prevent decode issues when sites use incorrect encoding
// ref: https://hsivonen.fi/encoding-menu/
// prevent decode issues when sites use incorrect encoding
// ref: https://hsivonen.fi/encoding-menu/
if (charset === 'gb2312' || charset === 'gbk') {
charset = 'gb18030';
}
}
} // turn raw buffers into a single utf-8 buffer
// turn raw buffers into a single utf-8 buffer
return convert(buffer, 'UTF-8', charset).toString();
}
/**

@@ -471,13 +458,14 @@ * Clone body given Res/Req instance

*/
function clone(instance) {
let p1, p2;
let body = instance.body;
let body = instance.body; // don't allow cloning a used body
// don't allow cloning a used body
if (instance.bodyUsed) {
throw new Error('cannot clone body after it is used');
}
} // check that body is a stream and not form-data object
// note: we can't clone the form-data object without having it as a dependency
// check that body is a stream and not form-data object
// note: we can't clone the form-data object without having it as a dependency
if (body instanceof Stream && typeof body.getBoundary !== 'function') {

@@ -488,4 +476,4 @@ // tee instance body

body.pipe(p1);
body.pipe(p2);
// set instance body to teed body and return the other teed body
body.pipe(p2); // set instance body to teed body and return the other teed body
instance.body = p1;

@@ -497,3 +485,2 @@ body = p2;

}
/**

@@ -508,6 +495,5 @@ * Performs the operation "extract a `Content-Type` value from |object|" as

*/
function extractContentType(instance) {
const body = instance.body;
// istanbul ignore if: Currently, because of a guard in Request, body
const body = instance.body; // istanbul ignore if: Currently, because of a guard in Request, body
// can never be null. Included here for completeness.

@@ -536,8 +522,5 @@

}
function getTotalBytes(instance) {
const body = instance.body;
const body = instance.body; // istanbul ignore if: included for completion
// istanbul ignore if: included for completion
if (body === null) {

@@ -563,2 +546,3 @@ // body is null

}
return null;

@@ -571,7 +555,5 @@ } else {

}
function writeToStream(dest, instance) {
const body = instance.body;
if (body === null) {

@@ -597,2 +579,3 @@ // body is null

}
body.pipe(new PassThrough()) // I have to put a PassThrough because somehow, FormData streams are not eaten by electron/net

@@ -638,23 +621,31 @@ .pipe(dest);

}
if (ch >= 65 && ch <= 90) {
return true;
}
if (ch === 45) {
return true;
}
if (ch >= 48 && ch <= 57) {
return true;
}
if (ch === 34 || ch === 40 || ch === 41 || ch === 44) {
return false;
}
if (ch >= 33 && ch <= 46) {
return true;
}
if (ch === 124 || ch === 126) {
return true;
}
return false;
}
// istanbul ignore next
} // istanbul ignore next
function checkIsHttpToken(val) {

@@ -664,6 +655,9 @@ if (typeof val !== 'string' || val.length === 0) {

}
if (!isValidTokenChar(val.charCodeAt(0))) {
return false;
}
const len = val.length;
if (len > 1) {

@@ -673,2 +667,3 @@ if (!isValidTokenChar(val.charCodeAt(1))) {

}
if (len > 2) {

@@ -678,2 +673,3 @@ if (!isValidTokenChar(val.charCodeAt(2))) {

}
if (len > 3) {

@@ -683,2 +679,3 @@ if (!isValidTokenChar(val.charCodeAt(3))) {

}
for (let i = 4; i < len; i++) {

@@ -692,5 +689,5 @@ if (!isValidTokenChar(val.charCodeAt(i))) {

}
return true;
}
/**

@@ -707,27 +704,39 @@ * True if val contains an invalid field-vchar

// istanbul ignore next
function checkInvalidHeaderChar(val) {
val += '';
if (val.length < 1) {
return false;
}
let c = val.charCodeAt(0);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {
return true;
}
if (val.length < 2) {
return false;
}
c = val.charCodeAt(1);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {
return true;
}
if (val.length < 3) {
return false;
}
c = val.charCodeAt(2);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {
return true;
}
for (let i = 3; i < val.length; ++i) {
c = val.charCodeAt(i);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {

@@ -737,2 +746,3 @@ return true;

}
return false;

@@ -749,5 +759,7 @@ }

name += '';
if (!checkIsHttpToken(name)) {
throw new TypeError(`${name} is not a legal HTTP header name`);
}
return name.toLowerCase();

@@ -758,5 +770,7 @@ }

value += '';
if (checkInvalidHeaderChar(value)) {
throw new TypeError(`${value} is not a legal HTTP header value`);
}
return value;

@@ -772,30 +786,46 @@ }

*/
constructor() {
let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
constructor(init = undefined) {
this[MAP] = Object.create(null); // We don't worry about converting prop to ByteString here as append()
// will handle it.
this[MAP] = Object.create(null);
// We don't worry about converting prop to ByteString here as append()
// will handle it.
if (init == null) ; else if (typeof init === 'object') {
const method = init[Symbol.iterator];
if (method != null) {
if (typeof method !== 'function') {
throw new TypeError('Header pairs must be iterable');
}
} // sequence<sequence<ByteString>>
// Note: per spec we have to first exhaust the lists then process them
// sequence<sequence<ByteString>>
// Note: per spec we have to first exhaust the lists then process them
const pairs = [];
for (const pair of init) {
for (var _iterator = init, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
const pair = _ref;
if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
throw new TypeError('Each header pair must be iterable');
}
pairs.push(Array.from(pair));
}
for (const pair of pairs) {
for (var _i2 = 0; _i2 < pairs.length; _i2++) {
const pair = pairs[_i2];
if (pair.length !== 2) {
throw new TypeError('Each header pair must be a name/value tuple');
}
this.append(pair[0], pair[1]);

@@ -805,3 +835,6 @@ }

// record<ByteString, ByteString>
for (const key of Object.keys(init)) {
var _arr = Object.keys(init);
for (var _i3 = 0; _i3 < _arr.length; _i3++) {
const key = _arr[_i3];
const value = init[key];

@@ -822,3 +855,2 @@ this.append(key, value);

}
/**

@@ -830,4 +862,7 @@ * Return first header value given name

*/
get(name) {
const list = this[MAP][sanitizeName(name)];
if (!list) {

@@ -839,3 +874,2 @@ return null;

}
/**

@@ -847,12 +881,12 @@ * Iterate over all headers

*/
forEach(callback) {
let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
forEach(callback, thisArg = undefined) {
let pairs = getHeaderPairs(this);
let i = 0;
while (i < pairs.length) {
var _pairs$i = pairs[i];
const name = _pairs$i[0],
const _pairs$i = pairs[i],
name = _pairs$i[0],
value = _pairs$i[1];
callback.call(thisArg, value, name, this);

@@ -863,3 +897,2 @@ pairs = getHeaderPairs(this);

}
/**

@@ -871,6 +904,7 @@ * Overwrite header values given name

*/
set(name, value) {
this[MAP][sanitizeName(name)] = [sanitizeValue(value)];
}
/**

@@ -882,2 +916,4 @@ * Append a value onto existing header

*/
append(name, value) {

@@ -891,3 +927,2 @@ if (!this.has(name)) {

}
/**

@@ -899,6 +934,7 @@ * Check for header name existence

*/
has(name) {
return !!this[MAP][sanitizeName(name)];
}
/**

@@ -909,6 +945,7 @@ * Delete all header values given name

*/
delete(name) {
delete this[MAP][sanitizeName(name)];
}
/**

@@ -919,6 +956,7 @@ * Return raw headers (non-spec api)

*/
raw() {
return this[MAP];
}
/**

@@ -929,6 +967,7 @@ * Get an iterator on keys.

*/
keys() {
return createHeadersIterator(this, 'key');
}
/**

@@ -939,6 +978,7 @@ * Get an iterator on values.

*/
values() {
return createHeadersIterator(this, 'value');
}
/**

@@ -951,8 +991,10 @@ * Get an iterator on entries.

*/
[Symbol.iterator]() {
return createHeadersIterator(this, 'key+value');
}
}
Headers.prototype.entries = Headers.prototype[Symbol.iterator];
Object.defineProperty(Headers.prototype, Symbol.toStringTag, {

@@ -966,11 +1008,36 @@ value: 'HeadersPrototype',

function getHeaderPairs(headers, kind) {
if (kind === 'key') return Object.keys(headers[MAP]).sort().map(function (k) {
return [k];
});
if (kind === 'key') return Object.keys(headers[MAP]).sort().map(k => [k]);
const pairs = [];
for (let key of Object.keys(headers[MAP]).sort()) {
for (let value of headers[MAP][key]) {
for (var _iterator2 = Object.keys(headers[MAP]).sort(), _isArray2 = Array.isArray(_iterator2), _i4 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref2;
if (_isArray2) {
if (_i4 >= _iterator2.length) break;
_ref2 = _iterator2[_i4++];
} else {
_i4 = _iterator2.next();
if (_i4.done) break;
_ref2 = _i4.value;
}
let key = _ref2;
for (var _iterator3 = headers[MAP][key], _isArray3 = Array.isArray(_iterator3), _i5 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref3;
if (_isArray3) {
if (_i5 >= _iterator3.length) break;
_ref3 = _iterator3[_i5++];
} else {
_i5 = _iterator3.next();
if (_i5.done) break;
_ref3 = _i5.value;
}
let value = _ref3;
pairs.push([key, value]);
}
}
return pairs;

@@ -998,9 +1065,9 @@ }

var _INTERNAL = this[INTERNAL];
const target = _INTERNAL.target,
kind = _INTERNAL.kind,
index = _INTERNAL.index;
const _this$INTERNAL = this[INTERNAL],
target = _this$INTERNAL.target,
kind = _this$INTERNAL.kind,
index = _this$INTERNAL.index;
const values = getHeaderPairs(target, kind);
const len = values.length;
if (index >= len) {

@@ -1015,4 +1082,4 @@ return {

this[INTERNAL].index = index + 1;
let result;
let result;
if (kind === 'key') {

@@ -1031,4 +1098,4 @@ result = pair[0];

}
}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {

@@ -1046,3 +1113,2 @@ value: 'HeadersIterator',

*/
/**

@@ -1054,9 +1120,6 @@ * Response class

*/
class Response {
constructor() {
let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
constructor(body = null, opts = {}) {
Body.call(this, body, opts);
this.url = opts.url;

@@ -1067,3 +1130,2 @@ this.status = opts.status || 200;

this.useElectronNet = opts.useElectronNet;
Object.defineProperty(this, Symbol.toStringTag, {

@@ -1076,10 +1138,10 @@ value: 'Response',

}
/**
* Convenience property representing if the request ended normally
*/
get ok() {
return this.status >= 200 && this.status < 300;
}
/**

@@ -1090,2 +1152,4 @@ * Clone this response

*/
clone() {

@@ -1101,6 +1165,5 @@ return new Response(clone(this), {

}
}
Body.mixIn(Response.prototype);
Object.defineProperty(Response.prototype, Symbol.toStringTag, {

@@ -1118,5 +1181,3 @@ value: 'ResponsePrototype',

*/
const PARSED_URL = Symbol('url');
/**

@@ -1128,9 +1189,7 @@ * Request class

*/
class Request {
constructor(input) {
let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
constructor(input, init = {}) {
let parsedURL; // normalize input
let parsedURL;
// normalize input
if (!(input instanceof Request)) {

@@ -1146,2 +1205,3 @@ if (input && input.href) {

}
input = {};

@@ -1159,9 +1219,7 @@ } else {

let inputBody = init.body != null ? init.body : input instanceof Request && input.body !== null ? clone(input) : null;
Body.call(this, inputBody, {
timeout: init.timeout || input.timeout || 0,
size: init.size || input.size || 0
});
}); // fetch spec options
// fetch spec options
this.method = method.toUpperCase();

@@ -1172,5 +1230,4 @@ this.redirect = init.redirect || input.redirect || 'follow';

this.useElectronNet = init.useElectronNet !== undefined // have to do this instead of || because it can be set to false
? init.useElectronNet : input.useElectronNet;
? init.useElectronNet : input.useElectronNet; // istanbul ignore if
// istanbul ignore if
if (this.useElectronNet && !process.versions.electron) throw new Error('Cannot use Electron/net module on Node.js!');

@@ -1184,12 +1241,12 @@

const contentType = extractContentType(this);
if (contentType !== null && !this.headers.has('Content-Type')) {
this.headers.append('Content-Type', contentType);
}
}
} // server only options
// server only options
this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
this.counter = init.counter || input.counter || 0;
this.session = init.session || input.session;
this[PARSED_URL] = parsedURL;

@@ -1207,3 +1264,2 @@ Object.defineProperty(this, Symbol.toStringTag, {

}
/**

@@ -1214,9 +1270,10 @@ * Clone this request

*/
clone() {
return new Request(this);
}
}
Body.mixIn(Request.prototype);
Object.defineProperty(Request.prototype, Symbol.toStringTag, {

@@ -1228,13 +1285,11 @@ value: 'RequestPrototype',

});
function getNodeRequestOptions(request) {
const parsedURL = request[PARSED_URL];
const headers = new Headers(request.headers);
const headers = new Headers(request.headers); // fetch step 3
// fetch step 3
if (!headers.has('Accept')) {
headers.set('Accept', '*/*');
}
} // Basic fetch
// Basic fetch
if (!parsedURL.protocol || !parsedURL.hostname) {

@@ -1246,11 +1301,14 @@ throw new TypeError('Only absolute URLs are supported');

throw new TypeError('Only HTTP(S) protocols are supported');
}
} // HTTP-network-or-cache fetch steps 5-9
// HTTP-network-or-cache fetch steps 5-9
let contentLengthValue = null;
if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
contentLengthValue = '0';
}
if (request.body != null) {
const totalBytes = getTotalBytes(request);
if (typeof totalBytes === 'number') {

@@ -1260,2 +1318,3 @@ contentLengthValue = String(totalBytes);

}
if (contentLengthValue) {

@@ -1265,10 +1324,10 @@ headers.set('Content-Length', contentLengthValue);

request.chunkedEncoding = true;
}
} // HTTP-network-or-cache fetch step 12
// HTTP-network-or-cache fetch step 12
if (!headers.has('User-Agent')) {
headers.set('User-Agent', `electron-fetch/1.0 ${request.useElectronNet ? 'electron' : 'node'} (+https://github.com/arantes555/electron-fetch)`);
}
} // HTTP-network-or-cache fetch step 16
// HTTP-network-or-cache fetch step 16
headers.set('Accept-Encoding', 'gzip,deflate');

@@ -1278,7 +1337,6 @@

headers.set('Connection', 'close');
}
// HTTP-network fetch step 4
} // HTTP-network fetch step 4
// chunked encoding is handled by Node.js when not running in electron
return Object.assign({}, parsedURL, {

@@ -1295,12 +1353,9 @@ method: request.method,

*/
let electron; // istanbul ignore else
let electron;
// istanbul ignore else
if (process.versions['electron']) {
electron = require('electron');
}
const isReady = !electron || electron.app.isReady() ? Promise.resolve() : new Promise(function (resolve$$1) {
return electron.app.once('ready', resolve$$1);
});
const isReady = !electron || electron.app.isReady() ? Promise.resolve() : new Promise(resolve$$1 => electron.app.once('ready', resolve$$1));
/**

@@ -1313,176 +1368,199 @@ * Fetch function

*/
function fetch(url) {
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
function fetch(url, opts = {}) {
// wrap http.request into fetch
return isReady.then(function () {
return new Promise(function (resolve$$1, reject) {
// build request object
const request = new Request(url, opts);
const options = getNodeRequestOptions(request);
return isReady.then(() => new Promise((resolve$$1, reject) => {
// build request object
const request = new Request(url, opts);
const options = getNodeRequestOptions(request);
const send = request.useElectronNet ? electron.net.request : (options.protocol === 'https:' ? https : http).request; // http.request only support string as host header, this hack make custom host header possible
const send = request.useElectronNet ? electron.net.request : (options.protocol === 'https:' ? https : http).request;
if (options.headers.host) {
options.headers.host = options.headers.host[0];
} // send request
// http.request only support string as host header, this hack make custom host header possible
if (options.headers.host) {
options.headers.host = options.headers.host[0];
}
// send request
let headers;
if (request.useElectronNet) {
headers = options.headers;
delete options.headers;
options.session = opts.session || electron.session.defaultSession; // we have to use a persistent session here, because of https://github.com/electron/electron/issues/13587
}
const req = send(options);
if (request.useElectronNet) {
for (let headerName in headers) {
if (typeof headers[headerName] === 'string') req.setHeader(headerName, headers[headerName]);else {
for (let headerValue of headers[headerName]) {
req.setHeader(headerName, headerValue);
let headers;
if (request.useElectronNet) {
headers = options.headers;
delete options.headers;
options.session = opts.session || electron.session.defaultSession; // we have to use a persistent session here, because of https://github.com/electron/electron/issues/13587
}
const req = send(options);
if (request.useElectronNet) {
for (let headerName in headers) {
if (typeof headers[headerName] === 'string') req.setHeader(headerName, headers[headerName]);else {
for (var _iterator = headers[headerName], _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
let headerValue = _ref;
req.setHeader(headerName, headerValue);
}
}
}
let reqTimeout;
}
if (request.timeout) {
reqTimeout = setTimeout(function () {
req.abort();
reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
}, request.timeout);
}
let reqTimeout;
if (request.useElectronNet) {
// handle authenticating proxies
req.on('login', function (authInfo, callback) {
if (opts.user && opts.password) {
callback(opts.user, opts.password);
} else {
req.abort();
reject(new FetchError(`login event received from ${authInfo.host} but no credentials provided`, 'proxy', { code: 'PROXY_AUTH_FAILED' }));
}
});
}
if (request.timeout) {
reqTimeout = setTimeout(() => {
req.abort();
reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
}, request.timeout);
}
req.on('error', function (err) {
clearTimeout(reqTimeout);
reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
if (request.useElectronNet) {
// handle authenticating proxies
req.on('login', (authInfo, callback) => {
if (opts.user && opts.password) {
callback(opts.user, opts.password);
} else {
req.abort();
reject(new FetchError(`login event received from ${authInfo.host} but no credentials provided`, 'proxy', {
code: 'PROXY_AUTH_FAILED'
}));
}
});
}
req.on('response', function (res) {
clearTimeout(reqTimeout);
req.on('error', err => {
clearTimeout(reqTimeout);
reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
});
req.on('response', res => {
clearTimeout(reqTimeout); // handle redirect
// handle redirect
if (fetch.isRedirect(res.statusCode) && request.redirect !== 'manual') {
if (request.redirect === 'error') {
reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
return;
}
if (fetch.isRedirect(res.statusCode) && request.redirect !== 'manual') {
if (request.redirect === 'error') {
reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
return;
}
if (request.counter >= request.follow) {
reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
return;
}
if (request.counter >= request.follow) {
reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
return;
}
if (!res.headers.location) {
reject(new FetchError(`redirect location header missing at: ${request.url}`, 'invalid-redirect'));
return;
}
if (!res.headers.location) {
reject(new FetchError(`redirect location header missing at: ${request.url}`, 'invalid-redirect'));
return;
} // per fetch spec, for POST request with 301/302 response, or any request with 303 response, use GET when following redirect
// per fetch spec, for POST request with 301/302 response, or any request with 303 response, use GET when following redirect
if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
request.method = 'GET';
request.body = null;
request.headers.delete('content-length');
}
request.counter++;
resolve$$1(fetch(resolve(request.url, res.headers.location), request));
return;
if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
request.method = 'GET';
request.body = null;
request.headers.delete('content-length');
}
// normalize location header for manual redirect mode
const headers = new Headers();
for (const name of Object.keys(res.headers)) {
if (Array.isArray(res.headers[name])) {
for (const val of res.headers[name]) {
headers.append(name, val);
request.counter++;
resolve$$1(fetch(resolve(request.url, res.headers.location), request));
return;
} // normalize location header for manual redirect mode
const headers = new Headers();
var _arr = Object.keys(res.headers);
for (var _i2 = 0; _i2 < _arr.length; _i2++) {
const name = _arr[_i2];
if (Array.isArray(res.headers[name])) {
for (var _iterator2 = res.headers[name], _isArray2 = Array.isArray(_iterator2), _i3 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref2;
if (_isArray2) {
if (_i3 >= _iterator2.length) break;
_ref2 = _iterator2[_i3++];
} else {
_i3 = _iterator2.next();
if (_i3.done) break;
_ref2 = _i3.value;
}
} else {
headers.append(name, res.headers[name]);
const val = _ref2;
headers.append(name, val);
}
} else {
headers.append(name, res.headers[name]);
}
if (request.redirect === 'manual' && headers.has('location')) {
headers.set('location', resolve(request.url, headers.get('location')));
}
}
// prepare response
let body = new PassThrough();
res.on('error', function (err) {
return body.emit('error', err);
});
res.pipe(body);
const responseOptions = {
url: request.url,
status: res.statusCode,
statusText: res.statusMessage,
headers: headers,
size: request.size,
timeout: request.timeout,
useElectronNet: request.useElectronNet
if (request.redirect === 'manual' && headers.has('location')) {
headers.set('location', resolve(request.url, headers.get('location')));
} // prepare response
// HTTP-network fetch step 16.1.2
};const codings = headers.get('Content-Encoding');
// HTTP-network fetch step 16.1.3: handle content codings
let body = new PassThrough();
res.on('error', err => body.emit('error', err));
res.pipe(body);
const responseOptions = {
url: request.url,
status: res.statusCode,
statusText: res.statusMessage,
headers: headers,
size: request.size,
timeout: request.timeout,
useElectronNet: request.useElectronNet // HTTP-network fetch step 16.1.2
// in following scenarios we ignore compression support
// 1. running on Electron/net module (it manages it for us)
// 2. HEAD request
// 3. no Content-Encoding header
// 4. no content response (204)
// 5. content not modified response (304)
if (!request.useElectronNet && request.method !== 'HEAD' && codings !== null && res.statusCode !== 204 && res.statusCode !== 304) {
// Be less strict when decoding compressed responses, since sometimes
// servers send slightly invalid responses that are still accepted
// by common browsers.
// Always using Z_SYNC_FLUSH is what cURL does.
const zlibOptions = {
flush: Z_SYNC_FLUSH,
finishFlush: Z_SYNC_FLUSH
};
};
const codings = headers.get('Content-Encoding'); // HTTP-network fetch step 16.1.3: handle content codings
// in following scenarios we ignore compression support
// 1. running on Electron/net module (it manages it for us)
// 2. HEAD request
// 3. no Content-Encoding header
// 4. no content response (204)
// 5. content not modified response (304)
if (codings === 'gzip' || codings === 'x-gzip') {
// for gzip
body = body.pipe(createGunzip(zlibOptions));
} else if (codings === 'deflate' || codings === 'x-deflate') {
// for deflate
// handle the infamous raw deflate response from old servers
// a hack for old IIS and Apache servers
const raw = res.pipe(new PassThrough());
return raw.once('data', function (chunk) {
// see http://stackoverflow.com/questions/37519828
if ((chunk[0] & 0x0F) === 0x08) {
body = body.pipe(createInflate(zlibOptions));
} else {
body = body.pipe(createInflateRaw(zlibOptions));
}
const response = new Response(body, responseOptions);
resolve$$1(response);
});
}
if (!request.useElectronNet && request.method !== 'HEAD' && codings !== null && res.statusCode !== 204 && res.statusCode !== 304) {
// Be less strict when decoding compressed responses, since sometimes
// servers send slightly invalid responses that are still accepted
// by common browsers.
// Always using Z_SYNC_FLUSH is what cURL does.
const zlibOptions = {
flush: Z_SYNC_FLUSH,
finishFlush: Z_SYNC_FLUSH
};
if (codings === 'gzip' || codings === 'x-gzip') {
// for gzip
body = body.pipe(createGunzip(zlibOptions));
} else if (codings === 'deflate' || codings === 'x-deflate') {
// for deflate
// handle the infamous raw deflate response from old servers
// a hack for old IIS and Apache servers
const raw = res.pipe(new PassThrough());
return raw.once('data', chunk => {
// see http://stackoverflow.com/questions/37519828
if ((chunk[0] & 0x0F) === 0x08) {
body = body.pipe(createInflate(zlibOptions));
} else {
body = body.pipe(createInflateRaw(zlibOptions));
}
const response = new Response(body, responseOptions);
resolve$$1(response);
});
}
}
const response = new Response(body, responseOptions);
resolve$$1(response);
});
writeToStream(req, request);
const response = new Response(body, responseOptions);
resolve$$1(response);
});
});
writeToStream(req, request);
}));
}
/**

@@ -1494,7 +1572,6 @@ * Redirect code matching

*/
fetch.isRedirect = function (code) {
return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
};
fetch.isRedirect = code => code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
export default fetch;
export { Headers, Request, Response, FetchError };

@@ -7,2 +7,4 @@ 'use strict';

var https = require('https');
var zlib = require('zlib');
var encoding = require('encoding');

@@ -13,12 +15,8 @@ var Stream = require('stream');

var url = require('url');
var https = require('https');
var zlib = require('zlib');
// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
// (MIT licensed)
const BUFFER = Symbol('buffer');
const TYPE = Symbol('type');
const CLOSED = Symbol('closed');
class Blob {

@@ -32,9 +30,6 @@ constructor() {

});
this[CLOSED] = false;
this[TYPE] = '';
const blobParts = arguments[0];
const options = arguments[1];
const buffers = [];

@@ -45,5 +40,7 @@

const length = Number(a.length);
for (let i = 0; i < length; i++) {
const element = a[i];
let buffer;
if (element instanceof Buffer) {

@@ -60,2 +57,3 @@ buffer = element;

}
buffers.push(buffer);

@@ -66,4 +64,4 @@ }

this[BUFFER] = Buffer.concat(buffers);
let type = options && options.type !== undefined && String(options.type).toLowerCase();
let type = options && options.type !== undefined && String(options.type).toLowerCase();
if (type && !/[^\u0020-\u007E]/.test(type)) {

@@ -88,6 +86,6 @@ this[TYPE] = type;

const size = this.size;
const start = arguments[0];
const end = arguments[1];
let relativeStart, relativeEnd;
if (start === undefined) {

@@ -100,2 +98,3 @@ relativeStart = 0;

}
if (end === undefined) {

@@ -108,7 +107,9 @@ relativeEnd = size;

}
const span = Math.max(relativeEnd - relativeStart, 0);
const buffer = this[BUFFER];
const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
const blob = new Blob([], { type: arguments[2] });
const blob = new Blob([], {
type: arguments[2]
});
blob[BUFFER] = slicedBuffer;

@@ -122,4 +123,4 @@ blob[CLOSED] = this[CLOSED];

}
}
Object.defineProperty(Blob.prototype, Symbol.toStringTag, {

@@ -146,3 +147,2 @@ value: 'BlobPrototype',

*/
const netErrorMap = {

@@ -155,24 +155,25 @@ 'ERR_CONNECTION_REFUSED': 'ECONNREFUSED',

};
function FetchError(message, type, systemError) {
Error.call(this, message);
const regex = /^.*net::(.*)/;
if (regex.test(message)) {
let errorCode = regex.exec(message)[1];
// istanbul ignore else
let errorCode = regex.exec(message)[1]; // istanbul ignore else
if (netErrorMap.hasOwnProperty(errorCode)) errorCode = netErrorMap[errorCode];
systemError = { code: errorCode };
systemError = {
code: errorCode
};
}
this.message = message;
this.type = type;
this.type = type; // when err.type is `system`, err.code contains system error code
// when err.type is `system`, err.code contains system error code
if (systemError) {
this.code = this.errno = systemError.code;
}
} // hide custom error implementation details from end-users
// hide custom error implementation details from end-users
Error.captureStackTrace(this, this.constructor);
}
FetchError.prototype = Object.create(Error.prototype);

@@ -187,5 +188,3 @@ FetchError.prototype.constructor = FetchError;

*/
const DISTURBED = Symbol('disturbed');
/**

@@ -200,10 +199,7 @@ * Body class

*/
function Body(body) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$size = _ref.size;
let size = _ref$size === undefined ? 0 : _ref$size;
var _ref$timeout = _ref.timeout;
let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
function Body(body, {
size = 0,
timeout = 0
} = {}) {
if (body == null) {

@@ -217,2 +213,3 @@ // body is undefined or null

}
this.body = body;

@@ -223,3 +220,2 @@ this[DISTURBED] = false;

}
Body.prototype = {

@@ -236,5 +232,3 @@ get bodyUsed() {

arrayBuffer() {
return consumeBody.call(this).then(function (buf) {
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
});
return consumeBody.call(this).then(buf => buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
},

@@ -249,11 +243,8 @@

let ct = this.headers && this.headers.get('content-type') || '';
return consumeBody.call(this).then(function (buf) {
return Object.assign(
// Prevent copying
new Blob([], {
type: ct.toLowerCase()
}), {
[BUFFER]: buf
});
});
return consumeBody.call(this).then(buf => Object.assign( // Prevent copying
new Blob([], {
type: ct.toLowerCase()
}), {
[BUFFER]: buf
}));
},

@@ -267,5 +258,3 @@

json() {
return consumeBody.call(this).then(function (buffer) {
return JSON.parse(buffer.toString());
});
return consumeBody.call(this).then(buffer => JSON.parse(buffer.toString()));
},

@@ -279,5 +268,3 @@

text() {
return consumeBody.call(this).then(function (buffer) {
return buffer.toString();
});
return consumeBody.call(this).then(buffer => buffer.toString());
},

@@ -301,7 +288,3 @@

textConverted() {
var _this = this;
return consumeBody.call(this).then(function (buffer) {
return convertBody(buffer, _this.headers);
});
return consumeBody.call(this).then(buffer => convertBody(buffer, this.headers));
}

@@ -312,3 +295,16 @@

Body.mixIn = function (proto) {
for (const name of Object.getOwnPropertyNames(Body.prototype)) {
for (var _iterator = Object.getOwnPropertyNames(Body.prototype), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
const name = _ref;
// istanbul ignore else

@@ -321,3 +317,2 @@ if (!(name in proto)) {

};
/**

@@ -328,5 +323,5 @@ * Decode buffers into utf-8 string

*/
function consumeBody() {
var _this2 = this;
if (this[DISTURBED]) {

@@ -336,52 +331,48 @@ return Promise.reject(new Error(`body used already for: ${this.url}`));

this[DISTURBED] = true;
this[DISTURBED] = true; // body is null
// body is null
if (this.body === null) {
return Promise.resolve(Buffer.alloc(0));
}
} // body is string
// body is string
if (typeof this.body === 'string') {
return Promise.resolve(Buffer.from(this.body));
}
} // body is blob
// body is blob
if (this.body instanceof Blob) {
return Promise.resolve(this.body[BUFFER]);
}
} // body is buffer
// body is buffer
if (Buffer.isBuffer(this.body)) {
return Promise.resolve(this.body);
}
} // istanbul ignore if: should never happen
// istanbul ignore if: should never happen
if (!(this.body instanceof Stream__default)) {
return Promise.resolve(Buffer.alloc(0));
}
} // body is stream
// get ready to actually consume the body
// body is stream
// get ready to actually consume the body
const accum = [];
let accumBytes = 0;
let abort = false;
return new Promise((resolve, reject) => {
let resTimeout; // allow timeout on slow response body
return new Promise(function (resolve, reject) {
let resTimeout;
// allow timeout on slow response body
if (_this2.timeout) {
resTimeout = setTimeout(function () {
if (this.timeout) {
resTimeout = setTimeout(() => {
abort = true;
reject(new FetchError(`Response timeout while trying to fetch ${_this2.url} (over ${_this2.timeout}ms)`, 'body-timeout'));
}, _this2.timeout);
}
reject(new FetchError(`Response timeout while trying to fetch ${this.url} (over ${this.timeout}ms)`, 'body-timeout'));
}, this.timeout);
} // handle stream error, such as incorrect content-encoding
// handle stream error, such as incorrect content-encoding
_this2.body.on('error', function (err) {
reject(new FetchError(`Invalid response body while trying to fetch ${_this2.url}: ${err.message}`, 'system', err));
this.body.on('error', err => {
reject(new FetchError(`Invalid response body while trying to fetch ${this.url}: ${err.message}`, 'system', err));
});
_this2.body.on('data', function (chunk) {
this.body.on('data', chunk => {
if (abort || chunk === null) {

@@ -391,5 +382,5 @@ return;

if (_this2.size && accumBytes + chunk.length > _this2.size) {
if (this.size && accumBytes + chunk.length > this.size) {
abort = true;
reject(new FetchError(`content size at ${_this2.url} over limit: ${_this2.size}`, 'max-size'));
reject(new FetchError(`content size at ${this.url} over limit: ${this.size}`, 'max-size'));
return;

@@ -401,4 +392,3 @@ }

});
_this2.body.on('end', function () {
this.body.on('end', () => {
if (abort) {

@@ -413,3 +403,2 @@ return;

}
/**

@@ -423,21 +412,21 @@ * Detect buffer encoding and convert to target encoding

*/
function convertBody(buffer, headers) {
const ct = headers.get('content-type');
let charset = 'utf-8';
let res, str;
let res, str; // header
// header
if (ct) {
res = /charset=([^;]*)/i.exec(ct);
}
} // no charset in content type, peek at response body for at most 1024 bytes
// no charset in content type, peek at response body for at most 1024 bytes
str = buffer.slice(0, 1024).toString();
// html5
str = buffer.slice(0, 1024).toString(); // html5
if (!res && str) {
res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
}
} // html4
// html4
if (!res && str) {

@@ -449,24 +438,22 @@ res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);

}
}
} // xml
// xml
if (!res && str) {
res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
}
} // found charset
// found charset
if (res) {
charset = res.pop();
charset = res.pop(); // prevent decode issues when sites use incorrect encoding
// ref: https://hsivonen.fi/encoding-menu/
// prevent decode issues when sites use incorrect encoding
// ref: https://hsivonen.fi/encoding-menu/
if (charset === 'gb2312' || charset === 'gbk') {
charset = 'gb18030';
}
}
} // turn raw buffers into a single utf-8 buffer
// turn raw buffers into a single utf-8 buffer
return encoding.convert(buffer, 'UTF-8', charset).toString();
}
/**

@@ -478,13 +465,14 @@ * Clone body given Res/Req instance

*/
function clone(instance) {
let p1, p2;
let body = instance.body;
let body = instance.body; // don't allow cloning a used body
// don't allow cloning a used body
if (instance.bodyUsed) {
throw new Error('cannot clone body after it is used');
}
} // check that body is a stream and not form-data object
// note: we can't clone the form-data object without having it as a dependency
// check that body is a stream and not form-data object
// note: we can't clone the form-data object without having it as a dependency
if (body instanceof Stream__default && typeof body.getBoundary !== 'function') {

@@ -495,4 +483,4 @@ // tee instance body

body.pipe(p1);
body.pipe(p2);
// set instance body to teed body and return the other teed body
body.pipe(p2); // set instance body to teed body and return the other teed body
instance.body = p1;

@@ -504,3 +492,2 @@ body = p2;

}
/**

@@ -515,6 +502,5 @@ * Performs the operation "extract a `Content-Type` value from |object|" as

*/
function extractContentType(instance) {
const body = instance.body;
// istanbul ignore if: Currently, because of a guard in Request, body
const body = instance.body; // istanbul ignore if: Currently, because of a guard in Request, body
// can never be null. Included here for completeness.

@@ -543,8 +529,5 @@

}
function getTotalBytes(instance) {
const body = instance.body;
const body = instance.body; // istanbul ignore if: included for completion
// istanbul ignore if: included for completion
if (body === null) {

@@ -570,2 +553,3 @@ // body is null

}
return null;

@@ -578,7 +562,5 @@ } else {

}
function writeToStream(dest, instance) {
const body = instance.body;
if (body === null) {

@@ -604,2 +586,3 @@ // body is null

}
body.pipe(new Stream.PassThrough()) // I have to put a PassThrough because somehow, FormData streams are not eaten by electron/net

@@ -645,23 +628,31 @@ .pipe(dest);

}
if (ch >= 65 && ch <= 90) {
return true;
}
if (ch === 45) {
return true;
}
if (ch >= 48 && ch <= 57) {
return true;
}
if (ch === 34 || ch === 40 || ch === 41 || ch === 44) {
return false;
}
if (ch >= 33 && ch <= 46) {
return true;
}
if (ch === 124 || ch === 126) {
return true;
}
return false;
}
// istanbul ignore next
} // istanbul ignore next
function checkIsHttpToken(val) {

@@ -671,6 +662,9 @@ if (typeof val !== 'string' || val.length === 0) {

}
if (!isValidTokenChar(val.charCodeAt(0))) {
return false;
}
const len = val.length;
if (len > 1) {

@@ -680,2 +674,3 @@ if (!isValidTokenChar(val.charCodeAt(1))) {

}
if (len > 2) {

@@ -685,2 +680,3 @@ if (!isValidTokenChar(val.charCodeAt(2))) {

}
if (len > 3) {

@@ -690,2 +686,3 @@ if (!isValidTokenChar(val.charCodeAt(3))) {

}
for (let i = 4; i < len; i++) {

@@ -699,5 +696,5 @@ if (!isValidTokenChar(val.charCodeAt(i))) {

}
return true;
}
/**

@@ -714,27 +711,39 @@ * True if val contains an invalid field-vchar

// istanbul ignore next
function checkInvalidHeaderChar(val) {
val += '';
if (val.length < 1) {
return false;
}
let c = val.charCodeAt(0);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {
return true;
}
if (val.length < 2) {
return false;
}
c = val.charCodeAt(1);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {
return true;
}
if (val.length < 3) {
return false;
}
c = val.charCodeAt(2);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {
return true;
}
for (let i = 3; i < val.length; ++i) {
c = val.charCodeAt(i);
if (c <= 31 && c !== 9 || c > 255 || c === 127) {

@@ -744,2 +753,3 @@ return true;

}
return false;

@@ -756,5 +766,7 @@ }

name += '';
if (!checkIsHttpToken(name)) {
throw new TypeError(`${name} is not a legal HTTP header name`);
}
return name.toLowerCase();

@@ -765,5 +777,7 @@ }

value += '';
if (checkInvalidHeaderChar(value)) {
throw new TypeError(`${value} is not a legal HTTP header value`);
}
return value;

@@ -779,30 +793,46 @@ }

*/
constructor() {
let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
constructor(init = undefined) {
this[MAP] = Object.create(null); // We don't worry about converting prop to ByteString here as append()
// will handle it.
this[MAP] = Object.create(null);
// We don't worry about converting prop to ByteString here as append()
// will handle it.
if (init == null) ; else if (typeof init === 'object') {
const method = init[Symbol.iterator];
if (method != null) {
if (typeof method !== 'function') {
throw new TypeError('Header pairs must be iterable');
}
} // sequence<sequence<ByteString>>
// Note: per spec we have to first exhaust the lists then process them
// sequence<sequence<ByteString>>
// Note: per spec we have to first exhaust the lists then process them
const pairs = [];
for (const pair of init) {
for (var _iterator = init, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
const pair = _ref;
if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
throw new TypeError('Each header pair must be iterable');
}
pairs.push(Array.from(pair));
}
for (const pair of pairs) {
for (var _i2 = 0; _i2 < pairs.length; _i2++) {
const pair = pairs[_i2];
if (pair.length !== 2) {
throw new TypeError('Each header pair must be a name/value tuple');
}
this.append(pair[0], pair[1]);

@@ -812,3 +842,6 @@ }

// record<ByteString, ByteString>
for (const key of Object.keys(init)) {
var _arr = Object.keys(init);
for (var _i3 = 0; _i3 < _arr.length; _i3++) {
const key = _arr[_i3];
const value = init[key];

@@ -829,3 +862,2 @@ this.append(key, value);

}
/**

@@ -837,4 +869,7 @@ * Return first header value given name

*/
get(name) {
const list = this[MAP][sanitizeName(name)];
if (!list) {

@@ -846,3 +881,2 @@ return null;

}
/**

@@ -854,12 +888,12 @@ * Iterate over all headers

*/
forEach(callback) {
let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
forEach(callback, thisArg = undefined) {
let pairs = getHeaderPairs(this);
let i = 0;
while (i < pairs.length) {
var _pairs$i = pairs[i];
const name = _pairs$i[0],
const _pairs$i = pairs[i],
name = _pairs$i[0],
value = _pairs$i[1];
callback.call(thisArg, value, name, this);

@@ -870,3 +904,2 @@ pairs = getHeaderPairs(this);

}
/**

@@ -878,6 +911,7 @@ * Overwrite header values given name

*/
set(name, value) {
this[MAP][sanitizeName(name)] = [sanitizeValue(value)];
}
/**

@@ -889,2 +923,4 @@ * Append a value onto existing header

*/
append(name, value) {

@@ -898,3 +934,2 @@ if (!this.has(name)) {

}
/**

@@ -906,6 +941,7 @@ * Check for header name existence

*/
has(name) {
return !!this[MAP][sanitizeName(name)];
}
/**

@@ -916,6 +952,7 @@ * Delete all header values given name

*/
delete(name) {
delete this[MAP][sanitizeName(name)];
}
/**

@@ -926,6 +963,7 @@ * Return raw headers (non-spec api)

*/
raw() {
return this[MAP];
}
/**

@@ -936,6 +974,7 @@ * Get an iterator on keys.

*/
keys() {
return createHeadersIterator(this, 'key');
}
/**

@@ -946,6 +985,7 @@ * Get an iterator on values.

*/
values() {
return createHeadersIterator(this, 'value');
}
/**

@@ -958,8 +998,10 @@ * Get an iterator on entries.

*/
[Symbol.iterator]() {
return createHeadersIterator(this, 'key+value');
}
}
Headers.prototype.entries = Headers.prototype[Symbol.iterator];
Object.defineProperty(Headers.prototype, Symbol.toStringTag, {

@@ -973,11 +1015,36 @@ value: 'HeadersPrototype',

function getHeaderPairs(headers, kind) {
if (kind === 'key') return Object.keys(headers[MAP]).sort().map(function (k) {
return [k];
});
if (kind === 'key') return Object.keys(headers[MAP]).sort().map(k => [k]);
const pairs = [];
for (let key of Object.keys(headers[MAP]).sort()) {
for (let value of headers[MAP][key]) {
for (var _iterator2 = Object.keys(headers[MAP]).sort(), _isArray2 = Array.isArray(_iterator2), _i4 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref2;
if (_isArray2) {
if (_i4 >= _iterator2.length) break;
_ref2 = _iterator2[_i4++];
} else {
_i4 = _iterator2.next();
if (_i4.done) break;
_ref2 = _i4.value;
}
let key = _ref2;
for (var _iterator3 = headers[MAP][key], _isArray3 = Array.isArray(_iterator3), _i5 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref3;
if (_isArray3) {
if (_i5 >= _iterator3.length) break;
_ref3 = _iterator3[_i5++];
} else {
_i5 = _iterator3.next();
if (_i5.done) break;
_ref3 = _i5.value;
}
let value = _ref3;
pairs.push([key, value]);
}
}
return pairs;

@@ -1005,9 +1072,9 @@ }

var _INTERNAL = this[INTERNAL];
const target = _INTERNAL.target,
kind = _INTERNAL.kind,
index = _INTERNAL.index;
const _this$INTERNAL = this[INTERNAL],
target = _this$INTERNAL.target,
kind = _this$INTERNAL.kind,
index = _this$INTERNAL.index;
const values = getHeaderPairs(target, kind);
const len = values.length;
if (index >= len) {

@@ -1022,4 +1089,4 @@ return {

this[INTERNAL].index = index + 1;
let result;
let result;
if (kind === 'key') {

@@ -1038,4 +1105,4 @@ result = pair[0];

}
}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {

@@ -1053,3 +1120,2 @@ value: 'HeadersIterator',

*/
/**

@@ -1061,9 +1127,6 @@ * Response class

*/
class Response {
constructor() {
let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
constructor(body = null, opts = {}) {
Body.call(this, body, opts);
this.url = opts.url;

@@ -1074,3 +1137,2 @@ this.status = opts.status || 200;

this.useElectronNet = opts.useElectronNet;
Object.defineProperty(this, Symbol.toStringTag, {

@@ -1083,10 +1145,10 @@ value: 'Response',

}
/**
* Convenience property representing if the request ended normally
*/
get ok() {
return this.status >= 200 && this.status < 300;
}
/**

@@ -1097,2 +1159,4 @@ * Clone this response

*/
clone() {

@@ -1108,6 +1172,5 @@ return new Response(clone(this), {

}
}
Body.mixIn(Response.prototype);
Object.defineProperty(Response.prototype, Symbol.toStringTag, {

@@ -1125,5 +1188,3 @@ value: 'ResponsePrototype',

*/
const PARSED_URL = Symbol('url');
/**

@@ -1135,9 +1196,7 @@ * Request class

*/
class Request {
constructor(input) {
let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
constructor(input, init = {}) {
let parsedURL; // normalize input
let parsedURL;
// normalize input
if (!(input instanceof Request)) {

@@ -1153,2 +1212,3 @@ if (input && input.href) {

}
input = {};

@@ -1166,9 +1226,7 @@ } else {

let inputBody = init.body != null ? init.body : input instanceof Request && input.body !== null ? clone(input) : null;
Body.call(this, inputBody, {
timeout: init.timeout || input.timeout || 0,
size: init.size || input.size || 0
});
}); // fetch spec options
// fetch spec options
this.method = method.toUpperCase();

@@ -1179,5 +1237,4 @@ this.redirect = init.redirect || input.redirect || 'follow';

this.useElectronNet = init.useElectronNet !== undefined // have to do this instead of || because it can be set to false
? init.useElectronNet : input.useElectronNet;
? init.useElectronNet : input.useElectronNet; // istanbul ignore if
// istanbul ignore if
if (this.useElectronNet && !process.versions.electron) throw new Error('Cannot use Electron/net module on Node.js!');

@@ -1191,12 +1248,12 @@

const contentType = extractContentType(this);
if (contentType !== null && !this.headers.has('Content-Type')) {
this.headers.append('Content-Type', contentType);
}
}
} // server only options
// server only options
this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
this.counter = init.counter || input.counter || 0;
this.session = init.session || input.session;
this[PARSED_URL] = parsedURL;

@@ -1214,3 +1271,2 @@ Object.defineProperty(this, Symbol.toStringTag, {

}
/**

@@ -1221,9 +1277,10 @@ * Clone this request

*/
clone() {
return new Request(this);
}
}
Body.mixIn(Request.prototype);
Object.defineProperty(Request.prototype, Symbol.toStringTag, {

@@ -1235,13 +1292,11 @@ value: 'RequestPrototype',

});
function getNodeRequestOptions(request) {
const parsedURL = request[PARSED_URL];
const headers = new Headers(request.headers);
const headers = new Headers(request.headers); // fetch step 3
// fetch step 3
if (!headers.has('Accept')) {
headers.set('Accept', '*/*');
}
} // Basic fetch
// Basic fetch
if (!parsedURL.protocol || !parsedURL.hostname) {

@@ -1253,11 +1308,14 @@ throw new TypeError('Only absolute URLs are supported');

throw new TypeError('Only HTTP(S) protocols are supported');
}
} // HTTP-network-or-cache fetch steps 5-9
// HTTP-network-or-cache fetch steps 5-9
let contentLengthValue = null;
if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
contentLengthValue = '0';
}
if (request.body != null) {
const totalBytes = getTotalBytes(request);
if (typeof totalBytes === 'number') {

@@ -1267,2 +1325,3 @@ contentLengthValue = String(totalBytes);

}
if (contentLengthValue) {

@@ -1272,10 +1331,10 @@ headers.set('Content-Length', contentLengthValue);

request.chunkedEncoding = true;
}
} // HTTP-network-or-cache fetch step 12
// HTTP-network-or-cache fetch step 12
if (!headers.has('User-Agent')) {
headers.set('User-Agent', `electron-fetch/1.0 ${request.useElectronNet ? 'electron' : 'node'} (+https://github.com/arantes555/electron-fetch)`);
}
} // HTTP-network-or-cache fetch step 16
// HTTP-network-or-cache fetch step 16
headers.set('Accept-Encoding', 'gzip,deflate');

@@ -1285,7 +1344,6 @@

headers.set('Connection', 'close');
}
// HTTP-network fetch step 4
} // HTTP-network fetch step 4
// chunked encoding is handled by Node.js when not running in electron
return Object.assign({}, parsedURL, {

@@ -1302,12 +1360,9 @@ method: request.method,

*/
let electron; // istanbul ignore else
let electron;
// istanbul ignore else
if (process.versions['electron']) {
electron = require('electron');
}
const isReady = !electron || electron.app.isReady() ? Promise.resolve() : new Promise(function (resolve) {
return electron.app.once('ready', resolve);
});
const isReady = !electron || electron.app.isReady() ? Promise.resolve() : new Promise(resolve => electron.app.once('ready', resolve));
/**

@@ -1320,176 +1375,199 @@ * Fetch function

*/
function fetch(url$$1) {
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
function fetch(url$$1, opts = {}) {
// wrap http.request into fetch
return isReady.then(function () {
return new Promise(function (resolve, reject) {
// build request object
const request = new Request(url$$1, opts);
const options = getNodeRequestOptions(request);
return isReady.then(() => new Promise((resolve, reject) => {
// build request object
const request = new Request(url$$1, opts);
const options = getNodeRequestOptions(request);
const send = request.useElectronNet ? electron.net.request : (options.protocol === 'https:' ? https : http).request; // http.request only support string as host header, this hack make custom host header possible
const send = request.useElectronNet ? electron.net.request : (options.protocol === 'https:' ? https : http).request;
if (options.headers.host) {
options.headers.host = options.headers.host[0];
} // send request
// http.request only support string as host header, this hack make custom host header possible
if (options.headers.host) {
options.headers.host = options.headers.host[0];
}
// send request
let headers;
if (request.useElectronNet) {
headers = options.headers;
delete options.headers;
options.session = opts.session || electron.session.defaultSession; // we have to use a persistent session here, because of https://github.com/electron/electron/issues/13587
}
const req = send(options);
if (request.useElectronNet) {
for (let headerName in headers) {
if (typeof headers[headerName] === 'string') req.setHeader(headerName, headers[headerName]);else {
for (let headerValue of headers[headerName]) {
req.setHeader(headerName, headerValue);
let headers;
if (request.useElectronNet) {
headers = options.headers;
delete options.headers;
options.session = opts.session || electron.session.defaultSession; // we have to use a persistent session here, because of https://github.com/electron/electron/issues/13587
}
const req = send(options);
if (request.useElectronNet) {
for (let headerName in headers) {
if (typeof headers[headerName] === 'string') req.setHeader(headerName, headers[headerName]);else {
for (var _iterator = headers[headerName], _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
let headerValue = _ref;
req.setHeader(headerName, headerValue);
}
}
}
let reqTimeout;
}
if (request.timeout) {
reqTimeout = setTimeout(function () {
req.abort();
reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
}, request.timeout);
}
let reqTimeout;
if (request.useElectronNet) {
// handle authenticating proxies
req.on('login', function (authInfo, callback) {
if (opts.user && opts.password) {
callback(opts.user, opts.password);
} else {
req.abort();
reject(new FetchError(`login event received from ${authInfo.host} but no credentials provided`, 'proxy', { code: 'PROXY_AUTH_FAILED' }));
}
});
}
if (request.timeout) {
reqTimeout = setTimeout(() => {
req.abort();
reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
}, request.timeout);
}
req.on('error', function (err) {
clearTimeout(reqTimeout);
reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
if (request.useElectronNet) {
// handle authenticating proxies
req.on('login', (authInfo, callback) => {
if (opts.user && opts.password) {
callback(opts.user, opts.password);
} else {
req.abort();
reject(new FetchError(`login event received from ${authInfo.host} but no credentials provided`, 'proxy', {
code: 'PROXY_AUTH_FAILED'
}));
}
});
}
req.on('response', function (res) {
clearTimeout(reqTimeout);
req.on('error', err => {
clearTimeout(reqTimeout);
reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
});
req.on('response', res => {
clearTimeout(reqTimeout); // handle redirect
// handle redirect
if (fetch.isRedirect(res.statusCode) && request.redirect !== 'manual') {
if (request.redirect === 'error') {
reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
return;
}
if (fetch.isRedirect(res.statusCode) && request.redirect !== 'manual') {
if (request.redirect === 'error') {
reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
return;
}
if (request.counter >= request.follow) {
reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
return;
}
if (request.counter >= request.follow) {
reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
return;
}
if (!res.headers.location) {
reject(new FetchError(`redirect location header missing at: ${request.url}`, 'invalid-redirect'));
return;
}
if (!res.headers.location) {
reject(new FetchError(`redirect location header missing at: ${request.url}`, 'invalid-redirect'));
return;
} // per fetch spec, for POST request with 301/302 response, or any request with 303 response, use GET when following redirect
// per fetch spec, for POST request with 301/302 response, or any request with 303 response, use GET when following redirect
if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
request.method = 'GET';
request.body = null;
request.headers.delete('content-length');
}
request.counter++;
resolve(fetch(url.resolve(request.url, res.headers.location), request));
return;
if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
request.method = 'GET';
request.body = null;
request.headers.delete('content-length');
}
// normalize location header for manual redirect mode
const headers = new Headers();
for (const name of Object.keys(res.headers)) {
if (Array.isArray(res.headers[name])) {
for (const val of res.headers[name]) {
headers.append(name, val);
request.counter++;
resolve(fetch(url.resolve(request.url, res.headers.location), request));
return;
} // normalize location header for manual redirect mode
const headers = new Headers();
var _arr = Object.keys(res.headers);
for (var _i2 = 0; _i2 < _arr.length; _i2++) {
const name = _arr[_i2];
if (Array.isArray(res.headers[name])) {
for (var _iterator2 = res.headers[name], _isArray2 = Array.isArray(_iterator2), _i3 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref2;
if (_isArray2) {
if (_i3 >= _iterator2.length) break;
_ref2 = _iterator2[_i3++];
} else {
_i3 = _iterator2.next();
if (_i3.done) break;
_ref2 = _i3.value;
}
} else {
headers.append(name, res.headers[name]);
const val = _ref2;
headers.append(name, val);
}
} else {
headers.append(name, res.headers[name]);
}
if (request.redirect === 'manual' && headers.has('location')) {
headers.set('location', url.resolve(request.url, headers.get('location')));
}
}
// prepare response
let body = new Stream.PassThrough();
res.on('error', function (err) {
return body.emit('error', err);
});
res.pipe(body);
const responseOptions = {
url: request.url,
status: res.statusCode,
statusText: res.statusMessage,
headers: headers,
size: request.size,
timeout: request.timeout,
useElectronNet: request.useElectronNet
if (request.redirect === 'manual' && headers.has('location')) {
headers.set('location', url.resolve(request.url, headers.get('location')));
} // prepare response
// HTTP-network fetch step 16.1.2
};const codings = headers.get('Content-Encoding');
// HTTP-network fetch step 16.1.3: handle content codings
let body = new Stream.PassThrough();
res.on('error', err => body.emit('error', err));
res.pipe(body);
const responseOptions = {
url: request.url,
status: res.statusCode,
statusText: res.statusMessage,
headers: headers,
size: request.size,
timeout: request.timeout,
useElectronNet: request.useElectronNet // HTTP-network fetch step 16.1.2
// in following scenarios we ignore compression support
// 1. running on Electron/net module (it manages it for us)
// 2. HEAD request
// 3. no Content-Encoding header
// 4. no content response (204)
// 5. content not modified response (304)
if (!request.useElectronNet && request.method !== 'HEAD' && codings !== null && res.statusCode !== 204 && res.statusCode !== 304) {
// Be less strict when decoding compressed responses, since sometimes
// servers send slightly invalid responses that are still accepted
// by common browsers.
// Always using Z_SYNC_FLUSH is what cURL does.
const zlibOptions = {
flush: zlib.Z_SYNC_FLUSH,
finishFlush: zlib.Z_SYNC_FLUSH
};
};
const codings = headers.get('Content-Encoding'); // HTTP-network fetch step 16.1.3: handle content codings
// in following scenarios we ignore compression support
// 1. running on Electron/net module (it manages it for us)
// 2. HEAD request
// 3. no Content-Encoding header
// 4. no content response (204)
// 5. content not modified response (304)
if (codings === 'gzip' || codings === 'x-gzip') {
// for gzip
body = body.pipe(zlib.createGunzip(zlibOptions));
} else if (codings === 'deflate' || codings === 'x-deflate') {
// for deflate
// handle the infamous raw deflate response from old servers
// a hack for old IIS and Apache servers
const raw = res.pipe(new Stream.PassThrough());
return raw.once('data', function (chunk) {
// see http://stackoverflow.com/questions/37519828
if ((chunk[0] & 0x0F) === 0x08) {
body = body.pipe(zlib.createInflate(zlibOptions));
} else {
body = body.pipe(zlib.createInflateRaw(zlibOptions));
}
const response = new Response(body, responseOptions);
resolve(response);
});
}
if (!request.useElectronNet && request.method !== 'HEAD' && codings !== null && res.statusCode !== 204 && res.statusCode !== 304) {
// Be less strict when decoding compressed responses, since sometimes
// servers send slightly invalid responses that are still accepted
// by common browsers.
// Always using Z_SYNC_FLUSH is what cURL does.
const zlibOptions = {
flush: zlib.Z_SYNC_FLUSH,
finishFlush: zlib.Z_SYNC_FLUSH
};
if (codings === 'gzip' || codings === 'x-gzip') {
// for gzip
body = body.pipe(zlib.createGunzip(zlibOptions));
} else if (codings === 'deflate' || codings === 'x-deflate') {
// for deflate
// handle the infamous raw deflate response from old servers
// a hack for old IIS and Apache servers
const raw = res.pipe(new Stream.PassThrough());
return raw.once('data', chunk => {
// see http://stackoverflow.com/questions/37519828
if ((chunk[0] & 0x0F) === 0x08) {
body = body.pipe(zlib.createInflate(zlibOptions));
} else {
body = body.pipe(zlib.createInflateRaw(zlibOptions));
}
const response = new Response(body, responseOptions);
resolve(response);
});
}
}
const response = new Response(body, responseOptions);
resolve(response);
});
writeToStream(req, request);
const response = new Response(body, responseOptions);
resolve(response);
});
});
writeToStream(req, request);
}));
}
/**

@@ -1501,6 +1579,5 @@ * Redirect code matching

*/
fetch.isRedirect = function (code) {
return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
};
fetch.isRedirect = code => code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
exports.default = fetch;

@@ -1507,0 +1584,0 @@ exports.Headers = Headers;

{
"name": "electron-fetch",
"version": "1.2.1",
"version": "1.3.0",
"description": "A light-weight module that brings window.fetch to electron's background process",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"module": "lib/index.es.js",
"types": "index.d.ts",
"files": [
"lib/index.js",
"lib/index.es.js",
"lib/index.d.ts"
"index.d.ts"
],
"engines": {
"node": ">=4"
"node": ">=6"
},

@@ -19,7 +19,9 @@ "scripts": {

"prepublishOnly": "npm run build",
"test": "npm run test:electron && npm run test:node && standard",
"test:electron": "xvfb-maybe cross-env BABEL_ENV=test electron-mocha --require babel-register test/test.js",
"test:node": "cross-env BABEL_ENV=test mocha --require babel-register test/test.js",
"coverage": "xvfb-maybe cross-env BABEL_ENV=coverage electron-mocha --require babel-register test/test.js -R test/coverage-reporter.js",
"report": "standard && npm run coverage && codecov -f coverage/coverage-final.json"
"test": "npm run test:electron && npm run test:node && npm run test:typings && standard",
"pretest:typings": "npm run build",
"test:typings": "ts-node test/test-typescript.ts",
"test:electron": "xvfb-maybe cross-env BABEL_ENV=test electron-mocha --require @babel/register test/test.js",
"test:node": "cross-env BABEL_ENV=test mocha --require @babel/register test/test.js",
"coverage": "xvfb-maybe cross-env BABEL_ENV=coverage electron-mocha --require @babel/register test/test.js -R test/coverage-reporter.js",
"report": "standard && npm run test:typings && npm run coverage && codecov -f coverage/coverage-final.json"
},

@@ -43,27 +45,30 @@ "repository": {

"devDependencies": {
"babel-eslint": "^8.2.5",
"babel-plugin-istanbul": "^4.1.6",
"babel-preset-env": "^1.7.0",
"babel-register": "^6.26.0",
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@babel/register": "^7.0.0",
"babel-eslint": "^10.0.1",
"babel-plugin-istanbul": "^5.1.0",
"basic-auth-parser": "0.0.2",
"chai": "^4.1.2",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"codecov": "^3.0.4",
"codecov": "^3.1.0",
"cross-env": "^5.2.0",
"electron": "2.0.4",
"electron": "2.0.13",
"electron-mocha": "^6.0.4",
"form-data": ">=2.3.2",
"is-builtin-module": "^2.0.0",
"istanbul-api": "^1.3.1",
"istanbul-lib-coverage": "^1.2.0",
"form-data": "^2.3.3",
"is-builtin-module": "^3.0.0",
"istanbul-api": "^2.0.6",
"istanbul-lib-coverage": "^2.0.1",
"mocha": "^5.2.0",
"nyc": "^12.0.2",
"nyc": "^13.1.0",
"parted": "^0.1.1",
"promise": "^8.0.1",
"promise": "^8.0.2",
"proxy": "^0.2.4",
"resumer": "0.0.0",
"rollup": "^0.62.0",
"rollup-plugin-babel": "^3.0.7",
"standard": "^11.0.1",
"whatwg-url": "^6.5.0",
"rollup": "^0.67.1",
"rollup-plugin-babel": "^4.0.3",
"standard": "^12.0.1",
"ts-node": "^7.0.1",
"typescript": "^3.1.6",
"whatwg-url": "^7.0.0",
"xvfb-maybe": "^0.2.1"

@@ -70,0 +75,0 @@ },

@@ -43,3 +43,3 @@

- Added electron-specific option `useElectronNet`, which can be set to false when running on Electron in order to behave as Node.js.
- Removed possibility to use custom Promise implementation (it's 2017, `Promise` is available everywhere!).
- Removed possibility to use custom Promise implementation (it's 2018, `Promise` is available everywhere!).
- Removed the possibility to forbid content compression (incompatible with Electron's `net` module, and of limited interest)

@@ -60,3 +60,3 @@ - [`standard`-ized](http://standardjs.com) the code.

// or
// const fetch = require('electron-fetch');
// const fetch = require('electron-fetch').default

@@ -63,0 +63,0 @@ // plain text or html

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc