From 390ee2396fdad175686b6e02bbbf64ecdc0b4fef Mon Sep 17 00:00:00 2001 From: grullo90 Date: Fri, 22 Dec 2017 16:08:30 +0100 Subject: [PATCH] Release 1.2.0 --- bower.json | 2 +- dist/xp-request.js | 2 +- lib/index.js | 137 +++++++++++++++++++++++---------------------- package.json | 7 ++- webpack.config.js | 11 +--- xp-request.html | 3 +- 6 files changed, 83 insertions(+), 79 deletions(-) diff --git a/bower.json b/bower.json index 82d8be5..f0117a8 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "xp-request", "description": "A class used to provide XHR functionality", - "version": "1.1.1", + "version": "1.2.0", "license": "BSD-3-Clause", "homepage": "https://expandjs.com/classes/xp-request", diff --git a/dist/xp-request.js b/dist/xp-request.js index 6a4e1e7..f577fcb 100644 --- a/dist/xp-request.js +++ b/dist/xp-request.js @@ -1 +1 @@ -!function(t){function e(n){if(s[n])return s[n].exports;var i=s[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var s={};e.m=t,e.c=s,e.i=function(t){return t},e.d=function(t,s,n){e.o(t,s)||Object.defineProperty(t,s,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var s=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(s,"a",s),s},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=2)}([function(t,e,s){(function(e){const n="undefined"!=typeof window?window:e,i="undefined"!=typeof window?null:s(6),r="undefined"!=typeof window?null:s(7),o="undefined"!=typeof window?{}:i.STATUS_CODES,h=n.location||{},u=n.XP||s(3),a=n.XPBuffer||s(4),d=n.XPEmitter||s(5);t.exports=n.XPRequest=new u.Class("XPRequest",{extends:d,initialize:{promise:!0,value(t,e){u.attempt(e=>{d.call(this);u.isObject(t)||(t={url:t});u.isFalsy(t.url)||Object.assign(t,u.pick(u.parseURL(t.url),["hostname","path","port","protocol"]));this.downLoaded=0;this.chunks=[];this.state="idle";this.options=t;this.headers=this.options.headers||{};this.hostname=this.options.hostname||h.hostname||"";this.keepAlive=this.options.keepAlive||0;this.method=this.options.method||"GET";this.parser=this.options.parser||"json";this.path=this.options.path||"";this.port=this.options.port||!this.options.hostname&&h.port||null;this.protocol=this.options.protocol||!this.options.hostname&&h.protocol||"http:";this.url=u.toURL({hostname:this.hostname,pathname:this.pathname,port:this.port,protocol:this.protocol,search:this.search});this._handleDownload=this._handleDownload.bind(this);this._handleEnd=this._handleEnd.bind(this,e);this._handleError=this._handleError.bind(this,e);this._handleResponse=this._handleResponse.bind(this,e)},e)}},header(t,e){if(u.assertArgument(u.isString(t,!0),1,"string"),u.assertArgument(u.isVoid(e)||u.isFalse(e)||u.isInput(e,!0),2,"string"),!u.isDefined(e))return this.headers[t];"idle"===this.state&&(e?this.headers[t]=e:delete this.headers[t])},abort:{callback:!0,value(t){return this.tsAbort||!this.tsSubmit?void t(null,!1):(this.adaptee.abort(),this.state="aborted",this.tsAbort=Date.now(),t(null,!0),this)}},submit:{callback:!0,value(t,e){if(!(u.isVoid(t)||a.isBuffer(t)||u.isInput(t)||u.isCollection(t)))return void e(u.error(400));if(!this.tsSubmit){this.ready(e);let s=["PATCH","POST","PUT"].includes(this.method),n=s?"":u.toQueryString(t,!0),o=s?t:void 0;if(o&&u.isCollection(t)&&!a.isBuffer(t)&&(o=JSON.stringify(t)),i){let t=this.adaptee=(this.protocol.startsWith("https")?r:i).request({hostname:this.hostname,keepAlive:this.keepAlive>0,keepAliveMsecs:this.keepAlive,method:this.method,path:this.pathname+(n||this.search),port:this.port,protocol:this.protocol,withCredentials:!1});Object.keys(this.headers).forEach(e=>u.isInput(this.headers[e],!0)&&t.setHeader(e,this.headers[e])),t.on("error",this._handleError),t.on("response",this._handleResponse)}if(!i){let t=this.adaptee=new XMLHttpRequest;t.open(this.method,n?`${this.url.replace(/\?.*/,``)}${n}`:this.url,!0),Object.keys(this.headers).forEach(e=>u.isInput(this.headers[e],!0)&&t.setRequestHeader(e,this.headers[e])),t.addEventListener("progress",this._handleResponse),t.addEventListener("progress",this._handleDownload),t.addEventListener("load",this._handleResponse),t.addEventListener("load",this._handleEnd),t.addEventListener("error",this._handleError),t.upload.addEventListener("error",this._handleError)}return this.state="pending",this.tsSubmit=Date.now(),this.adaptee[i?"end":"send"](o),this.emit("submit",t),this}}},adaptee:{set(t){return this.adaptee||t},validate(t){return!u.isObject(t)&&"Object"}},chunks:{set(t){return this.chunks||t},validate(t){return!u.isArray(t)&&"Array"}},data:{set(t){return u.isDefined(this.data)?this.data:t}},downLoaded:{set(t){return t},validate(t){return!u.isInt(t,!0)&&"number"}},downRatio:{get(){return u.isVoid(this.downTotal)?null:this.downTotal?this.downLoaded/this.downTotal:1}},downTotal:{set(t){return u.isDefined(this.downTotal)?this.downTotal:t},validate(t){return!u.isNull(t)&&!u.isInt(t,!0)&&"number"}},error:{set(t){return u.isDefined(this.error)?this.error:t},validate(t){return!u.isNull(t)&&!u.isObject(t)&&"Object"}},headers:{set(t){return this.headers||u.isObject(t)&&u.cloneDeep(t)},validate(t){return!u.isObject(t)&&"Object"}},host:{get(){return`${this.hostname||``}${this.port?`:${this.port}`:``}`}},hostname:{set(t){return this.hostname||t},validate(t){return!u.isString(t,!0)&&"string"}},keepAlive:{set(t){return u.isDefined(this.keepAlive)?this.keepAlive:t},validate(t){return!u.isInt(t,!0)&&"number"}},method:{set(t){return this.method||u.upperCase(t)},validate(t){return!u.isString(t,!0)&&"string"}},parser:{set(t){return this.parser||t},validate(t){return!this.parsers.includes(t)&&"string"}},parsers:{frozen:!0,writable:!1,value:["buffer","json","text"]},path:{set(t){return u.isDefined(this.path)?this.path:t},then(t){let e=t.match(/([^?]*)(.*)/);this.pathname=e[1],this.query=e[2].slice(1)},validate(t){return!u.isString(t)&&"string"}},pathname:{set(t){return u.isDefined(this.pathname)?this.pathname:t},validate(t){return!u.isString(t)&&"string"}},port:{set(t){return u.isDefined(this.port)?this.port:t},validate(t){return!u.isNull(t)&&!u.isNumeric(t,!0)&&"number"}},protocol:{set(t){return this.protocol||t},validate(t){return!u.isString(t,!0)&&"string"}},query:{set(t){return u.isDefined(this.query)?this.query:t},validate(t){return!u.isString(t)&&"string"}},response:{set(t){return this.response||t},validate(t){return!u.isObject(t)&&"Object"}},search:{get(){return this.query?`?${this.query}`:``}},state:{set(t){return t},then(t){return"idle"!==t&&this.emit("state",t)},validate(t){return!this.states.includes(t)&&"string"}},states:{frozen:!0,writable:!1,value:["aborted","complete","failed","idle","pending"]},statusCode:{set(t){return this.statusCode||t},validate(t){return!u.isInt(t,!0)&&"number"}},statusMessage:{set(t){return u.isDefined(this.statusMessage)?this.statusMessage:t},validate(t){return!u.isNull(t)&&!u.isString(t)&&"string"}},time:{get(){return this.tsData?this.tsData-this.tsSubmit:void 0}},tsAbort:{set(t){return this.tsAbort||t},validate(t){return!u.isInt(t,!0)&&"number"}},tsData:{set(t){return this.tsData||t},validate(t){return!u.isInt(t,!0)&&"number"}},tsResponse:{set(t){return this.tsResponse||t},validate(t){return!u.isInt(t,!0)&&"number"}},tsSubmit:{set(t){return this.tsSubmit||t},validate(t){return!u.isInt(t,!0)&&"number"}},url:{set(t){return this.url||t},validate(t){return!u.isString(t,!0)&&"string"}},_handleDownload(t){i&&"buffer"!==this.parser&&this.chunks.push(t),this.emit("download",this.downLoaded+=i?a.byteLength(t):t.loaded,this.downTotal)},_handleEnd(t,e){let s=this.error||"buffer"===this.parser?null:i?this.chunks.join(""):e.target.response,n=this.error?"failed":"complete";"json"!==this.parser||this.error||(s=u.toDefined(u.parseJSON(s.toString()))),this.data=s,this.state=n,this.tsData=Date.now(),this.emit(this.error?"error":"data",this.error||s),"buffer"!==this.parser&&t(this.error,s)},_handleError(t,e){this.error=u.error(0,i?e.message:"Request not sent."),this.state="failed",this.emit("error",this.error),t(this.error,null)},_handleResponse(t,e){u.isDefined(this.statusCode)||(this.response=i?e:e.target,this.statusCode=this.response[i?"statusCode":"status"]||502,this.statusMessage=this.response[i?"statusMessage":"statusText"]||o[this.statusCode]||null,this.error=this.statusCode>=400?u.error(this.statusCode,this.statusMessage):null,this.downTotal=u.toDefined(u.toFinite(i?this.response.headers["content-length"]:this.response.getResponseHeader("Content-Length"))),this.tsResponse=Date.now(),i&&this.response.on("data",this._handleDownload),i&&this.response.on("end",this._handleEnd),this.emit("response",this.response),"buffer"===this.parser&&t(this.error,this.error?null:this.response))}})}).call(e,s(1))},function(t,e){var s;s=function(){return this}();try{s=s||Function("return this")()||(0,eval)("this")}catch(t){"object"==typeof window&&(s=window)}t.exports=s},function(t,e,s){t.exports=s(0)},function(t,e){t.exports=XP},function(t,e){t.exports=XPBuffer},function(t,e){t.exports=XPEmitter},function(t,e){t.exports=http},function(t,e){t.exports=https}]); \ No newline at end of file +!function(t){function e(i){if(s[i])return s[i].exports;var r=s[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var s={};e.m=t,e.c=s,e.d=function(t,s,i){e.o(t,s)||Object.defineProperty(t,s,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var s=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(s,"a",s),s},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,s){t.exports=s(1)},function(t,e,s){(function(e){const i="undefined"!=typeof window?window:e,r="undefined"!=typeof window?null:s(3),n="undefined"!=typeof window?null:s(4),o="undefined"!=typeof window?{}:r.STATUS_CODES,a=i.location||{},h=i.XP||s(5),d=i.XPBuffer||s(6),l=i.XPEmitter||s(7);t.exports=new h.Class("XPRequest",{extends:l,initialize:{promise:!0,value(t,e){l.call(this),h.isObject(t)||(t={url:t}),h.isFalsy(t.url)||Object.assign(t,h.pick(h.parseURL(t.url),["hostname","path","port","protocol"])),this.downLoaded=0,this.chunks=[],this.state="idle",this.options=t,this.headers=this.options.headers||{},this.hostname=this.options.hostname||a.hostname||"",this.keepAlive=this.options.keepAlive||0,this.method=this.options.method||"GET",this.parser=this.options.parser||"json",this.path=this.options.path||"",this.port=this.options.port||!this.options.hostname&&a.port||null,this.protocol=this.options.protocol||!this.options.hostname&&a.protocol||"http:",this.url=h.toURL({hostname:this.hostname,pathname:this.pathname,port:this.port,protocol:this.protocol,search:this.search}),this._handleDownload=this._handleDownload.bind(this),this._handleEnd=this._handleEnd.bind(this,e),this._handleError=this._handleError.bind(this,e),this._handleResponse=this._handleResponse.bind(this,e)}},getHeader(t){return h.assertArgument(h.isString(t,!0),1,"string"),this.headers[t]},setHeader(t,e){h.assertArgument(h.isString(t,!0),1,"string"),h.assertArgument(h.isVoid(e)||h.isFalse(e)||h.isInput(e),2,"string"),"idle"===this.state&&(h.isInput(e,!0)?this.headers[t]=e.toString():delete this.headers[t])},abort:{callback:!0,value(t){!this.tsAbort&&this.tsSubmit?(this.adaptee.abort(),this.state="aborted",this.tsAbort=Date.now(),t(null,!0)):t(null,!1)}},submit:{callback:!0,value(t,e){if(!(h.isVoid(t)||d.isBuffer(t)||h.isInput(t)||h.isCollection(t)))return void e(h.error(400));if(this.tsSubmit)return;this.ready(e);let s=["PATCH","POST","PUT"].includes(this.method),i=s?"":h.toQueryString(t,!0),o=s?t:void 0;if(o&&h.isCollection(t)&&!d.isBuffer(t)&&(o=JSON.stringify(t)),r){let t=this.protocol.startsWith("https")?n:r,e=this.adaptee=t.request({hostname:this.hostname,keepAlive:this.keepAlive>0,keepAliveMsecs:this.keepAlive,method:this.method,path:this.pathname+(i||this.search),port:this.port,protocol:this.protocol,withCredentials:!1});Object.keys(this.headers).forEach(t=>h.isInput(this.headers[t],!0)&&e.setHeader(t,this.headers[t])),e.once("error",this._handleError),e.once("response",this._handleResponse)}if(!r){let t=this.adaptee=new XMLHttpRequest;t.open(this.method,i?`${this.url.replace(/\?.*/,"")}${i}`:this.url,!0),Object.keys(this.headers).forEach(e=>h.isInput(this.headers[e],!0)&&t.setRequestHeader(e,this.headers[e])),t.addEventListener("progress",this._handleResponse),t.addEventListener("progress",this._handleDownload),t.addEventListener("load",this._handleResponse),t.addEventListener("load",this._handleEnd),t.addEventListener("error",this._handleError),t.upload.addEventListener("error",this._handleError)}this.state="pending",this.tsSubmit=Date.now(),this.adaptee[r?"end":"send"](o),this.emit("submit",t)}},adaptee:{set(t){return this.adaptee||t},validate:t=>!h.isObject(t)&&"Object"},chunks:{set(t){return this.chunks||t},validate:t=>!h.isArray(t)&&"Array"},data:{set(t){return h.isDefined(this.data)?this.data:t}},downLoaded:{set:t=>t,validate:t=>!h.isInt(t,!0)&&"number"},downRatio:{get(){return h.isVoid(this.downTotal)?null:this.downTotal?this.downLoaded/this.downTotal:1}},downTotal:{set(t){return h.isDefined(this.downTotal)?this.downTotal:t},validate:t=>!h.isNull(t)&&!h.isInt(t,!0)&&"number"},error:{set(t){return h.isDefined(this.error)?this.error:t},validate:t=>!h.isNull(t)&&!h.isObject(t)&&"Object"},headers:{set(t){return this.headers||h.isObject(t)&&h.cloneDeep(t)},validate:t=>!h.isObject(t)&&"Object"},host:{get(){return`${this.hostname||""}${this.port?`:${this.port}`:""}`}},hostname:{set(t){return this.hostname||t},validate:t=>!h.isString(t,!0)&&"string"},keepAlive:{set(t){return h.isDefined(this.keepAlive)?this.keepAlive:t},validate:t=>!h.isInt(t,!0)&&"number"},method:{set(t){return this.method||h.upperCase(t)},validate:t=>!h.isString(t,!0)&&"string"},parser:{set(t){return this.parser||t},validate(t){return!this.parsers.includes(t)&&"string"}},parsers:{frozen:!0,writable:!1,value:["buffer","json","text"]},path:{set(t){return h.isDefined(this.path)?this.path:t},then(t){let e=t.match(/([^?]*)(.*)/);this.pathname=e[1],this.query=e[2].slice(1)},validate:t=>!h.isString(t)&&"string"},pathname:{set(t){return h.isDefined(this.pathname)?this.pathname:t},validate:t=>!h.isString(t)&&"string"},port:{set(t){return h.isDefined(this.port)?this.port:t},validate:t=>!h.isNull(t)&&!h.isNumeric(t,!0)&&"number"},protocol:{set(t){return this.protocol||t},validate:t=>!h.isString(t,!0)&&"string"},query:{set(t){return h.isDefined(this.query)?this.query:t},validate:t=>!h.isString(t)&&"string"},response:{set(t){return this.response||t},validate:t=>!h.isObject(t)&&"Object"},search:{get(){return this.query?`?${this.query}`:""}},state:{set:t=>t,then(t){return"idle"!==t&&this.emit("state",t)},validate(t){return!this.states.includes(t)&&"string"}},states:{frozen:!0,writable:!1,value:["aborted","complete","failed","idle","pending"]},statusCode:{set(t){return this.statusCode||t},validate:t=>!h.isInt(t,!0)&&"number"},statusMessage:{set(t){return h.isDefined(this.statusMessage)?this.statusMessage:t},validate:t=>!h.isNull(t)&&!h.isString(t)&&"string"},time:{get(){return this.tsData?this.tsData-this.tsSubmit:void 0}},tsAbort:{set(t){return this.tsAbort||t},validate:t=>!h.isInt(t,!0)&&"number"},tsData:{set(t){return this.tsData||t},validate:t=>!h.isInt(t,!0)&&"number"},tsResponse:{set(t){return this.tsResponse||t},validate:t=>!h.isInt(t,!0)&&"number"},tsSubmit:{set(t){return this.tsSubmit||t},validate:t=>!h.isInt(t,!0)&&"number"},url:{set(t){return this.url||t},validate:t=>!h.isString(t,!0)&&"string"},_handleDownload(t){r&&"buffer"!==this.parser&&this.chunks.push(t),this.emit("download",this.downLoaded+=r?h.byteLength(t):t.loaded,this.downTotal)},_handleEnd(t,e){let s="buffer"!==this.parser?r?this.chunks.join(""):e.target.response:null;this.data="json"===this.parser?h.toDefined(h.parseJSON(s.toString())):s,this.state=this.error?"failed":"complete",this.tsData=Date.now(),this.emit(this.error?"error":"data",this.error||this.data),"buffer"!==this.parser&&t(this.error,this.data)},_handleError(t,e){this.error=h.error(0,r?e.message:"Request not sent."),this.state="failed",this.emit("error",this.error),t(this.error,null)},_handleResponse(t,e){h.isDefined(this.statusCode)||(this.response=r?e:e.target,this.statusCode=this.response[r?"statusCode":"status"]||502,this.statusMessage=this.response[r?"statusMessage":"statusText"]||o[this.statusCode]||null,this.error=this.statusCode>=400?h.error(this.statusCode,this.statusMessage):null,this.downTotal=h.toDefined(h.toFinite(r?this.response.headers["content-length"]:this.response.getResponseHeader("Content-Length"))),this.tsResponse=Date.now(),r&&this.response.on("data",this._handleDownload),r&&this.response.once("end",this._handleEnd),this.emit("response",this.response),"buffer"===this.parser&&t(this.error,this.error?null:this.response))}}),"undefined"!=typeof window&&(window.XPRequest=t.exports)}).call(e,s(2))},function(t,e){var s;s=function(){return this}();try{s=s||Function("return this")()||(0,eval)("this")}catch(t){"object"==typeof window&&(s=window)}t.exports=s},function(t,e){t.exports=http},function(t,e){t.exports=https},function(t,e){t.exports=XP},function(t,e){t.exports=XPBuffer},function(t,e){t.exports=XPEmitter}]); \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 8b6fb5d..dda0fb0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -23,12 +23,11 @@ const env = typeof window !== "undefined" ? window : global, * * @class XPRequest * @extends XPEmitter /bower_components/xp-emitter/lib/index.js - * @since 1.0.0 * @description A class used to provide XHR functionality * @keywords nodejs, expandjs * @source https://github.com/expandjs/xp-request/blob/master/lib/index.js */ -module.exports = env.XPRequest = new XP.Class('XPRequest', { +module.exports = new XP.Class('XPRequest', { // EXTENDS extends: XPEmitter, @@ -98,65 +97,75 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { promise: true, value(options, resolver) { - // Attempting - XP.attempt(resolver => { - - // Super - XPEmitter.call(this); - - // Overriding - if (!XP.isObject(options)) { options = {url: options}; } - if (!XP.isFalsy(options.url)) { Object.assign(options, XP.pick(XP.parseURL(options.url), ['hostname', 'path', 'port', 'protocol'])); } - - // Setting - this.downLoaded = 0; - this.chunks = []; - this.state = 'idle'; - this.options = options; - this.headers = this.options.headers || {}; - this.hostname = this.options.hostname || location.hostname || ''; - this.keepAlive = this.options.keepAlive || 0; - this.method = this.options.method || 'GET'; - this.parser = this.options.parser || 'json'; - this.path = this.options.path || ''; - this.port = this.options.port || (!this.options.hostname && location.port) || null; - this.protocol = this.options.protocol || (!this.options.hostname && location.protocol) || 'http:'; - this.url = XP.toURL({hostname: this.hostname, pathname: this.pathname, port: this.port, protocol: this.protocol, search: this.search}); - - // Binding - this._handleDownload = this._handleDownload.bind(this); - this._handleEnd = this._handleEnd.bind(this, resolver); - this._handleError = this._handleError.bind(this, resolver); - this._handleResponse = this._handleResponse.bind(this, resolver); - - }, resolver); + // Super + XPEmitter.call(this); + + // Overriding + if (!XP.isObject(options)) { options = {url: options}; } + if (!XP.isFalsy(options.url)) { Object.assign(options, XP.pick(XP.parseURL(options.url), ['hostname', 'path', 'port', 'protocol'])); } + + // Setting + this.downLoaded = 0; + this.chunks = []; + this.state = 'idle'; + this.options = options; + this.headers = this.options.headers || {}; + this.hostname = this.options.hostname || location.hostname || ''; + this.keepAlive = this.options.keepAlive || 0; + this.method = this.options.method || 'GET'; + this.parser = this.options.parser || 'json'; + this.path = this.options.path || ''; + this.port = this.options.port || !this.options.hostname && location.port || null; + this.protocol = this.options.protocol || !this.options.hostname && location.protocol || 'http:'; + this.url = XP.toURL({hostname: this.hostname, pathname: this.pathname, port: this.port, protocol: this.protocol, search: this.search}); + + // Binding + this._handleDownload = this._handleDownload.bind(this); + this._handleEnd = this._handleEnd.bind(this, resolver); + this._handleError = this._handleError.bind(this, resolver); + this._handleResponse = this._handleResponse.bind(this, resolver); } }, /*********************************************************************/ /** - * Get or set a header. + * Get a header. * - * @method header + * @method getHeader * @param {string} name - * @param {number | string} [value] - * @returns {number | string} + * @returns {string} */ - header(name, value) { + getHeader(name) { // Asserting XP.assertArgument(XP.isString(name, true), 1, 'string'); - XP.assertArgument(XP.isVoid(value) || XP.isFalse(value) || XP.isInput(value, true), 2, 'string'); - // Getting - if (!XP.isDefined(value)) { return this.headers[name]; } + // Returning + return this.headers[name]; + }, - // Checking + /** + * Set a header. + * + * @method setHeader + * @param {string} name + * @param {string} [value] + */ + setHeader(name, value) { + + // Asserting + XP.assertArgument(XP.isString(name, true), 1, 'string'); + XP.assertArgument(XP.isVoid(value) || XP.isFalse(value) || XP.isInput(value), 2, 'string'); + + // Preventing if (this.state !== 'idle') { return; } + // Removing + if (!XP.isInput(value, true)) { delete this.headers[name]; return; } + // Setting - if (value) { this.headers[name] = value; } else { delete this.headers[name]; } + this.headers[name] = value.toString(); }, /*********************************************************************/ @@ -166,7 +175,6 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { * * @method abort * @param {Function} [callback] - * @returns {Object} */ abort: { callback: true, @@ -184,9 +192,6 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { // Callback callback(null, true); - - // Chaining - return this; } }, @@ -196,7 +201,6 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { * @method submit * @param {*} [data] * @param {Function} [callback] - * @returns {Object} */ submit: { callback: true, @@ -222,8 +226,11 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { // CASE: server if (http) { + // Let + let protocol = this.protocol.startsWith('https') ? https : http; + // Adapting - let request = this.adaptee = (this.protocol.startsWith('https') ? https : http).request({ + let request = this.adaptee = protocol.request({ hostname: this.hostname, keepAlive: this.keepAlive > 0, keepAliveMsecs: this.keepAlive, @@ -238,8 +245,8 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { Object.keys(this.headers).forEach(key => XP.isInput(this.headers[key], true) && request.setHeader(key, this.headers[key])); // Listening - request.on('error', this._handleError); - request.on('response', this._handleResponse); + request.once('error', this._handleError); + request.once('response', this._handleResponse); } // CASE: browser @@ -272,9 +279,6 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { // Emitting this.emit('submit', data); - - // Chaining - return this; } }, @@ -654,29 +658,25 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { if (http && this.parser !== 'buffer') { this.chunks.push(event); } // Emitting - this.emit('download', this.downLoaded += http ? XPBuffer.byteLength(event) : event.loaded, this.downTotal); + this.emit('download', this.downLoaded += http ? XP.byteLength(event) : event.loaded, this.downTotal); }, // HANDLER _handleEnd(resolver, event) { // Let - let data = this.error || this.parser === 'buffer' ? null : (http ? this.chunks.join('') : event.target.response), - state = this.error ? 'failed' : 'complete'; - - // Parsing - if (this.parser === 'json' && !this.error) { data = XP.toDefined(XP.parseJSON(data.toString())); } + let data = this.parser !== 'buffer' ? (http ? this.chunks.join('') : event.target.response) : null; // Setting - this.data = data; - this.state = state; + this.data = this.parser === 'json' ? XP.toDefined(XP.parseJSON(data.toString())) : data; + this.state = this.error ? 'failed' : 'complete'; this.tsData = Date.now(); // Emitting - this.emit(this.error ? 'error' : 'data', this.error || data); + this.emit(this.error ? 'error' : 'data', this.error || this.data); // Resolving - if (this.parser !== 'buffer') { resolver(this.error, data); } + if (this.parser !== 'buffer') { resolver(this.error, this.data); } }, // HANDLER @@ -709,7 +709,7 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { // Listening if (http) { this.response.on('data', this._handleDownload); } - if (http) { this.response.on('end', this._handleEnd); } + if (http) { this.response.once('end', this._handleEnd); } // Emitting this.emit('response', this.response); @@ -718,3 +718,8 @@ module.exports = env.XPRequest = new XP.Class('XPRequest', { if (this.parser === 'buffer') { resolver(this.error, this.error ? null : this.response); } } }); + +/*********************************************************************/ + +// Globalizing +if (typeof window !== "undefined") { window.XPRequest = module.exports; } diff --git a/package.json b/package.json index 32fa2ff..2349564 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xp-request", "description": "A class used to provide XHR functionality", - "version": "1.1.1", + "version": "1.2.0", "license": "BSD-3-Clause", "homepage": "https://expandjs.com/classes/xp-request", "author": "ExpandJS (https://expandjs.com)", @@ -23,6 +23,11 @@ "xp-emitter": "^1.0.0" }, + "devDependencies": { + "uglifyjs-webpack-plugin": "^1.1.0", + "webpack": "^3.10.0" + }, + "scripts": { "build": "webpack" } diff --git a/webpack.config.js b/webpack.config.js index a1a448e..fa3c20d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,18 +4,13 @@ const Uglify = require('uglifyjs-webpack-plugin'); // Exporting module.exports = { entry: './index.js', + output: {filename: 'xp-request.js', path: `${__dirname}/dist`}, + plugins: [new Uglify({uglifyOptions: {output: {comments: /^$/}}})], externals: { 'expandjs': 'XP', 'http': 'http', 'https': 'https', 'xp-buffer': 'XPBuffer', 'xp-emitter': 'XPEmitter' - }, - output: { - filename: 'xp-request.js', - path: `${__dirname}/dist` - }, - plugins: [ - new Uglify({compress: {warnings: false}, output: {comments: false}}) - ] + } }; diff --git a/xp-request.html b/xp-request.html index 96a35a9..f58d8b9 100644 --- a/xp-request.html +++ b/xp-request.html @@ -10,11 +10,10 @@ A class used to provide XHR functionality. @class xp-request -@since 1.0.0 @description A class used to provide XHR functionality @keywords nodejs, expandjs -@homepage https://expandjs.com/components/xp-request +@homepage https://expandjs.com/classes/xp-request @repository https://github.com/expandjs/xp-request -->