mirror of
https://github.com/Wessel/wumpfetch.git
synced 2026-06-08 14:10:03 +02:00
Many fixes!
This commit is contained in:
12
README.md
12
README.md
@@ -12,12 +12,12 @@ $ npm i wumpfetch # Install w/ NPM
|
|||||||
## Usage
|
## Usage
|
||||||
##### Code
|
##### Code
|
||||||
```js
|
```js
|
||||||
const w = require( 'wumpfetch' );
|
const w = require('wumpfetch');
|
||||||
|
|
||||||
;( async() => {
|
;(async() => {
|
||||||
const r = await w( 'https://aws.random.cat/meow' ).send();
|
const r = await w('https://aws.random.cat/meow').send();
|
||||||
|
|
||||||
console.log( r.json() );
|
console.log(r.json());
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
##### Result
|
##### Result
|
||||||
@@ -33,7 +33,7 @@ const w = require('wumpfetch');
|
|||||||
|
|
||||||
;(async() => {
|
;(async() => {
|
||||||
const r = await w('https://my-site.com/postboi', 'POST')
|
const r = await w('https://my-site.com/postboi', 'POST')
|
||||||
.timeout( 1000 ) // Set a 1s timeout
|
.timeout(1000) // Set a 1s timeout
|
||||||
.query('video', 'wumpboye') // Add a query
|
.query('video', 'wumpboye') // Add a query
|
||||||
.header({ 'Authorization': 'Pablito' }) // Set a header
|
.header({ 'Authorization': 'Pablito' }) // Set a header
|
||||||
.body({ x: 'y', z: 1, beep: 'boop', chocolate: true }) // Send a json body
|
.body({ x: 'y', z: 1, beep: 'boop', chocolate: true }) // Send a json body
|
||||||
@@ -72,4 +72,4 @@ const w = require('wumpfetch');
|
|||||||
### Why should i use wumpfetch?
|
### Why should i use wumpfetch?
|
||||||
Wumpfetch is a lightweight and fast request library comparing to other packages such as request and node-fetch which are both around 1.5-4mb in size
|
Wumpfetch is a lightweight and fast request library comparing to other packages such as request and node-fetch which are both around 1.5-4mb in size
|
||||||
<br />
|
<br />
|
||||||
[](https://packagephobia.now.sh/result?p=wumpfetch) (6kb concatenated and 3.84kb minified, both in **/dest**)
|
[](https://packagephobia.now.sh/result?p=wumpfetch) (6.2kb concatenated and 4.4kb minified, both in **/dest**)
|
||||||
14
__test__/main.js
Normal file
14
__test__/main.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const util = require('util');
|
||||||
|
const wump = require('../lib');
|
||||||
|
|
||||||
|
console.log(`Using wumpfetch v${wump.version} [${wump.userAgent}]\n\n`);
|
||||||
|
|
||||||
|
;(async() => {
|
||||||
|
const requests = [
|
||||||
|
await wump({ url: 'https://jsonplaceholder.typicode.com/todos/1', parse: 'json' }).send(),
|
||||||
|
await wump('https://jsonplaceholder.typicode.com/todos/1').send()
|
||||||
|
];
|
||||||
|
|
||||||
|
console.log(`Test 1: \n${util.inspect(requests[0].body)}\n\n`);
|
||||||
|
console.log(`Test 2: \n${util.inspect(requests[1].json())}\n\n`);
|
||||||
|
})();
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
const { join } = require('path');
|
|
||||||
|
|
||||||
const common = [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH' ];
|
|
||||||
const request = require(join(__dirname, 'model', 'WumpRequest.js'));
|
|
||||||
|
|
||||||
module.exports = (url, method) => {
|
|
||||||
return new request(url, method);
|
|
||||||
};
|
|
||||||
|
|
||||||
common.forEach((v) => {
|
|
||||||
module.exports[v.toLowerCase()] = (url, method) => {
|
|
||||||
return new request(url, Object.assign({ method: v }, method));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
109
dist/wumpfetch.concat.js
vendored
109
dist/wumpfetch.concat.js
vendored
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
const { URL } = require('url');
|
const { URL } = require('url');
|
||||||
@@ -8,6 +7,7 @@ const { createGunzip, createInflate } = require('zlib');
|
|||||||
|
|
||||||
const c = [ 'gzip', 'deflate' ];
|
const c = [ 'gzip', 'deflate' ];
|
||||||
const common = [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH' ];
|
const common = [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH' ];
|
||||||
|
const { version } = require('../package.json');
|
||||||
|
|
||||||
const WumpResponse = class WumpResponse {
|
const WumpResponse = class WumpResponse {
|
||||||
constructor (res) {
|
constructor (res) {
|
||||||
@@ -30,28 +30,33 @@ const WumpResponse = class WumpResponse {
|
|||||||
return JSON.parse(this.body);
|
return JSON.parse(this.body);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const WumpRequest = class WumpRequest {
|
|
||||||
constructor (url = {}, m = {}) {
|
|
||||||
const o = typeof url === 'string' ? m : url;
|
|
||||||
const obj = typeof o === 'object';
|
|
||||||
|
|
||||||
if (typeof url !== 'string' && !o.hasOwnProperty('url')) throw new Error('Missing url parameter');
|
const WumpRequest = class WumpRequest {
|
||||||
|
constructor (url = {}, method = {}) {
|
||||||
|
const o = (typeof url === 'string' ? method : url);
|
||||||
|
const obj = (typeof o === 'object');
|
||||||
|
|
||||||
|
if (typeof url !== 'string' && !o.hasOwnProperty('url')) {
|
||||||
|
throw new Error('Missing url parameter');
|
||||||
|
}
|
||||||
|
|
||||||
this.o = {
|
this.o = {
|
||||||
'm' : typeof o === 'string' ? o : obj && o.method ? o.method : 'GET',
|
'm': typeof o === 'string' ? o : obj && o.method ? o.method : 'GET',
|
||||||
'url' : typeof url === 'string' ? new URL( url ) : obj && typeof o.url === 'string' ? new URL( o.url ) : url,
|
'url': typeof url === 'string' ? new URL(url) : obj && typeof o.url === 'string' ? new URL(o.url) : url,
|
||||||
'SDA' : obj && typeof o.sendDataAs === 'string' ? o.sendDataAs : undefined,
|
'SDA': obj && typeof o.sendDataAs === 'string' ? o.sendDataAs : obj && o.data && typeof o.data === 'object' ? 'json' : undefined,
|
||||||
'data' : obj && o.data ? o.data : obj && o.form ? stringify( o.form ) : undefined,
|
'data': obj && o.data ? o.data : obj && o.json ? o.json : obj && o.form ? stringify(o.form) : undefined,
|
||||||
'parse' : obj && o.parse ? o.parse : undefined,
|
'parse': obj && o.parse ? o.parse : undefined,
|
||||||
'follow' : !!( obj && o.followRedirects ),
|
'follow': !!(obj && o.followRedirects),
|
||||||
'rHeaders' : obj && typeof o.headers === 'object' ? o.headers : {},
|
'rHeaders': obj && typeof o.headers === 'object' ? o.headers : {},
|
||||||
'streamed' : !!( obj && o.streamed ),
|
'streamed': !!(obj && o.streamed),
|
||||||
'compressed' : !!( obj && o.compressed ),
|
'compressed': !!(obj && o.compressed),
|
||||||
'timeoutTime': obj && typeof o.timeout === 'number' ? o.timeout : null,
|
'timeoutTime': obj && typeof o.timeout === 'number' ? o.timeout : null,
|
||||||
'coreOptions': obj && typeof o.coreOptions === 'object' ? o.coreOptions : {}
|
'coreOptions': obj && typeof o.coreOptions === 'object' ? o.coreOptions : {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof o.core === 'object') Object.keys(o.core).forEach((v) => this.option(v, o.core[v]));
|
if (typeof o.core === 'object') {
|
||||||
|
Object.keys(o.core).forEach((v) => this.option(v, o.core[v]));
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -70,7 +75,7 @@ const WumpRequest = class WumpRequest {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
header ( a, b ) {
|
header (a, b) {
|
||||||
if (typeof a === 'object') Object.keys(a).forEach((v) => this.o.rHeaders[v.toLowerCase()] = a[v]);
|
if (typeof a === 'object') Object.keys(a).forEach((v) => this.o.rHeaders[v.toLowerCase()] = a[v]);
|
||||||
else this.o.rHeaders[a.toLowerCase()] = b;
|
else this.o.rHeaders[a.toLowerCase()] = b;
|
||||||
|
|
||||||
@@ -79,34 +84,40 @@ const WumpRequest = class WumpRequest {
|
|||||||
|
|
||||||
compress () {
|
compress () {
|
||||||
this.compressed = true;
|
this.compressed = true;
|
||||||
if (!this.o.rHeaders[ 'accept-encoding' ]) this.o.rHeaders[ 'accept-encoding' ] = c.join(', ');
|
if (!this.o.rHeaders['accept-encoding']) this.o.rHeaders['accept-encoding'] = c.join(', ');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
path (p) {
|
path (p) {
|
||||||
this.o.url.pathname = join(this.o.url.pathname, p);
|
this.o.url.pathname = join(this.o.url.pathname, p);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream () {
|
stream () {
|
||||||
this.o.streamed = true;
|
this.o.streamed = true;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
option (n, v) {
|
option (n, v) {
|
||||||
this.o.coreOptions[n] = v;
|
this.o.coreOptions[n] = v;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
timeout (timeout) {
|
timeout (timeout) {
|
||||||
this.o.timeoutTime = timeout;
|
this.o.timeoutTime = timeout;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
send () {
|
send () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.o.data) {
|
if (this.o.data) {
|
||||||
if (!this.o.rHeaders.hasOwnProperty('user-agent')) this.o.rHeaders['User-Agent'] = 'wumpfetch/0.0.1 (https://github.com/PassTheWessel/wumpfetch)';
|
if (!this.o.rHeaders.hasOwnProperty('user-agent')) {
|
||||||
|
this.o.rHeaders['User-Agent'] = w.userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.o.SDA === 'json' && !this.o.rHeaders.hasOwnProperty('content-type')) this.o.rHeaders['Content-Type'] = 'application/json';
|
if (this.o.SDA === 'json' && !this.o.rHeaders.hasOwnProperty('content-type')) this.o.rHeaders['Content-Type'] = 'application/json';
|
||||||
if (this.o.SDA === 'form') {
|
if (this.o.SDA === 'form') {
|
||||||
@@ -116,32 +127,33 @@ const WumpRequest = class WumpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let req;
|
let req;
|
||||||
const options = Object.assign({
|
const options = {
|
||||||
'host' : this.o.url.hostname,
|
'host': this.o.url.hostname,
|
||||||
'port' : this.o.url.port,
|
'port': this.o.url.port,
|
||||||
'path' : this.o.url.pathname + this.o.url.search,
|
'path': this.o.url.pathname + this.o.url.search,
|
||||||
'method' : this.o.m,
|
'method': this.o.m,
|
||||||
'headers' : this.o.rHeaders,
|
'headers': this.o.rHeaders,
|
||||||
'protocol': this.o.url.protocol
|
'protocol': this.o.url.protocol,
|
||||||
}, this.o.coreOptions);
|
...this.o.coreOptions
|
||||||
|
}
|
||||||
|
|
||||||
const resHandler = async (res) => {
|
const handler = async (res) => {
|
||||||
let stream = res;
|
let stream = res;
|
||||||
|
|
||||||
if (this.o.compressed) {
|
if (this.o.compressed) {
|
||||||
if (res.headers['content-encoding'] === 'gzip') stream = res.pipe(createGunzip());
|
if (res.headers['content-encoding'] === 'gzip') stream = res.pipe(createGunzip());
|
||||||
else if (res.headers[ 'content-encoding' ] === 'deflate') stream = res.pipe(createInflate());
|
else if (res.headers[ 'content-encoding'] === 'deflate') stream = res.pipe(createInflate());
|
||||||
}
|
}
|
||||||
|
|
||||||
let wumpRes;
|
let wumpRes;
|
||||||
|
|
||||||
if ( this.o.streamed ) resolve(stream);
|
if (this.o.streamed) resolve(stream);
|
||||||
else {
|
else {
|
||||||
wumpRes = new WumpResponse(res);
|
wumpRes = new WumpResponse(res);
|
||||||
|
|
||||||
if (res.headers.hasOwnProperty('location') && this.o.follow) {
|
if (res.headers.hasOwnProperty('location') && this.o.follow) {
|
||||||
this.o.url = (new URL(res.headers['location'], this.o.url)).toString();
|
this.o.url = (new URL(res.headers['location'], this.o.url)).toString();
|
||||||
return await w(this.o);
|
return await module.exports(this.o);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.on('error', (e) => reject(e));
|
stream.on('error', (e) => reject(e));
|
||||||
@@ -158,8 +170,8 @@ const WumpRequest = class WumpRequest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.o.url.protocol === 'http:') req = http.request(options, resHandler);
|
if (this.o.url.protocol === 'http:') req = http.request(options, handler);
|
||||||
else if (this.o.url.protocol === 'https:') req = https.request(options, resHandler);
|
else if (this.o.url.protocol === 'https:') req = https.request(options, handler);
|
||||||
else throw new Error(`Bad URL protocol: ${this.o.url.protocol}`);
|
else throw new Error(`Bad URL protocol: ${this.o.url.protocol}`);
|
||||||
|
|
||||||
|
|
||||||
@@ -171,22 +183,37 @@ const WumpRequest = class WumpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.on('error', (e) => reject(e));
|
req.on('error', (e) => reject(e));
|
||||||
if (this.o.data) req.write(this.o.SDA === 'json' ? JSON.stringify(this.o.data) : this.o.data);
|
|
||||||
|
if (this.o.data) {
|
||||||
|
if (this.o.SDA === 'json') {
|
||||||
|
req.write(JSON.stringify(this.o.data));
|
||||||
|
} else {
|
||||||
|
if (typeof this.o.data === 'object') {
|
||||||
|
req.write(JSON.stringify(this.o.data));
|
||||||
|
} else {
|
||||||
|
req.write(this.o.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
req.end();
|
req.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports = (url, method) => {
|
||||||
function w(url, method) {
|
|
||||||
return new WumpRequest(url, method);
|
return new WumpRequest(url, method);
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = w;
|
|
||||||
|
|
||||||
common.forEach((v) => {
|
common.forEach((v) => {
|
||||||
module.exports[v.toLowerCase()] = (url, method = v) => {
|
module.exports[v.toLowerCase()] = (url, method) => {
|
||||||
return new request(url, Object.assign({ method: v }, method));
|
if (typeof url === 'string') {
|
||||||
|
return new WumpRequest(url, { method: v, ...method });
|
||||||
|
} else {
|
||||||
|
return new WumpRequest({ method: v, ...url }, method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.exports.version = version;
|
||||||
|
module.exports.userAgent = `wumpfetch/${version} (https://github.com/PassTheWessel/wumpfetch)`;
|
||||||
|
|||||||
2
dist/wumpfetch.min.js
vendored
2
dist/wumpfetch.min.js
vendored
@@ -1 +1 @@
|
|||||||
const http=require("http"),https=require("https"),{URL:URL}=require("url"),{join:join}=require("path"),{stringify:stringify}=require("querystring"),{createGunzip:createGunzip,createInflate:createInflate}=require("zlib"),c=["gzip","deflate"],common=["GET","HEAD","POST","PUT","DELETE","CONNECT","OPTIONS","TRACE","PATCH"],WumpResponse=class{constructor(t){this.body=Buffer.alloc(0),this.coreRes=t,this.headers=t.headers,this.statusCode=t.statusCode}_addChunk(t){this.body=Buffer.concat([this.body,t])}text(){return this.body.toString()}json(){return JSON.parse(this.body)}},WumpRequest=class{constructor(t={},e={}){const o="string"==typeof t?e:t,r="object"==typeof o;if("string"!=typeof t&&!o.hasOwnProperty("url"))throw new Error("Missing url parameter");return this.o={m:"string"==typeof o?o:r&&o.method?o.method:"GET",url:"string"==typeof t?new URL(t):r&&"string"==typeof o.url?new URL(o.url):t,SDA:r&&"string"==typeof o.sendDataAs?o.sendDataAs:void 0,data:r&&o.data?o.data:r&&o.form?stringify(o.form):void 0,parse:r&&o.parse?o.parse:void 0,follow:!(!r||!o.followRedirects),rHeaders:r&&"object"==typeof o.headers?o.headers:{},streamed:!(!r||!o.streamed),compressed:!(!r||!o.compressed),timeoutTime:r&&"number"==typeof o.timeout?o.timeout:null,coreOptions:r&&"object"==typeof o.coreOptions?o.coreOptions:{}},"object"==typeof o.core&&Object.keys(o.core).forEach(t=>this.option(t,o.core[t])),this}query(t,e){return"object"==typeof t?Object.keys(t).forEach(e=>this.o.url.searchParams.append(e,t[e])):this.o.url.searchParams.append(t,e),this}body(t,e){return this.o.SDA="object"!=typeof t||e||Buffer.isBuffer(t)?e?e.toLowerCase():"buffer":"json",this.o.data="form"===this.SDA?stringify(t):"json"===this.SDA?JSON.stringify(t):t,this}header(t,e){return"object"==typeof t?Object.keys(t).forEach(e=>this.o.rHeaders[e.toLowerCase()]=t[e]):this.o.rHeaders[t.toLowerCase()]=e,this}compress(){return this.compressed=!0,this.o.rHeaders["accept-encoding"]||(this.o.rHeaders["accept-encoding"]=c.join(", ")),this}path(t){return this.o.url.pathname=join(this.o.url.pathname,t),this}stream(){return this.o.streamed=!0,this}option(t,e){return this.o.coreOptions[t]=e,this}timeout(t){return this.o.timeoutTime=t,this}send(){return new Promise((t,e)=>{let o;this.o.data&&(this.o.rHeaders.hasOwnProperty("user-agent")||(this.o.rHeaders["User-Agent"]="wumpfetch/0.0.1 (https://github.com/PassTheWessel/wumpfetch)"),"json"!==this.o.SDA||this.o.rHeaders.hasOwnProperty("content-type")||(this.o.rHeaders["Content-Type"]="application/json"),"form"===this.o.SDA&&(this.o.rHeaders.hasOwnProperty("content-type")||(this.o.rHeaders["Content-Type"]="application/x-www-form-urlencoded"),this.o.rHeaders.hasOwnProperty("content-length")||(this.o.rHeaders["Content-Length"]=Buffer.byteLength(this.o.data))));const r=Object.assign({host:this.o.url.hostname,port:this.o.url.port,path:this.o.url.pathname+this.o.url.search,method:this.o.m,headers:this.o.rHeaders,protocol:this.o.url.protocol},this.o.coreOptions),s=async o=>{let r,s=o;if(this.o.compressed&&("gzip"===o.headers["content-encoding"]?s=o.pipe(createGunzip()):"deflate"===o.headers["content-encoding"]&&(s=o.pipe(createInflate()))),this.o.streamed)t(s);else{if(r=new WumpResponse(o),o.headers.hasOwnProperty("location")&&this.o.follow)return this.o.url=new URL(o.headers.location,this.o.url).toString(),await w(this.o);s.on("error",t=>e(t)),s.on("data",t=>r._addChunk(t)),s.on("end",()=>{this.o.parse&&("json"===this.o.parse?r.body=JSON.parse(r.body):"text"===this.o.parse?r.body=r.body.toString():r.body=r.body),t(r)})}};if("http:"===this.o.url.protocol)o=http.request(r,s);else{if("https:"!==this.o.url.protocol)throw new Error(`Bad URL protocol: ${this.o.url.protocol}`);o=https.request(r,s)}this.o.timeoutTime&&o.setTimeout(this.o.timeoutTime,()=>{o.abort(),this.o.streamed||e(new Error("Timeout reached"))}),o.on("error",t=>e(t)),this.o.data&&o.write("json"===this.o.SDA?JSON.stringify(this.o.data):this.o.data),o.end()})}};function w(t,e){return new WumpRequest(t,e)}module.exports=w,common.forEach(t=>{module.exports[t.toLowerCase()]=((e,o=t)=>new request(e,Object.assign({method:t},o)))});
|
const http=require("http"),https=require("https"),{URL:URL}=require("url"),{join:join}=require("path"),{stringify:stringify}=require("querystring"),{createGunzip:createGunzip,createInflate:createInflate}=require("zlib"),c=["gzip","deflate"],common=["GET","HEAD","POST","PUT","DELETE","CONNECT","OPTIONS","TRACE","PATCH"],{version:version}=require("../package.json"),WumpResponse=class{constructor(e){this.body=Buffer.alloc(0),this.coreRes=e,this.headers=e.headers,this.statusCode=e.statusCode}_addChunk(e){this.body=Buffer.concat([this.body,e])}text(){return this.body.toString()}json(){return JSON.parse(this.body)}},WumpRequest=class{constructor(e={},t={}){const o="string"==typeof e?t:e,r="object"==typeof o;if("string"!=typeof e&&!o.hasOwnProperty("url"))throw new Error("Missing url parameter");return this.o={m:"string"==typeof o?o:r&&o.method?o.method:"GET",url:"string"==typeof e?new URL(e):r&&"string"==typeof o.url?new URL(o.url):e,SDA:r&&"string"==typeof o.sendDataAs?o.sendDataAs:r&&o.data&&"object"==typeof o.data?"json":void 0,data:r&&o.data?o.data:r&&o.json?o.json:r&&o.form?stringify(o.form):void 0,parse:r&&o.parse?o.parse:void 0,follow:!(!r||!o.followRedirects),rHeaders:r&&"object"==typeof o.headers?o.headers:{},streamed:!(!r||!o.streamed),compressed:!(!r||!o.compressed),timeoutTime:r&&"number"==typeof o.timeout?o.timeout:null,coreOptions:r&&"object"==typeof o.coreOptions?o.coreOptions:{}},"object"==typeof o.core&&Object.keys(o.core).forEach(e=>this.option(e,o.core[e])),this}query(e,t){return"object"==typeof e?Object.keys(e).forEach(t=>this.o.url.searchParams.append(t,e[t])):this.o.url.searchParams.append(e,t),this}body(e,t){return this.o.SDA="object"!=typeof e||t||Buffer.isBuffer(e)?t?t.toLowerCase():"buffer":"json",this.o.data="form"===this.SDA?stringify(e):"json"===this.SDA?JSON.stringify(e):e,this}header(e,t){return"object"==typeof e?Object.keys(e).forEach(t=>this.o.rHeaders[t.toLowerCase()]=e[t]):this.o.rHeaders[e.toLowerCase()]=t,this}compress(){return this.compressed=!0,this.o.rHeaders["accept-encoding"]||(this.o.rHeaders["accept-encoding"]=c.join(", ")),this}path(e){return this.o.url.pathname=join(this.o.url.pathname,e),this}stream(){return this.o.streamed=!0,this}option(e,t){return this.o.coreOptions[e]=t,this}timeout(e){return this.o.timeoutTime=e,this}send(){return new Promise((e,t)=>{let o;this.o.data&&(this.o.rHeaders.hasOwnProperty("user-agent")||(this.o.rHeaders["User-Agent"]=w.userAgent),"json"!==this.o.SDA||this.o.rHeaders.hasOwnProperty("content-type")||(this.o.rHeaders["Content-Type"]="application/json"),"form"===this.o.SDA&&(this.o.rHeaders.hasOwnProperty("content-type")||(this.o.rHeaders["Content-Type"]="application/x-www-form-urlencoded"),this.o.rHeaders.hasOwnProperty("content-length")||(this.o.rHeaders["Content-Length"]=Buffer.byteLength(this.o.data))));const r={host:this.o.url.hostname,port:this.o.url.port,path:this.o.url.pathname+this.o.url.search,method:this.o.m,headers:this.o.rHeaders,protocol:this.o.url.protocol,...this.o.coreOptions},s=async o=>{let r,s=o;if(this.o.compressed&&("gzip"===o.headers["content-encoding"]?s=o.pipe(createGunzip()):"deflate"===o.headers["content-encoding"]&&(s=o.pipe(createInflate()))),this.o.streamed)e(s);else{if(r=new WumpResponse(o),o.headers.hasOwnProperty("location")&&this.o.follow)return this.o.url=new URL(o.headers.location,this.o.url).toString(),await module.exports(this.o);s.on("error",e=>t(e)),s.on("data",e=>r._addChunk(e)),s.on("end",()=>{this.o.parse&&("json"===this.o.parse?r.body=JSON.parse(r.body):"text"===this.o.parse?r.body=r.body.toString():r.body=r.body),e(r)})}};if("http:"===this.o.url.protocol)o=http.request(r,s);else{if("https:"!==this.o.url.protocol)throw new Error(`Bad URL protocol: ${this.o.url.protocol}`);o=https.request(r,s)}this.o.timeoutTime&&o.setTimeout(this.o.timeoutTime,()=>{o.abort(),this.o.streamed||t(new Error("Timeout reached"))}),o.on("error",e=>t(e)),this.o.data&&("json"===this.o.SDA?o.write(JSON.stringify(this.o.data)):"object"==typeof this.o.data?o.write(JSON.stringify(this.o.data)):o.write(this.o.data)),o.end()})}};module.exports=((e,t)=>new WumpRequest(e,t)),common.forEach(e=>{module.exports[e.toLowerCase()]=((t,o)=>"string"==typeof t?new WumpRequest(t,{method:e,...o}):new WumpRequest({method:e,...t},o))}),module.exports.version=version,module.exports.userAgent=`wumpfetch/${version} (https://github.com/PassTheWessel/wumpfetch)`;
|
||||||
53
examples/thronebutt-icons.js
Normal file
53
examples/thronebutt-icons.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Download all death animations from nuclear throne
|
||||||
|
*
|
||||||
|
* @name Thronebutt-downloader
|
||||||
|
* @author Wessel "wesselgame" T <discord@go2it.eu>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Check if node >= v8.0.0 is installed
|
||||||
|
if (Number(process.version.slice(1).split('.')[0]) < 8) throw new Error('Node 8.0.0 or higher is required. Update Node on your system.');
|
||||||
|
// Declarations
|
||||||
|
const fs = require('fs');
|
||||||
|
const wump = require('../lib');
|
||||||
|
// Random string generator
|
||||||
|
const string = (iterations = 1, seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') => {
|
||||||
|
let text = '';
|
||||||
|
|
||||||
|
if (typeof seed !== 'string' || seed.length <= 0 || typeof iterations !== 'number') return text;
|
||||||
|
for (let i = 0; i < iterations; i++) text += seed.charAt(Math.floor(Math.random() * seed.length));
|
||||||
|
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
// Set process values
|
||||||
|
process.name = 'Thronebutt';
|
||||||
|
process.hash = string(8);
|
||||||
|
// Define some basic stuff
|
||||||
|
const start = Date.now();
|
||||||
|
const settings = {
|
||||||
|
entries : 150, // Times to loop
|
||||||
|
baseURL : 'https://thronebutt.com/img/deathflags', // BaseURL for images
|
||||||
|
interval : 500, // Interval inbetween every request
|
||||||
|
fileType : 'gif', // The file type to save as
|
||||||
|
randomize: true // Add a random 0-500ms to every interval
|
||||||
|
};
|
||||||
|
// Fetch `url` and save it to `dump/<index>.<fileType>`
|
||||||
|
const get = async(url, index) => {
|
||||||
|
const req = await wump(url).send();
|
||||||
|
if (req.statusCode !== 200) {
|
||||||
|
return console.log(`[${process.name}] Failed on "${url}": ${req.statusCode}`)
|
||||||
|
} else {
|
||||||
|
fs.writeFileSync(`dump/${index}.${settings.fileType}`, req.body);
|
||||||
|
console.log(`[${process.name}] Successfully copied "${url}" to "dump/${index}.${settings.fileType}" in ${Date.now() - start}ms from queue`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Create the `dump` directory if it doesn't exist
|
||||||
|
fs.mkdir('dump', (err) => {
|
||||||
|
if (err && err.code !== 'EEXIST') throw err;
|
||||||
|
});
|
||||||
|
// Loop `settings.entries` times and download the files
|
||||||
|
for (let i = 0; i < settings.entries; i++) {
|
||||||
|
const interval = ((settings.interval + (settings.randomize ? Math.floor(Math.random() * 500) : 0)) * i);
|
||||||
|
setTimeout(() => get(`${settings.baseURL}/${i}.${settings.fileType}`, i), interval)
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ gulp.task('build:node', () => {
|
|||||||
|
|
||||||
gulp.task('concat', () => {
|
gulp.task('concat', () => {
|
||||||
return gulp
|
return gulp
|
||||||
.src([ 'createRequest.js', 'model/**/*.js' ])
|
.src('lib/**/*.js')
|
||||||
.pipe(concat('wumpfetch.concat.js'))
|
.pipe(concat('wumpfetch.concat.js'))
|
||||||
.pipe(gulp.dest('./dist'));
|
.pipe(gulp.dest('dist'));
|
||||||
});
|
});
|
||||||
20
lib/index.js
Normal file
20
lib/index.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const common = [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH' ];
|
||||||
|
const request = require('./model/WumpRequest');
|
||||||
|
const { version } = require('../package.json');
|
||||||
|
|
||||||
|
module.exports = (url, method) => {
|
||||||
|
return new request(url, method);
|
||||||
|
};
|
||||||
|
|
||||||
|
common.forEach((v) => {
|
||||||
|
module.exports[v.toLowerCase()] = (url, method) => {
|
||||||
|
if (typeof url === 'string') {
|
||||||
|
return new request(url, { method: v, ...method });
|
||||||
|
} else {
|
||||||
|
return new request({ method: v, ...url }, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports.version = version;
|
||||||
|
module.exports.userAgent = `wumpfetch/${version} (https://github.com/PassTheWessel/wumpfetch)`;
|
||||||
@@ -5,33 +5,37 @@ const { join } = require('path');
|
|||||||
const { stringify } = require('querystring');
|
const { stringify } = require('querystring');
|
||||||
const { createGunzip, createInflate } = require('zlib');
|
const { createGunzip, createInflate } = require('zlib');
|
||||||
|
|
||||||
const WumpResponse = require(join(__dirname, 'WumpResponse.js'));
|
const WumpResponse = require('./WumpResponse');
|
||||||
|
|
||||||
const w = require(join(__dirname, '..', 'createRequest.js' ));
|
const w = require('../index');
|
||||||
const c = [ 'gzip', 'deflate' ];
|
const c = [ 'gzip', 'deflate' ];
|
||||||
|
|
||||||
module.exports = class WumpRequest {
|
module.exports = class WumpRequest {
|
||||||
constructor (url = {}, m = {}) {
|
constructor (url = {}, method = {}) {
|
||||||
const o = typeof url === 'string' ? m : url;
|
const o = (typeof url === 'string' ? method : url);
|
||||||
const obj = typeof o === 'object';
|
const obj = (typeof o === 'object');
|
||||||
|
|
||||||
if (typeof url !== 'string' && !o.hasOwnProperty('url')) throw new Error('Missing url parameter');
|
if (typeof url !== 'string' && !o.hasOwnProperty('url')) {
|
||||||
|
throw new Error('Missing url parameter');
|
||||||
|
}
|
||||||
|
|
||||||
this.o = {
|
this.o = {
|
||||||
'm' : typeof o === 'string' ? o : obj && o.method ? o.method : 'GET',
|
'm': typeof o === 'string' ? o : obj && o.method ? o.method : 'GET',
|
||||||
'url' : typeof url === 'string' ? new URL( url ) : obj && typeof o.url === 'string' ? new URL( o.url ) : url,
|
'url': typeof url === 'string' ? new URL(url) : obj && typeof o.url === 'string' ? new URL(o.url) : url,
|
||||||
'SDA' : obj && typeof o.sendDataAs === 'string' ? o.sendDataAs : obj && o.data && typeof o.data === 'object' ? 'json' : undefined,
|
'SDA': obj && typeof o.sendDataAs === 'string' ? o.sendDataAs : obj && o.data && typeof o.data === 'object' ? 'json' : undefined,
|
||||||
'data' : obj && o.data ? o.data : obj && o.form ? stringify( o.form ) : undefined,
|
'data': obj && o.data ? o.data : obj && o.json ? o.json : obj && o.form ? stringify(o.form) : undefined,
|
||||||
'parse' : obj && o.parse ? o.parse : undefined,
|
'parse': obj && o.parse ? o.parse : undefined,
|
||||||
'follow' : !!( obj && o.followRedirects ),
|
'follow': !!(obj && o.followRedirects),
|
||||||
'rHeaders' : obj && typeof o.headers === 'object' ? o.headers : {},
|
'rHeaders': obj && typeof o.headers === 'object' ? o.headers : {},
|
||||||
'streamed' : !!( obj && o.streamed ),
|
'streamed': !!(obj && o.streamed),
|
||||||
'compressed' : !!( obj && o.compressed ),
|
'compressed': !!(obj && o.compressed),
|
||||||
'timeoutTime': obj && typeof o.timeout === 'number' ? o.timeout : null,
|
'timeoutTime': obj && typeof o.timeout === 'number' ? o.timeout : null,
|
||||||
'coreOptions': obj && typeof o.coreOptions === 'object' ? o.coreOptions : {}
|
'coreOptions': obj && typeof o.coreOptions === 'object' ? o.coreOptions : {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof o.core === 'object') Object.keys(o.core).forEach((v) => this.option(v, o.core[v]));
|
if (typeof o.core === 'object') {
|
||||||
|
Object.keys(o.core).forEach((v) => this.option(v, o.core[v]));
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -50,7 +54,7 @@ module.exports = class WumpRequest {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
header ( a, b ) {
|
header (a, b) {
|
||||||
if (typeof a === 'object') Object.keys(a).forEach((v) => this.o.rHeaders[v.toLowerCase()] = a[v]);
|
if (typeof a === 'object') Object.keys(a).forEach((v) => this.o.rHeaders[v.toLowerCase()] = a[v]);
|
||||||
else this.o.rHeaders[a.toLowerCase()] = b;
|
else this.o.rHeaders[a.toLowerCase()] = b;
|
||||||
|
|
||||||
@@ -59,34 +63,40 @@ module.exports = class WumpRequest {
|
|||||||
|
|
||||||
compress () {
|
compress () {
|
||||||
this.compressed = true;
|
this.compressed = true;
|
||||||
if (!this.o.rHeaders[ 'accept-encoding' ]) this.o.rHeaders[ 'accept-encoding' ] = c.join(', ');
|
if (!this.o.rHeaders['accept-encoding']) this.o.rHeaders['accept-encoding'] = c.join(', ');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
path (p) {
|
path (p) {
|
||||||
this.o.url.pathname = join(this.o.url.pathname, p);
|
this.o.url.pathname = join(this.o.url.pathname, p);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream () {
|
stream () {
|
||||||
this.o.streamed = true;
|
this.o.streamed = true;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
option (n, v) {
|
option (n, v) {
|
||||||
this.o.coreOptions[n] = v;
|
this.o.coreOptions[n] = v;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
timeout (timeout) {
|
timeout (timeout) {
|
||||||
this.o.timeoutTime = timeout;
|
this.o.timeoutTime = timeout;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
send () {
|
send () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.o.data) {
|
if (this.o.data) {
|
||||||
if (!this.o.rHeaders.hasOwnProperty('user-agent')) this.o.rHeaders['User-Agent'] = 'wumpfetch/0.0.1 (https://github.com/PassTheWessel/wumpfetch)';
|
if (!this.o.rHeaders.hasOwnProperty('user-agent')) {
|
||||||
|
this.o.rHeaders['User-Agent'] = w.userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.o.SDA === 'json' && !this.o.rHeaders.hasOwnProperty('content-type')) this.o.rHeaders['Content-Type'] = 'application/json';
|
if (this.o.SDA === 'json' && !this.o.rHeaders.hasOwnProperty('content-type')) this.o.rHeaders['Content-Type'] = 'application/json';
|
||||||
if (this.o.SDA === 'form') {
|
if (this.o.SDA === 'form') {
|
||||||
@@ -96,26 +106,27 @@ module.exports = class WumpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let req;
|
let req;
|
||||||
const options = Object.assign({
|
const options = {
|
||||||
'host' : this.o.url.hostname,
|
'host': this.o.url.hostname,
|
||||||
'port' : this.o.url.port,
|
'port': this.o.url.port,
|
||||||
'path' : this.o.url.pathname + this.o.url.search,
|
'path': this.o.url.pathname + this.o.url.search,
|
||||||
'method' : this.o.m,
|
'method': this.o.m,
|
||||||
'headers' : this.o.rHeaders,
|
'headers': this.o.rHeaders,
|
||||||
'protocol': this.o.url.protocol
|
'protocol': this.o.url.protocol,
|
||||||
}, this.o.coreOptions);
|
...this.o.coreOptions
|
||||||
|
}
|
||||||
|
|
||||||
const resHandler = async (res) => {
|
const handler = async (res) => {
|
||||||
let stream = res;
|
let stream = res;
|
||||||
|
|
||||||
if (this.o.compressed) {
|
if (this.o.compressed) {
|
||||||
if (res.headers['content-encoding'] === 'gzip') stream = res.pipe(createGunzip());
|
if (res.headers['content-encoding'] === 'gzip') stream = res.pipe(createGunzip());
|
||||||
else if (res.headers[ 'content-encoding' ] === 'deflate') stream = res.pipe(createInflate());
|
else if (res.headers[ 'content-encoding'] === 'deflate') stream = res.pipe(createInflate());
|
||||||
}
|
}
|
||||||
|
|
||||||
let wumpRes;
|
let wumpRes;
|
||||||
|
|
||||||
if ( this.o.streamed ) resolve(stream);
|
if (this.o.streamed) resolve(stream);
|
||||||
else {
|
else {
|
||||||
wumpRes = new WumpResponse(res);
|
wumpRes = new WumpResponse(res);
|
||||||
|
|
||||||
@@ -138,8 +149,8 @@ module.exports = class WumpRequest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.o.url.protocol === 'http:') req = http.request(options, resHandler);
|
if (this.o.url.protocol === 'http:') req = http.request(options, handler);
|
||||||
else if (this.o.url.protocol === 'https:') req = https.request(options, resHandler);
|
else if (this.o.url.protocol === 'https:') req = https.request(options, handler);
|
||||||
else throw new Error(`Bad URL protocol: ${this.o.url.protocol}`);
|
else throw new Error(`Bad URL protocol: ${this.o.url.protocol}`);
|
||||||
|
|
||||||
|
|
||||||
21
package.json
21
package.json
@@ -1,24 +1,21 @@
|
|||||||
{
|
{
|
||||||
"name": "wumpfetch",
|
"name": "wumpfetch",
|
||||||
"version": "0.1.3",
|
"version": "0.2.0",
|
||||||
"description": "🚀 A lightweight and fast Node.js HTTP Client",
|
"description": "🚀 A lightweight and fast Node.JS HTTP Client",
|
||||||
"author": "Wessel \"wesselgame\" T <discord@go2it.eu>",
|
"author": "Wessel \"wesselgame\" T <discord@go2it.eu>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "createRequest.js",
|
"main": "lib/index.js",
|
||||||
"typings": "index.d.ts",
|
|
||||||
"files": [
|
"files": [
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
"createRequest.js",
|
"lib/"
|
||||||
"model/",
|
|
||||||
"index.d.ts"
|
|
||||||
],
|
],
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://www.github.com/wumpusapp/wumpfetch/issues"
|
"url": "https://www.github.com/PassTheWessel/wumpfetch/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://www.github.com/wumpusapp/wumpfetch#readme",
|
"homepage": "https://www.github.com/PassTheWessel/wumpfetch#readme",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://www.github.com/wumpusapp/wumpfetch"
|
"url": "https://www.github.com/PassTheWessel/wumpfetch"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"http",
|
"http",
|
||||||
@@ -31,11 +28,9 @@
|
|||||||
"patch",
|
"patch",
|
||||||
"lightweight"
|
"lightweight"
|
||||||
],
|
],
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.0",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-minify": "^3.1.0",
|
"gulp-minify": "^3.1.0"
|
||||||
"lumah": "^0.0.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
test.js
21
test.js
@@ -1,21 +0,0 @@
|
|||||||
const u = require('util');
|
|
||||||
const l = require('lumah');
|
|
||||||
const w = require('./createRequest.js');
|
|
||||||
|
|
||||||
l.register('Fetch cat image A', async (end) => {
|
|
||||||
const r = await w({ url: 'https://aws.random.cat/meow', parse: 'json' }).send();
|
|
||||||
end(r.statusCode === 200 ? true : false, r.statusCode === 200 ? u.inspect(r.body) : r.statusCode);
|
|
||||||
});
|
|
||||||
|
|
||||||
l.register('Fetch cat image B', (end) => {
|
|
||||||
w({ url: 'https://aws.random.cat/meow', parse: 'json' }).send().then((r) => {
|
|
||||||
end(r.statusCode === 200 ? true : false, r.statusCode === 200 ? u.inspect(r.body) : r.statusCode)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
l.register('Fetch cat image C', async (end) => {
|
|
||||||
const r = await w.get({ url: 'https://aws.random.cat/meow', parse: 'json' }).send();
|
|
||||||
end(r.statusCode === 200 ? true : false, r.statusCode === 200 ? u.inspect(r.body) : r.statusCode);
|
|
||||||
});
|
|
||||||
|
|
||||||
l.start();
|
|
||||||
Reference in New Issue
Block a user