diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..69f9f14 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,64 @@ +{ + "env": { + "es6": true, + "amd": true, + "node": true, + "mongo": true, + "jquery": true, + "browser": true, + "commonjs": true + }, + "parserOptions": { + "ecmaVersion": 9, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true, + "forOf": true, + "spread": true, + "modules": true, + "classes": true, + "generators": true, + "restParams": true, + "regexUFlag": true, + "regexYFlag": true, + "globalReturn": true, + "destructuring": true, + "impliedStrict": true, + "blockBindings": true, + "defaultParams": true, + "octalLiterals": true, + "arrowFunctions": true, + "binaryLiterals": true, + "templateStrings": true, + "superInFunctions": true, + "unicodeCodePointEscapes": true, + "objectLiteralShorthandMethods": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": true, + "objectLiteralShorthandProperties": true + } + }, + "plugins": [], + "rules": { + "semi": "warn", + "indent": [ 0, 2 ], + "strict": "off", + "eqeqeq": "error", + "no-var": "warn", + "no-undef": "warn", + "valid-jsdoc": "warn", + "comma-dangle": "warn", + "no-dupe-args": "warn", + "no-dupe-keys": "warn", + "require-await": "warn", + "spaced-comment": "error", + "space-in-parens": "error", + "no-global-assign": "warn", + "no-duplicate-imports": "error", + "no-dupe-class-members": "error" + }, + "globals": { + "_config": false, + "console": false + } +} \ No newline at end of file diff --git a/__test__/main.js b/__test__/main.js index 1a399a0..5a95f8f 100644 --- a/__test__/main.js +++ b/__test__/main.js @@ -1,14 +1,16 @@ const util = require('util'); const wump = require('../lib'); -console.log(`Using wumpfetch v${wump.version} [${wump.userAgent}]\n\n`); +console.log(`Using wumpfetch v${wump.version} [${wump.userAgent}]`); ;(async() => { const requests = [ await wump({ url: 'https://jsonplaceholder.typicode.com/todos/1', parse: 'json' }).send(), - await wump('https://jsonplaceholder.typicode.com/todos/1', { chaining: false }) + await wump('https://jsonplaceholder.typicode.com/todos/1', { chain: false }), + await wump('https://jsonplaceholder.typicode.com/posts', { chain: false, method: 'POST', body: { title: 'yeet', body: 'us', userId: 1 } }) ]; - console.log(`Test 1: \n${util.inspect(requests[0].body)}\n\n`); - console.log(`Test 2: \n${util.inspect(requests[1].json())}\n\n`); + console.log(`Test 1: \n${util.inspect(requests[0].body)}\n`); + console.log(`Test 2: \n${util.inspect(requests[1].json())}\n`); + console.log(`Test 3: \n${util.inspect(requests[2].parse())}\n`); })(); \ No newline at end of file diff --git a/dist/wumpfetch.concat.js b/dist/wumpfetch.concat.js index 7bdcd78..276530c 100644 --- a/dist/wumpfetch.concat.js +++ b/dist/wumpfetch.concat.js @@ -142,7 +142,7 @@ const WumpRequest = class WumpRequest { if (this.o.compressed) { 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; diff --git a/lib/index.js b/lib/index.js index 42486b1..c9d6716 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,18 +1,15 @@ const req = require('./model/WumpRequest'); -const pkg = require('../package.json'); - const common = [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH' ]; +const metaData = require('../package.json'); -module.exports = (url, method) => { - return new req(url, method); -}; +module.exports = (url, method) => { return new req(url, method); }; -common.forEach((v) => { - module.exports[v.toLowerCase()] = (url, method) => { - if (typeof url === 'string') return new req(url, { method: v, ...method }); - else return new req({ method: v, ...url }, method); - } -}); +for (const method of common) { + module.exports[method.toLowerCase()] = (url, method) => { + if (typeof url === 'string') return new req(url, { method: method, ...method }); + else return new req({ method: method, ...url }, method); + }; +} -module.exports.version = pkg.version; -module.exports.userAgent = `${pkg.name}/${pkg.version} (${pkg.repository.url})`; \ No newline at end of file +module.exports.version = metaData.version; +module.exports.userAgent = `${metaData.name}/${metaData.version} (${metaData.repository.url})`; \ No newline at end of file diff --git a/lib/model/WumpRequest.js b/lib/model/WumpRequest.js index 87e836f..4e5d2e6 100644 --- a/lib/model/WumpRequest.js +++ b/lib/model/WumpRequest.js @@ -1,75 +1,73 @@ -const u = require('url'); -const h = require('http'); -const hs = require('https'); -const pa = require('path'); -const qs = require('querystring'); -const zl = require('zlib'); - -const pkg = require('../../package.json'); -const WumpRes = require('./WumpResponse'); +const zlib = require('zlib'); +const http = require('http'); +const https = require('https'); +const { URL } = require('url'); +const { stringify } = require('querystring'); +const { join: pJoin } = require('path'); const w = require('../index'); -const c = [ 'gzip', 'deflate' ]; +const WumpRes = require('./WumpResponse'); +const metaData = require('../../package.json'); +const compressions = [ 'gzip', 'deflate' ]; + module.exports = 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 = { - 'm': typeof o === 'string' ? o : obj && o.method ? o.method : 'GET', - 'url': typeof url === 'string' ? new u.URL(url) : obj && typeof o.url === 'string' ? new u.URL(o.url) : url, - 'SDA': obj && typeof o.sendDataAs === 'string' ? o.sendDataAs : obj && o.data && typeof o.data === 'object' ? 'json' : undefined, - 'data': obj && o.body ? o.body : obj && o.data ? o.data : obj && o.json ? o.json : obj && o.form ? qs.stringify(o.form) : undefined, - 'parse': obj && o.parse ? o.parse : undefined, - 'chain': obj && typeof o.chaining === 'boolean' ? o.chaining : true, - 'follow': !!(obj && o.followRedirects), - 'rHeaders': obj && typeof o.headers === 'object' ? o.headers : {}, - 'streamed': !!(obj && o.streamed), - 'compressed': !!(obj && o.compressed), - 'timeoutTime': obj && typeof o.timeout === 'number' ? o.timeout : null, - 'coreOptions': obj && typeof o.coreOptions === 'object' ? o.coreOptions : {} + 'm': typeof o === 'string' ? o : (o.method || 'GET'), + 'url': typeof url === 'string' ? new URL(url) : typeof o.url === 'string' ? new URL(o.url) : url, + 'SDA': typeof o.sendDataAs === 'string' ? o.sendDataAs : o.data && typeof o.data === 'object' ? 'json' : undefined, + 'data': o.body || o.data || o.json || (o.form ? stringify(o.form) : undefined), + 'parse': o.parse, + 'chain': typeof o.chain === 'boolean' ? o.chain : true, + 'follow': !!(o.followRedirects), + 'rHeaders': typeof o.headers === 'object' ? o.headers : {}, + 'streamed': !!(o.streamed), + 'compressed': !!(o.compressed), + 'timeoutTime': typeof o.timeout === 'number' ? o.timeout : null, + 'coreOptions': 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') for (const key of Object.keys(o.core)) this.option(key, o.core[key]); if (!this.o.chain) return this.send(); return this; } - query (a, b) { - if (typeof a === 'object') Object.keys(a).forEach((v) => this.o.url.searchParams.append(v, a[v])); - else this.o.url.searchParams.append(a, b); + query (name, value) { + if (typeof a === 'object') for (const key of Object.keys(name)) this.o.url.searchParams.append(key, name[key]); + else this.o.url.searchParams.append(name, value); return this; } - body (data, SA) { - this.o.SDA = typeof data === 'object' && !SA && !Buffer.isBuffer(data) ? 'json' : (SA ? SA.toLowerCase() : 'buffer'); - this.o.data = this.SDA === 'form' ? qs.stringify(data) : (this.SDA === 'json' ? JSON.stringify(data) : data); + body (data, sendAs) { + this.o.SDA = typeof data === 'object' && !sendAs && !Buffer.isBuffer(data) ? 'json' : sendAs ? sendAs.toLowerCase() : 'buffer'; + this.o.data = this.sendAs === 'form' ? stringify(data) : this.SDA === 'json' ? JSON.stringify(data) : data; return this; } - header (a, b) { - if (typeof a === 'object') Object.keys(a).forEach((v) => this.o.rHeaders[v.toLowerCase()] = a[v]); - else this.o.rHeaders[a.toLowerCase()] = b; + header (name, value) { + if (typeof name === 'object') for (const key of Object.keys(name)) this.o.rHeaders[key.toLowerCase()] = name[key]; + else this.o.rHeaders[name.toLowerCase()] = value; return this; } compress () { 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'] = compressions.join(', '); return this; } path (p) { - this.o.url.pathname = pa.join(this.o.url.pathname, p); + this.o.url.pathname = pJoin(this.o.url.pathname, p); return this; } @@ -80,12 +78,12 @@ module.exports = class WumpRequest { return this; } - option (n, v) { - this.o.coreOptions[n] = v; + option (name, value) { + this.o.coreOptions[name] = value; return this; } - timeout (timeout) { + timeout (timeout = 0) { this.o.timeoutTime = timeout; return this; @@ -94,7 +92,7 @@ module.exports = class WumpRequest { send () { return new Promise((resolve, reject) => { if (this.o.data) { - if (!this.o.rHeaders.hasOwnProperty('user-agent')) this.o.rHeaders['User-Agent'] = w.userAgent || `${pkg.name}/${pkg.version} (${pkg.repository.urll})`; + if (!this.o.rHeaders.hasOwnProperty('user-agent')) this.o.rHeaders['User-Agent'] = w.userAgent || `${metaData.name}/${metaData.version} (${metaData.repository.url})`; if (this.o.SDA === 'json' && !this.o.rHeaders.hasOwnProperty('content-type')) this.o.rHeaders['Content-Type'] = 'application/json'; if (this.o.SDA === 'form') { @@ -107,19 +105,21 @@ module.exports = class WumpRequest { const options = { 'host': this.o.url.hostname, '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, 'headers': this.o.rHeaders, 'protocol': this.o.url.protocol, ...this.o.coreOptions - } + }; const handler = async (res) => { let stream = res; if (this.o.compressed) { - if (res.headers['content-encoding'] === 'gzip') stream = res.pipe(zl.createGunzip()); - else if (res.headers[ 'content-encoding'] === 'deflate') stream = res.pipe(zl.createInflate()); + switch (res.headers['content-encoding']) { + case 'gzip': stream = res.pipe(zlib.createGunzip()); break; + case 'defalte': stream = res.pipe(zlib.createInflate()); break; + } } let wumpRes; @@ -129,7 +129,7 @@ module.exports = class WumpRequest { wumpRes = new WumpRes(res); if (res.headers.hasOwnProperty('location') && this.o.follow) { - this.o.url = (new u.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); } @@ -137,9 +137,11 @@ module.exports = class WumpRequest { stream.on('data', (c) => wumpRes._addChunk(c)); stream.on('end', () => { if (this.o.parse) { - if (this.o.parse === 'json') wumpRes.body = JSON.parse(wumpRes.body); - else if (this.o.parse === 'text') wumpRes.body = wumpRes.body.toString(); - else wumpRes.body = wumpRes.body; + switch (this.o.parse) { + case 'json': wumpRes.body = JSON.parse(wumpRes.body); break; + case 'text': wumpRes.body = wumpRes.body.toString(); break; + default: wumpRes.body = wumpRes.body; + } } resolve(wumpRes); @@ -147,9 +149,11 @@ module.exports = class WumpRequest { } }; - if (this.o.url.protocol === 'http:') req = h.request(options, handler); - else if (this.o.url.protocol === 'https:') req = hs.request(options, handler); - else throw new Error(`Bad URL protocol: ${this.o.url.protocol}`); + switch (this.o.url.protocol) { + case 'http:': req = http.request(options, handler); break; + case 'https:': req = https.request(options, handler); break; + default: throw new Error(`Bad URL protocol: ${this.o.url.protocol}`); + } if (this.o.timeoutTime) { req.setTimeout(this.o.timeoutTime, () => { @@ -162,12 +166,10 @@ module.exports = class WumpRequest { 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); - } + else if (this.o.data instanceof Object) req.write(JSON.stringify(this.o.data)); + else req.write(this.o.data); } - + req.end(); }); } diff --git a/lib/model/WumpResponse.js b/lib/model/WumpResponse.js index bf3d801..703ea8b 100644 --- a/lib/model/WumpResponse.js +++ b/lib/model/WumpResponse.js @@ -2,7 +2,6 @@ module.exports = class WumpResponse { constructor (res) { this.body = Buffer.alloc(0); this.coreRes = res; - this.headers = res.headers; this.statusCode = res.statusCode; } @@ -12,19 +11,11 @@ module.exports = class WumpResponse { } parse () { - if (this.headers['content-type'] === 'application/json') return JSON.parse(this.body); + if (this.headers['content-type'].includes('application/json')) return JSON.parse(this.body); else return this.body.toString(); } - - buffer () { - return this.body; - } - text () { - return this.body.toString(); - } - - json () { - return JSON.parse(this.body); - } + text () { return this.body.toString(); } + json () { return JSON.parse(this.body); } + buffer () { return this.body; } }; diff --git a/package.json b/package.json index bfe453c..0b35568 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wumpfetch", - "version": "0.2.12", + "version": "0.2.13", "description": "🚀 A lightweight and fast Node.JS HTTP Client", "author": "Wessel \"wesselgame\" T ", "license": "MIT", @@ -33,8 +33,6 @@ "lightweight" ], "devDependencies": { - "gulp": "^4.0.0", - "gulp-concat": "^2.6.1", - "gulp-minify": "^3.1.0" + "eslint": "^5.16.0" } }