Front end of the Slack clone application.

superagent.js 46KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.superagent = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  2. function Agent() {
  3. this._defaults = [];
  4. }
  5. ["use", "on", "once", "set", "query", "type", "accept", "auth", "withCredentials", "sortQuery", "retry", "ok", "redirects",
  6. "timeout", "buffer", "serialize", "parse", "ca", "key", "pfx", "cert"].forEach(function(fn) {
  7. /** Default setting for all requests from this agent */
  8. Agent.prototype[fn] = function(/*varargs*/) {
  9. this._defaults.push({fn:fn, arguments:arguments});
  10. return this;
  11. }
  12. });
  13. Agent.prototype._setDefaults = function(req) {
  14. this._defaults.forEach(function(def) {
  15. req[def.fn].apply(req, def.arguments);
  16. });
  17. };
  18. module.exports = Agent;
  19. },{}],2:[function(require,module,exports){
  20. 'use strict';
  21. /**
  22. * Check if `obj` is an object.
  23. *
  24. * @param {Object} obj
  25. * @return {Boolean}
  26. * @api private
  27. */
  28. function isObject(obj) {
  29. return null !== obj && 'object' === typeof obj;
  30. }
  31. module.exports = isObject;
  32. },{}],3:[function(require,module,exports){
  33. 'use strict';
  34. /**
  35. * Module of mixed-in functions shared between node and client code
  36. */
  37. var isObject = require('./is-object');
  38. /**
  39. * Expose `RequestBase`.
  40. */
  41. module.exports = RequestBase;
  42. /**
  43. * Initialize a new `RequestBase`.
  44. *
  45. * @api public
  46. */
  47. function RequestBase(obj) {
  48. if (obj) return mixin(obj);
  49. }
  50. /**
  51. * Mixin the prototype properties.
  52. *
  53. * @param {Object} obj
  54. * @return {Object}
  55. * @api private
  56. */
  57. function mixin(obj) {
  58. for (var key in RequestBase.prototype) {
  59. obj[key] = RequestBase.prototype[key];
  60. }
  61. return obj;
  62. }
  63. /**
  64. * Clear previous timeout.
  65. *
  66. * @return {Request} for chaining
  67. * @api public
  68. */
  69. RequestBase.prototype.clearTimeout = function _clearTimeout(){
  70. clearTimeout(this._timer);
  71. clearTimeout(this._responseTimeoutTimer);
  72. delete this._timer;
  73. delete this._responseTimeoutTimer;
  74. return this;
  75. };
  76. /**
  77. * Override default response body parser
  78. *
  79. * This function will be called to convert incoming data into request.body
  80. *
  81. * @param {Function}
  82. * @api public
  83. */
  84. RequestBase.prototype.parse = function parse(fn){
  85. this._parser = fn;
  86. return this;
  87. };
  88. /**
  89. * Set format of binary response body.
  90. * In browser valid formats are 'blob' and 'arraybuffer',
  91. * which return Blob and ArrayBuffer, respectively.
  92. *
  93. * In Node all values result in Buffer.
  94. *
  95. * Examples:
  96. *
  97. * req.get('/')
  98. * .responseType('blob')
  99. * .end(callback);
  100. *
  101. * @param {String} val
  102. * @return {Request} for chaining
  103. * @api public
  104. */
  105. RequestBase.prototype.responseType = function(val){
  106. this._responseType = val;
  107. return this;
  108. };
  109. /**
  110. * Override default request body serializer
  111. *
  112. * This function will be called to convert data set via .send or .attach into payload to send
  113. *
  114. * @param {Function}
  115. * @api public
  116. */
  117. RequestBase.prototype.serialize = function serialize(fn){
  118. this._serializer = fn;
  119. return this;
  120. };
  121. /**
  122. * Set timeouts.
  123. *
  124. * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time.
  125. * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections.
  126. *
  127. * Value of 0 or false means no timeout.
  128. *
  129. * @param {Number|Object} ms or {response, deadline}
  130. * @return {Request} for chaining
  131. * @api public
  132. */
  133. RequestBase.prototype.timeout = function timeout(options){
  134. if (!options || 'object' !== typeof options) {
  135. this._timeout = options;
  136. this._responseTimeout = 0;
  137. return this;
  138. }
  139. for(var option in options) {
  140. switch(option) {
  141. case 'deadline':
  142. this._timeout = options.deadline;
  143. break;
  144. case 'response':
  145. this._responseTimeout = options.response;
  146. break;
  147. default:
  148. console.warn("Unknown timeout option", option);
  149. }
  150. }
  151. return this;
  152. };
  153. /**
  154. * Set number of retry attempts on error.
  155. *
  156. * Failed requests will be retried 'count' times if timeout or err.code >= 500.
  157. *
  158. * @param {Number} count
  159. * @param {Function} [fn]
  160. * @return {Request} for chaining
  161. * @api public
  162. */
  163. RequestBase.prototype.retry = function retry(count, fn){
  164. // Default to 1 if no count passed or true
  165. if (arguments.length === 0 || count === true) count = 1;
  166. if (count <= 0) count = 0;
  167. this._maxRetries = count;
  168. this._retries = 0;
  169. this._retryCallback = fn;
  170. return this;
  171. };
  172. var ERROR_CODES = [
  173. 'ECONNRESET',
  174. 'ETIMEDOUT',
  175. 'EADDRINFO',
  176. 'ESOCKETTIMEDOUT'
  177. ];
  178. /**
  179. * Determine if a request should be retried.
  180. * (Borrowed from segmentio/superagent-retry)
  181. *
  182. * @param {Error} err
  183. * @param {Response} [res]
  184. * @returns {Boolean}
  185. */
  186. RequestBase.prototype._shouldRetry = function(err, res) {
  187. if (!this._maxRetries || this._retries++ >= this._maxRetries) {
  188. return false;
  189. }
  190. if (this._retryCallback) {
  191. try {
  192. var override = this._retryCallback(err, res);
  193. if (override === true) return true;
  194. if (override === false) return false;
  195. // undefined falls back to defaults
  196. } catch(e) {
  197. console.error(e);
  198. }
  199. }
  200. if (res && res.status && res.status >= 500 && res.status != 501) return true;
  201. if (err) {
  202. if (err.code && ~ERROR_CODES.indexOf(err.code)) return true;
  203. // Superagent timeout
  204. if (err.timeout && err.code == 'ECONNABORTED') return true;
  205. if (err.crossDomain) return true;
  206. }
  207. return false;
  208. };
  209. /**
  210. * Retry request
  211. *
  212. * @return {Request} for chaining
  213. * @api private
  214. */
  215. RequestBase.prototype._retry = function() {
  216. this.clearTimeout();
  217. // node
  218. if (this.req) {
  219. this.req = null;
  220. this.req = this.request();
  221. }
  222. this._aborted = false;
  223. this.timedout = false;
  224. return this._end();
  225. };
  226. /**
  227. * Promise support
  228. *
  229. * @param {Function} resolve
  230. * @param {Function} [reject]
  231. * @return {Request}
  232. */
  233. RequestBase.prototype.then = function then(resolve, reject) {
  234. if (!this._fullfilledPromise) {
  235. var self = this;
  236. if (this._endCalled) {
  237. console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises");
  238. }
  239. this._fullfilledPromise = new Promise(function(innerResolve, innerReject) {
  240. self.end(function(err, res) {
  241. if (err) innerReject(err);
  242. else innerResolve(res);
  243. });
  244. });
  245. }
  246. return this._fullfilledPromise.then(resolve, reject);
  247. };
  248. RequestBase.prototype['catch'] = function(cb) {
  249. return this.then(undefined, cb);
  250. };
  251. /**
  252. * Allow for extension
  253. */
  254. RequestBase.prototype.use = function use(fn) {
  255. fn(this);
  256. return this;
  257. };
  258. RequestBase.prototype.ok = function(cb) {
  259. if ('function' !== typeof cb) throw Error("Callback required");
  260. this._okCallback = cb;
  261. return this;
  262. };
  263. RequestBase.prototype._isResponseOK = function(res) {
  264. if (!res) {
  265. return false;
  266. }
  267. if (this._okCallback) {
  268. return this._okCallback(res);
  269. }
  270. return res.status >= 200 && res.status < 300;
  271. };
  272. /**
  273. * Get request header `field`.
  274. * Case-insensitive.
  275. *
  276. * @param {String} field
  277. * @return {String}
  278. * @api public
  279. */
  280. RequestBase.prototype.get = function(field){
  281. return this._header[field.toLowerCase()];
  282. };
  283. /**
  284. * Get case-insensitive header `field` value.
  285. * This is a deprecated internal API. Use `.get(field)` instead.
  286. *
  287. * (getHeader is no longer used internally by the superagent code base)
  288. *
  289. * @param {String} field
  290. * @return {String}
  291. * @api private
  292. * @deprecated
  293. */
  294. RequestBase.prototype.getHeader = RequestBase.prototype.get;
  295. /**
  296. * Set header `field` to `val`, or multiple fields with one object.
  297. * Case-insensitive.
  298. *
  299. * Examples:
  300. *
  301. * req.get('/')
  302. * .set('Accept', 'application/json')
  303. * .set('X-API-Key', 'foobar')
  304. * .end(callback);
  305. *
  306. * req.get('/')
  307. * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
  308. * .end(callback);
  309. *
  310. * @param {String|Object} field
  311. * @param {String} val
  312. * @return {Request} for chaining
  313. * @api public
  314. */
  315. RequestBase.prototype.set = function(field, val){
  316. if (isObject(field)) {
  317. for (var key in field) {
  318. this.set(key, field[key]);
  319. }
  320. return this;
  321. }
  322. this._header[field.toLowerCase()] = val;
  323. this.header[field] = val;
  324. return this;
  325. };
  326. /**
  327. * Remove header `field`.
  328. * Case-insensitive.
  329. *
  330. * Example:
  331. *
  332. * req.get('/')
  333. * .unset('User-Agent')
  334. * .end(callback);
  335. *
  336. * @param {String} field
  337. */
  338. RequestBase.prototype.unset = function(field){
  339. delete this._header[field.toLowerCase()];
  340. delete this.header[field];
  341. return this;
  342. };
  343. /**
  344. * Write the field `name` and `val`, or multiple fields with one object
  345. * for "multipart/form-data" request bodies.
  346. *
  347. * ``` js
  348. * request.post('/upload')
  349. * .field('foo', 'bar')
  350. * .end(callback);
  351. *
  352. * request.post('/upload')
  353. * .field({ foo: 'bar', baz: 'qux' })
  354. * .end(callback);
  355. * ```
  356. *
  357. * @param {String|Object} name
  358. * @param {String|Blob|File|Buffer|fs.ReadStream} val
  359. * @return {Request} for chaining
  360. * @api public
  361. */
  362. RequestBase.prototype.field = function(name, val) {
  363. // name should be either a string or an object.
  364. if (null === name || undefined === name) {
  365. throw new Error('.field(name, val) name can not be empty');
  366. }
  367. if (this._data) {
  368. console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
  369. }
  370. if (isObject(name)) {
  371. for (var key in name) {
  372. this.field(key, name[key]);
  373. }
  374. return this;
  375. }
  376. if (Array.isArray(val)) {
  377. for (var i in val) {
  378. this.field(name, val[i]);
  379. }
  380. return this;
  381. }
  382. // val should be defined now
  383. if (null === val || undefined === val) {
  384. throw new Error('.field(name, val) val can not be empty');
  385. }
  386. if ('boolean' === typeof val) {
  387. val = '' + val;
  388. }
  389. this._getFormData().append(name, val);
  390. return this;
  391. };
  392. /**
  393. * Abort the request, and clear potential timeout.
  394. *
  395. * @return {Request}
  396. * @api public
  397. */
  398. RequestBase.prototype.abort = function(){
  399. if (this._aborted) {
  400. return this;
  401. }
  402. this._aborted = true;
  403. this.xhr && this.xhr.abort(); // browser
  404. this.req && this.req.abort(); // node
  405. this.clearTimeout();
  406. this.emit('abort');
  407. return this;
  408. };
  409. RequestBase.prototype._auth = function(user, pass, options, base64Encoder) {
  410. switch (options.type) {
  411. case 'basic':
  412. this.set('Authorization', 'Basic ' + base64Encoder(user + ':' + pass));
  413. break;
  414. case 'auto':
  415. this.username = user;
  416. this.password = pass;
  417. break;
  418. case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' })
  419. this.set('Authorization', 'Bearer ' + user);
  420. break;
  421. }
  422. return this;
  423. };
  424. /**
  425. * Enable transmission of cookies with x-domain requests.
  426. *
  427. * Note that for this to work the origin must not be
  428. * using "Access-Control-Allow-Origin" with a wildcard,
  429. * and also must set "Access-Control-Allow-Credentials"
  430. * to "true".
  431. *
  432. * @api public
  433. */
  434. RequestBase.prototype.withCredentials = function(on) {
  435. // This is browser-only functionality. Node side is no-op.
  436. if (on == undefined) on = true;
  437. this._withCredentials = on;
  438. return this;
  439. };
  440. /**
  441. * Set the max redirects to `n`. Does noting in browser XHR implementation.
  442. *
  443. * @param {Number} n
  444. * @return {Request} for chaining
  445. * @api public
  446. */
  447. RequestBase.prototype.redirects = function(n){
  448. this._maxRedirects = n;
  449. return this;
  450. };
  451. /**
  452. * Maximum size of buffered response body, in bytes. Counts uncompressed size.
  453. * Default 200MB.
  454. *
  455. * @param {Number} n
  456. * @return {Request} for chaining
  457. */
  458. RequestBase.prototype.maxResponseSize = function(n){
  459. if ('number' !== typeof n) {
  460. throw TypeError("Invalid argument");
  461. }
  462. this._maxResponseSize = n;
  463. return this;
  464. };
  465. /**
  466. * Convert to a plain javascript object (not JSON string) of scalar properties.
  467. * Note as this method is designed to return a useful non-this value,
  468. * it cannot be chained.
  469. *
  470. * @return {Object} describing method, url, and data of this request
  471. * @api public
  472. */
  473. RequestBase.prototype.toJSON = function() {
  474. return {
  475. method: this.method,
  476. url: this.url,
  477. data: this._data,
  478. headers: this._header,
  479. };
  480. };
  481. /**
  482. * Send `data` as the request body, defaulting the `.type()` to "json" when
  483. * an object is given.
  484. *
  485. * Examples:
  486. *
  487. * // manual json
  488. * request.post('/user')
  489. * .type('json')
  490. * .send('{"name":"tj"}')
  491. * .end(callback)
  492. *
  493. * // auto json
  494. * request.post('/user')
  495. * .send({ name: 'tj' })
  496. * .end(callback)
  497. *
  498. * // manual x-www-form-urlencoded
  499. * request.post('/user')
  500. * .type('form')
  501. * .send('name=tj')
  502. * .end(callback)
  503. *
  504. * // auto x-www-form-urlencoded
  505. * request.post('/user')
  506. * .type('form')
  507. * .send({ name: 'tj' })
  508. * .end(callback)
  509. *
  510. * // defaults to x-www-form-urlencoded
  511. * request.post('/user')
  512. * .send('name=tobi')
  513. * .send('species=ferret')
  514. * .end(callback)
  515. *
  516. * @param {String|Object} data
  517. * @return {Request} for chaining
  518. * @api public
  519. */
  520. RequestBase.prototype.send = function(data){
  521. var isObj = isObject(data);
  522. var type = this._header['content-type'];
  523. if (this._formData) {
  524. console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
  525. }
  526. if (isObj && !this._data) {
  527. if (Array.isArray(data)) {
  528. this._data = [];
  529. } else if (!this._isHost(data)) {
  530. this._data = {};
  531. }
  532. } else if (data && this._data && this._isHost(this._data)) {
  533. throw Error("Can't merge these send calls");
  534. }
  535. // merge
  536. if (isObj && isObject(this._data)) {
  537. for (var key in data) {
  538. this._data[key] = data[key];
  539. }
  540. } else if ('string' == typeof data) {
  541. // default to x-www-form-urlencoded
  542. if (!type) this.type('form');
  543. type = this._header['content-type'];
  544. if ('application/x-www-form-urlencoded' == type) {
  545. this._data = this._data
  546. ? this._data + '&' + data
  547. : data;
  548. } else {
  549. this._data = (this._data || '') + data;
  550. }
  551. } else {
  552. this._data = data;
  553. }
  554. if (!isObj || this._isHost(data)) {
  555. return this;
  556. }
  557. // default to json
  558. if (!type) this.type('json');
  559. return this;
  560. };
  561. /**
  562. * Sort `querystring` by the sort function
  563. *
  564. *
  565. * Examples:
  566. *
  567. * // default order
  568. * request.get('/user')
  569. * .query('name=Nick')
  570. * .query('search=Manny')
  571. * .sortQuery()
  572. * .end(callback)
  573. *
  574. * // customized sort function
  575. * request.get('/user')
  576. * .query('name=Nick')
  577. * .query('search=Manny')
  578. * .sortQuery(function(a, b){
  579. * return a.length - b.length;
  580. * })
  581. * .end(callback)
  582. *
  583. *
  584. * @param {Function} sort
  585. * @return {Request} for chaining
  586. * @api public
  587. */
  588. RequestBase.prototype.sortQuery = function(sort) {
  589. // _sort default to true but otherwise can be a function or boolean
  590. this._sort = typeof sort === 'undefined' ? true : sort;
  591. return this;
  592. };
  593. /**
  594. * Compose querystring to append to req.url
  595. *
  596. * @api private
  597. */
  598. RequestBase.prototype._finalizeQueryString = function(){
  599. var query = this._query.join('&');
  600. if (query) {
  601. this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
  602. }
  603. this._query.length = 0; // Makes the call idempotent
  604. if (this._sort) {
  605. var index = this.url.indexOf('?');
  606. if (index >= 0) {
  607. var queryArr = this.url.substring(index + 1).split('&');
  608. if ('function' === typeof this._sort) {
  609. queryArr.sort(this._sort);
  610. } else {
  611. queryArr.sort();
  612. }
  613. this.url = this.url.substring(0, index) + '?' + queryArr.join('&');
  614. }
  615. }
  616. };
  617. // For backwards compat only
  618. RequestBase.prototype._appendQueryString = function() {console.trace("Unsupported");}
  619. /**
  620. * Invoke callback with timeout error.
  621. *
  622. * @api private
  623. */
  624. RequestBase.prototype._timeoutError = function(reason, timeout, errno){
  625. if (this._aborted) {
  626. return;
  627. }
  628. var err = new Error(reason + timeout + 'ms exceeded');
  629. err.timeout = timeout;
  630. err.code = 'ECONNABORTED';
  631. err.errno = errno;
  632. this.timedout = true;
  633. this.abort();
  634. this.callback(err);
  635. };
  636. RequestBase.prototype._setTimeouts = function() {
  637. var self = this;
  638. // deadline
  639. if (this._timeout && !this._timer) {
  640. this._timer = setTimeout(function(){
  641. self._timeoutError('Timeout of ', self._timeout, 'ETIME');
  642. }, this._timeout);
  643. }
  644. // response timeout
  645. if (this._responseTimeout && !this._responseTimeoutTimer) {
  646. this._responseTimeoutTimer = setTimeout(function(){
  647. self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT');
  648. }, this._responseTimeout);
  649. }
  650. };
  651. },{"./is-object":2}],4:[function(require,module,exports){
  652. 'use strict';
  653. /**
  654. * Module dependencies.
  655. */
  656. var utils = require('./utils');
  657. /**
  658. * Expose `ResponseBase`.
  659. */
  660. module.exports = ResponseBase;
  661. /**
  662. * Initialize a new `ResponseBase`.
  663. *
  664. * @api public
  665. */
  666. function ResponseBase(obj) {
  667. if (obj) return mixin(obj);
  668. }
  669. /**
  670. * Mixin the prototype properties.
  671. *
  672. * @param {Object} obj
  673. * @return {Object}
  674. * @api private
  675. */
  676. function mixin(obj) {
  677. for (var key in ResponseBase.prototype) {
  678. obj[key] = ResponseBase.prototype[key];
  679. }
  680. return obj;
  681. }
  682. /**
  683. * Get case-insensitive `field` value.
  684. *
  685. * @param {String} field
  686. * @return {String}
  687. * @api public
  688. */
  689. ResponseBase.prototype.get = function(field) {
  690. return this.header[field.toLowerCase()];
  691. };
  692. /**
  693. * Set header related properties:
  694. *
  695. * - `.type` the content type without params
  696. *
  697. * A response of "Content-Type: text/plain; charset=utf-8"
  698. * will provide you with a `.type` of "text/plain".
  699. *
  700. * @param {Object} header
  701. * @api private
  702. */
  703. ResponseBase.prototype._setHeaderProperties = function(header){
  704. // TODO: moar!
  705. // TODO: make this a util
  706. // content-type
  707. var ct = header['content-type'] || '';
  708. this.type = utils.type(ct);
  709. // params
  710. var params = utils.params(ct);
  711. for (var key in params) this[key] = params[key];
  712. this.links = {};
  713. // links
  714. try {
  715. if (header.link) {
  716. this.links = utils.parseLinks(header.link);
  717. }
  718. } catch (err) {
  719. // ignore
  720. }
  721. };
  722. /**
  723. * Set flags such as `.ok` based on `status`.
  724. *
  725. * For example a 2xx response will give you a `.ok` of __true__
  726. * whereas 5xx will be __false__ and `.error` will be __true__. The
  727. * `.clientError` and `.serverError` are also available to be more
  728. * specific, and `.statusType` is the class of error ranging from 1..5
  729. * sometimes useful for mapping respond colors etc.
  730. *
  731. * "sugar" properties are also defined for common cases. Currently providing:
  732. *
  733. * - .noContent
  734. * - .badRequest
  735. * - .unauthorized
  736. * - .notAcceptable
  737. * - .notFound
  738. *
  739. * @param {Number} status
  740. * @api private
  741. */
  742. ResponseBase.prototype._setStatusProperties = function(status){
  743. var type = status / 100 | 0;
  744. // status / class
  745. this.status = this.statusCode = status;
  746. this.statusType = type;
  747. // basics
  748. this.info = 1 == type;
  749. this.ok = 2 == type;
  750. this.redirect = 3 == type;
  751. this.clientError = 4 == type;
  752. this.serverError = 5 == type;
  753. this.error = (4 == type || 5 == type)
  754. ? this.toError()
  755. : false;
  756. // sugar
  757. this.created = 201 == status;
  758. this.accepted = 202 == status;
  759. this.noContent = 204 == status;
  760. this.badRequest = 400 == status;
  761. this.unauthorized = 401 == status;
  762. this.notAcceptable = 406 == status;
  763. this.forbidden = 403 == status;
  764. this.notFound = 404 == status;
  765. this.unprocessableEntity = 422 == status;
  766. };
  767. },{"./utils":5}],5:[function(require,module,exports){
  768. 'use strict';
  769. /**
  770. * Return the mime type for the given `str`.
  771. *
  772. * @param {String} str
  773. * @return {String}
  774. * @api private
  775. */
  776. exports.type = function(str){
  777. return str.split(/ *; */).shift();
  778. };
  779. /**
  780. * Return header field parameters.
  781. *
  782. * @param {String} str
  783. * @return {Object}
  784. * @api private
  785. */
  786. exports.params = function(str){
  787. return str.split(/ *; */).reduce(function(obj, str){
  788. var parts = str.split(/ *= */);
  789. var key = parts.shift();
  790. var val = parts.shift();
  791. if (key && val) obj[key] = val;
  792. return obj;
  793. }, {});
  794. };
  795. /**
  796. * Parse Link header fields.
  797. *
  798. * @param {String} str
  799. * @return {Object}
  800. * @api private
  801. */
  802. exports.parseLinks = function(str){
  803. return str.split(/ *, */).reduce(function(obj, str){
  804. var parts = str.split(/ *; */);
  805. var url = parts[0].slice(1, -1);
  806. var rel = parts[1].split(/ *= */)[1].slice(1, -1);
  807. obj[rel] = url;
  808. return obj;
  809. }, {});
  810. };
  811. /**
  812. * Strip content related fields from `header`.
  813. *
  814. * @param {Object} header
  815. * @return {Object} header
  816. * @api private
  817. */
  818. exports.cleanHeader = function(header, changesOrigin){
  819. delete header['content-type'];
  820. delete header['content-length'];
  821. delete header['transfer-encoding'];
  822. delete header['host'];
  823. // secuirty
  824. if (changesOrigin) {
  825. delete header['authorization'];
  826. delete header['cookie'];
  827. }
  828. return header;
  829. };
  830. },{}],6:[function(require,module,exports){
  831. /**
  832. * Expose `Emitter`.
  833. */
  834. if (typeof module !== 'undefined') {
  835. module.exports = Emitter;
  836. }
  837. /**
  838. * Initialize a new `Emitter`.
  839. *
  840. * @api public
  841. */
  842. function Emitter(obj) {
  843. if (obj) return mixin(obj);
  844. };
  845. /**
  846. * Mixin the emitter properties.
  847. *
  848. * @param {Object} obj
  849. * @return {Object}
  850. * @api private
  851. */
  852. function mixin(obj) {
  853. for (var key in Emitter.prototype) {
  854. obj[key] = Emitter.prototype[key];
  855. }
  856. return obj;
  857. }
  858. /**
  859. * Listen on the given `event` with `fn`.
  860. *
  861. * @param {String} event
  862. * @param {Function} fn
  863. * @return {Emitter}
  864. * @api public
  865. */
  866. Emitter.prototype.on =
  867. Emitter.prototype.addEventListener = function(event, fn){
  868. this._callbacks = this._callbacks || {};
  869. (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
  870. .push(fn);
  871. return this;
  872. };
  873. /**
  874. * Adds an `event` listener that will be invoked a single
  875. * time then automatically removed.
  876. *
  877. * @param {String} event
  878. * @param {Function} fn
  879. * @return {Emitter}
  880. * @api public
  881. */
  882. Emitter.prototype.once = function(event, fn){
  883. function on() {
  884. this.off(event, on);
  885. fn.apply(this, arguments);
  886. }
  887. on.fn = fn;
  888. this.on(event, on);
  889. return this;
  890. };
  891. /**
  892. * Remove the given callback for `event` or all
  893. * registered callbacks.
  894. *
  895. * @param {String} event
  896. * @param {Function} fn
  897. * @return {Emitter}
  898. * @api public
  899. */
  900. Emitter.prototype.off =
  901. Emitter.prototype.removeListener =
  902. Emitter.prototype.removeAllListeners =
  903. Emitter.prototype.removeEventListener = function(event, fn){
  904. this._callbacks = this._callbacks || {};
  905. // all
  906. if (0 == arguments.length) {
  907. this._callbacks = {};
  908. return this;
  909. }
  910. // specific event
  911. var callbacks = this._callbacks['$' + event];
  912. if (!callbacks) return this;
  913. // remove all handlers
  914. if (1 == arguments.length) {
  915. delete this._callbacks['$' + event];
  916. return this;
  917. }
  918. // remove specific handler
  919. var cb;
  920. for (var i = 0; i < callbacks.length; i++) {
  921. cb = callbacks[i];
  922. if (cb === fn || cb.fn === fn) {
  923. callbacks.splice(i, 1);
  924. break;
  925. }
  926. }
  927. return this;
  928. };
  929. /**
  930. * Emit `event` with the given args.
  931. *
  932. * @param {String} event
  933. * @param {Mixed} ...
  934. * @return {Emitter}
  935. */
  936. Emitter.prototype.emit = function(event){
  937. this._callbacks = this._callbacks || {};
  938. var args = [].slice.call(arguments, 1)
  939. , callbacks = this._callbacks['$' + event];
  940. if (callbacks) {
  941. callbacks = callbacks.slice(0);
  942. for (var i = 0, len = callbacks.length; i < len; ++i) {
  943. callbacks[i].apply(this, args);
  944. }
  945. }
  946. return this;
  947. };
  948. /**
  949. * Return array of callbacks for `event`.
  950. *
  951. * @param {String} event
  952. * @return {Array}
  953. * @api public
  954. */
  955. Emitter.prototype.listeners = function(event){
  956. this._callbacks = this._callbacks || {};
  957. return this._callbacks['$' + event] || [];
  958. };
  959. /**
  960. * Check if this emitter has `event` handlers.
  961. *
  962. * @param {String} event
  963. * @return {Boolean}
  964. * @api public
  965. */
  966. Emitter.prototype.hasListeners = function(event){
  967. return !! this.listeners(event).length;
  968. };
  969. },{}],7:[function(require,module,exports){
  970. /**
  971. * Root reference for iframes.
  972. */
  973. var root;
  974. if (typeof window !== 'undefined') { // Browser window
  975. root = window;
  976. } else if (typeof self !== 'undefined') { // Web Worker
  977. root = self;
  978. } else { // Other environments
  979. console.warn("Using browser-only version of superagent in non-browser environment");
  980. root = this;
  981. }
  982. var Emitter = require('component-emitter');
  983. var RequestBase = require('./request-base');
  984. var isObject = require('./is-object');
  985. var ResponseBase = require('./response-base');
  986. var Agent = require('./agent-base');
  987. /**
  988. * Noop.
  989. */
  990. function noop(){};
  991. /**
  992. * Expose `request`.
  993. */
  994. var request = exports = module.exports = function(method, url) {
  995. // callback
  996. if ('function' == typeof url) {
  997. return new exports.Request('GET', method).end(url);
  998. }
  999. // url first
  1000. if (1 == arguments.length) {
  1001. return new exports.Request('GET', method);
  1002. }
  1003. return new exports.Request(method, url);
  1004. }
  1005. exports.Request = Request;
  1006. /**
  1007. * Determine XHR.
  1008. */
  1009. request.getXHR = function () {
  1010. if (root.XMLHttpRequest
  1011. && (!root.location || 'file:' != root.location.protocol
  1012. || !root.ActiveXObject)) {
  1013. return new XMLHttpRequest;
  1014. } else {
  1015. try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
  1016. try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
  1017. try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
  1018. try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
  1019. }
  1020. throw Error("Browser-only version of superagent could not find XHR");
  1021. };
  1022. /**
  1023. * Removes leading and trailing whitespace, added to support IE.
  1024. *
  1025. * @param {String} s
  1026. * @return {String}
  1027. * @api private
  1028. */
  1029. var trim = ''.trim
  1030. ? function(s) { return s.trim(); }
  1031. : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
  1032. /**
  1033. * Serialize the given `obj`.
  1034. *
  1035. * @param {Object} obj
  1036. * @return {String}
  1037. * @api private
  1038. */
  1039. function serialize(obj) {
  1040. if (!isObject(obj)) return obj;
  1041. var pairs = [];
  1042. for (var key in obj) {
  1043. pushEncodedKeyValuePair(pairs, key, obj[key]);
  1044. }
  1045. return pairs.join('&');
  1046. }
  1047. /**
  1048. * Helps 'serialize' with serializing arrays.
  1049. * Mutates the pairs array.
  1050. *
  1051. * @param {Array} pairs
  1052. * @param {String} key
  1053. * @param {Mixed} val
  1054. */
  1055. function pushEncodedKeyValuePair(pairs, key, val) {
  1056. if (val != null) {
  1057. if (Array.isArray(val)) {
  1058. val.forEach(function(v) {
  1059. pushEncodedKeyValuePair(pairs, key, v);
  1060. });
  1061. } else if (isObject(val)) {
  1062. for(var subkey in val) {
  1063. pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]);
  1064. }
  1065. } else {
  1066. pairs.push(encodeURIComponent(key)
  1067. + '=' + encodeURIComponent(val));
  1068. }
  1069. } else if (val === null) {
  1070. pairs.push(encodeURIComponent(key));
  1071. }
  1072. }
  1073. /**
  1074. * Expose serialization method.
  1075. */
  1076. request.serializeObject = serialize;
  1077. /**
  1078. * Parse the given x-www-form-urlencoded `str`.
  1079. *
  1080. * @param {String} str
  1081. * @return {Object}
  1082. * @api private
  1083. */
  1084. function parseString(str) {
  1085. var obj = {};
  1086. var pairs = str.split('&');
  1087. var pair;
  1088. var pos;
  1089. for (var i = 0, len = pairs.length; i < len; ++i) {
  1090. pair = pairs[i];
  1091. pos = pair.indexOf('=');
  1092. if (pos == -1) {
  1093. obj[decodeURIComponent(pair)] = '';
  1094. } else {
  1095. obj[decodeURIComponent(pair.slice(0, pos))] =
  1096. decodeURIComponent(pair.slice(pos + 1));
  1097. }
  1098. }
  1099. return obj;
  1100. }
  1101. /**
  1102. * Expose parser.
  1103. */
  1104. request.parseString = parseString;
  1105. /**
  1106. * Default MIME type map.
  1107. *
  1108. * superagent.types.xml = 'application/xml';
  1109. *
  1110. */
  1111. request.types = {
  1112. html: 'text/html',
  1113. json: 'application/json',
  1114. xml: 'text/xml',
  1115. urlencoded: 'application/x-www-form-urlencoded',
  1116. 'form': 'application/x-www-form-urlencoded',
  1117. 'form-data': 'application/x-www-form-urlencoded'
  1118. };
  1119. /**
  1120. * Default serialization map.
  1121. *
  1122. * superagent.serialize['application/xml'] = function(obj){
  1123. * return 'generated xml here';
  1124. * };
  1125. *
  1126. */
  1127. request.serialize = {
  1128. 'application/x-www-form-urlencoded': serialize,
  1129. 'application/json': JSON.stringify
  1130. };
  1131. /**
  1132. * Default parsers.
  1133. *
  1134. * superagent.parse['application/xml'] = function(str){
  1135. * return { object parsed from str };
  1136. * };
  1137. *
  1138. */
  1139. request.parse = {
  1140. 'application/x-www-form-urlencoded': parseString,
  1141. 'application/json': JSON.parse
  1142. };
  1143. /**
  1144. * Parse the given header `str` into
  1145. * an object containing the mapped fields.
  1146. *
  1147. * @param {String} str
  1148. * @return {Object}
  1149. * @api private
  1150. */
  1151. function parseHeader(str) {
  1152. var lines = str.split(/\r?\n/);
  1153. var fields = {};
  1154. var index;
  1155. var line;
  1156. var field;
  1157. var val;
  1158. for (var i = 0, len = lines.length; i < len; ++i) {
  1159. line = lines[i];
  1160. index = line.indexOf(':');
  1161. if (index === -1) { // could be empty line, just skip it
  1162. continue;
  1163. }
  1164. field = line.slice(0, index).toLowerCase();
  1165. val = trim(line.slice(index + 1));
  1166. fields[field] = val;
  1167. }
  1168. return fields;
  1169. }
  1170. /**
  1171. * Check if `mime` is json or has +json structured syntax suffix.
  1172. *
  1173. * @param {String} mime
  1174. * @return {Boolean}
  1175. * @api private
  1176. */
  1177. function isJSON(mime) {
  1178. // should match /json or +json
  1179. // but not /json-seq
  1180. return /[\/+]json($|[^-\w])/.test(mime);
  1181. }
  1182. /**
  1183. * Initialize a new `Response` with the given `xhr`.
  1184. *
  1185. * - set flags (.ok, .error, etc)
  1186. * - parse header
  1187. *
  1188. * Examples:
  1189. *
  1190. * Aliasing `superagent` as `request` is nice:
  1191. *
  1192. * request = superagent;
  1193. *
  1194. * We can use the promise-like API, or pass callbacks:
  1195. *
  1196. * request.get('/').end(function(res){});
  1197. * request.get('/', function(res){});
  1198. *
  1199. * Sending data can be chained:
  1200. *
  1201. * request
  1202. * .post('/user')
  1203. * .send({ name: 'tj' })
  1204. * .end(function(res){});
  1205. *
  1206. * Or passed to `.send()`:
  1207. *
  1208. * request
  1209. * .post('/user')
  1210. * .send({ name: 'tj' }, function(res){});
  1211. *
  1212. * Or passed to `.post()`:
  1213. *
  1214. * request
  1215. * .post('/user', { name: 'tj' })
  1216. * .end(function(res){});
  1217. *
  1218. * Or further reduced to a single call for simple cases:
  1219. *
  1220. * request
  1221. * .post('/user', { name: 'tj' }, function(res){});
  1222. *
  1223. * @param {XMLHTTPRequest} xhr
  1224. * @param {Object} options
  1225. * @api private
  1226. */
  1227. function Response(req) {
  1228. this.req = req;
  1229. this.xhr = this.req.xhr;
  1230. // responseText is accessible only if responseType is '' or 'text' and on older browsers
  1231. this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
  1232. ? this.xhr.responseText
  1233. : null;
  1234. this.statusText = this.req.xhr.statusText;
  1235. var status = this.xhr.status;
  1236. // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
  1237. if (status === 1223) {
  1238. status = 204;
  1239. }
  1240. this._setStatusProperties(status);
  1241. this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
  1242. // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
  1243. // getResponseHeader still works. so we get content-type even if getting
  1244. // other headers fails.
  1245. this.header['content-type'] = this.xhr.getResponseHeader('content-type');
  1246. this._setHeaderProperties(this.header);
  1247. if (null === this.text && req._responseType) {
  1248. this.body = this.xhr.response;
  1249. } else {
  1250. this.body = this.req.method != 'HEAD'
  1251. ? this._parseBody(this.text ? this.text : this.xhr.response)
  1252. : null;
  1253. }
  1254. }
  1255. ResponseBase(Response.prototype);
  1256. /**
  1257. * Parse the given body `str`.
  1258. *
  1259. * Used for auto-parsing of bodies. Parsers
  1260. * are defined on the `superagent.parse` object.
  1261. *
  1262. * @param {String} str
  1263. * @return {Mixed}
  1264. * @api private
  1265. */
  1266. Response.prototype._parseBody = function(str) {
  1267. var parse = request.parse[this.type];
  1268. if (this.req._parser) {
  1269. return this.req._parser(this, str);
  1270. }
  1271. if (!parse && isJSON(this.type)) {
  1272. parse = request.parse['application/json'];
  1273. }
  1274. return parse && str && (str.length || str instanceof Object)
  1275. ? parse(str)
  1276. : null;
  1277. };
  1278. /**
  1279. * Return an `Error` representative of this response.
  1280. *
  1281. * @return {Error}
  1282. * @api public
  1283. */
  1284. Response.prototype.toError = function(){
  1285. var req = this.req;
  1286. var method = req.method;
  1287. var url = req.url;
  1288. var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
  1289. var err = new Error(msg);
  1290. err.status = this.status;
  1291. err.method = method;
  1292. err.url = url;
  1293. return err;
  1294. };
  1295. /**
  1296. * Expose `Response`.
  1297. */
  1298. request.Response = Response;
  1299. /**
  1300. * Initialize a new `Request` with the given `method` and `url`.
  1301. *
  1302. * @param {String} method
  1303. * @param {String} url
  1304. * @api public
  1305. */
  1306. function Request(method, url) {
  1307. var self = this;
  1308. this._query = this._query || [];
  1309. this.method = method;
  1310. this.url = url;
  1311. this.header = {}; // preserves header name case
  1312. this._header = {}; // coerces header names to lowercase
  1313. this.on('end', function(){
  1314. var err = null;
  1315. var res = null;
  1316. try {
  1317. res = new Response(self);
  1318. } catch(e) {
  1319. err = new Error('Parser is unable to parse the response');
  1320. err.parse = true;
  1321. err.original = e;
  1322. // issue #675: return the raw response if the response parsing fails
  1323. if (self.xhr) {
  1324. // ie9 doesn't have 'response' property
  1325. err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response;
  1326. // issue #876: return the http status code if the response parsing fails
  1327. err.status = self.xhr.status ? self.xhr.status : null;
  1328. err.statusCode = err.status; // backwards-compat only
  1329. } else {
  1330. err.rawResponse = null;
  1331. err.status = null;
  1332. }
  1333. return self.callback(err);
  1334. }
  1335. self.emit('response', res);
  1336. var new_err;
  1337. try {
  1338. if (!self._isResponseOK(res)) {
  1339. new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
  1340. }
  1341. } catch(custom_err) {
  1342. new_err = custom_err; // ok() callback can throw
  1343. }
  1344. // #1000 don't catch errors from the callback to avoid double calling it
  1345. if (new_err) {
  1346. new_err.original = err;
  1347. new_err.response = res;
  1348. new_err.status = res.status;
  1349. self.callback(new_err, res);
  1350. } else {
  1351. self.callback(null, res);
  1352. }
  1353. });
  1354. }
  1355. /**
  1356. * Mixin `Emitter` and `RequestBase`.
  1357. */
  1358. Emitter(Request.prototype);
  1359. RequestBase(Request.prototype);
  1360. /**
  1361. * Set Content-Type to `type`, mapping values from `request.types`.
  1362. *
  1363. * Examples:
  1364. *
  1365. * superagent.types.xml = 'application/xml';
  1366. *
  1367. * request.post('/')
  1368. * .type('xml')
  1369. * .send(xmlstring)
  1370. * .end(callback);
  1371. *
  1372. * request.post('/')
  1373. * .type('application/xml')
  1374. * .send(xmlstring)
  1375. * .end(callback);
  1376. *
  1377. * @param {String} type
  1378. * @return {Request} for chaining
  1379. * @api public
  1380. */
  1381. Request.prototype.type = function(type){
  1382. this.set('Content-Type', request.types[type] || type);
  1383. return this;
  1384. };
  1385. /**
  1386. * Set Accept to `type`, mapping values from `request.types`.
  1387. *
  1388. * Examples:
  1389. *
  1390. * superagent.types.json = 'application/json';
  1391. *
  1392. * request.get('/agent')
  1393. * .accept('json')
  1394. * .end(callback);
  1395. *
  1396. * request.get('/agent')
  1397. * .accept('application/json')
  1398. * .end(callback);
  1399. *
  1400. * @param {String} accept
  1401. * @return {Request} for chaining
  1402. * @api public
  1403. */
  1404. Request.prototype.accept = function(type){
  1405. this.set('Accept', request.types[type] || type);
  1406. return this;
  1407. };
  1408. /**
  1409. * Set Authorization field value with `user` and `pass`.
  1410. *
  1411. * @param {String} user
  1412. * @param {String} [pass] optional in case of using 'bearer' as type
  1413. * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic')
  1414. * @return {Request} for chaining
  1415. * @api public
  1416. */
  1417. Request.prototype.auth = function(user, pass, options){
  1418. if (1 === arguments.length) pass = '';
  1419. if (typeof pass === 'object' && pass !== null) { // pass is optional and can be replaced with options
  1420. options = pass;
  1421. pass = '';
  1422. }
  1423. if (!options) {
  1424. options = {
  1425. type: 'function' === typeof btoa ? 'basic' : 'auto',
  1426. };
  1427. }
  1428. var encoder = function(string) {
  1429. if ('function' === typeof btoa) {
  1430. return btoa(string);
  1431. }
  1432. throw new Error('Cannot use basic auth, btoa is not a function');
  1433. };
  1434. return this._auth(user, pass, options, encoder);
  1435. };
  1436. /**
  1437. * Add query-string `val`.
  1438. *
  1439. * Examples:
  1440. *
  1441. * request.get('/shoes')
  1442. * .query('size=10')
  1443. * .query({ color: 'blue' })
  1444. *
  1445. * @param {Object|String} val
  1446. * @return {Request} for chaining
  1447. * @api public
  1448. */
  1449. Request.prototype.query = function(val){
  1450. if ('string' != typeof val) val = serialize(val);
  1451. if (val) this._query.push(val);
  1452. return this;
  1453. };
  1454. /**
  1455. * Queue the given `file` as an attachment to the specified `field`,
  1456. * with optional `options` (or filename).
  1457. *
  1458. * ``` js
  1459. * request.post('/upload')
  1460. * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
  1461. * .end(callback);
  1462. * ```
  1463. *
  1464. * @param {String} field
  1465. * @param {Blob|File} file
  1466. * @param {String|Object} options
  1467. * @return {Request} for chaining
  1468. * @api public
  1469. */
  1470. Request.prototype.attach = function(field, file, options){
  1471. if (file) {
  1472. if (this._data) {
  1473. throw Error("superagent can't mix .send() and .attach()");
  1474. }
  1475. this._getFormData().append(field, file, options || file.name);
  1476. }
  1477. return this;
  1478. };
  1479. Request.prototype._getFormData = function(){
  1480. if (!this._formData) {
  1481. this._formData = new root.FormData();
  1482. }
  1483. return this._formData;
  1484. };
  1485. /**
  1486. * Invoke the callback with `err` and `res`
  1487. * and handle arity check.
  1488. *
  1489. * @param {Error} err
  1490. * @param {Response} res
  1491. * @api private
  1492. */
  1493. Request.prototype.callback = function(err, res){
  1494. if (this._shouldRetry(err, res)) {
  1495. return this._retry();
  1496. }
  1497. var fn = this._callback;
  1498. this.clearTimeout();
  1499. if (err) {
  1500. if (this._maxRetries) err.retries = this._retries - 1;
  1501. this.emit('error', err);
  1502. }
  1503. fn(err, res);
  1504. };
  1505. /**
  1506. * Invoke callback with x-domain error.
  1507. *
  1508. * @api private
  1509. */
  1510. Request.prototype.crossDomainError = function(){
  1511. var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
  1512. err.crossDomain = true;
  1513. err.status = this.status;
  1514. err.method = this.method;
  1515. err.url = this.url;
  1516. this.callback(err);
  1517. };
  1518. // This only warns, because the request is still likely to work
  1519. Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){
  1520. console.warn("This is not supported in browser version of superagent");
  1521. return this;
  1522. };
  1523. // This throws, because it can't send/receive data as expected
  1524. Request.prototype.pipe = Request.prototype.write = function(){
  1525. throw Error("Streaming is not supported in browser version of superagent");
  1526. };
  1527. /**
  1528. * Check if `obj` is a host object,
  1529. * we don't want to serialize these :)
  1530. *
  1531. * @param {Object} obj
  1532. * @return {Boolean}
  1533. * @api private
  1534. */
  1535. Request.prototype._isHost = function _isHost(obj) {
  1536. // Native objects stringify to [object File], [object Blob], [object FormData], etc.
  1537. return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]';
  1538. }
  1539. /**
  1540. * Initiate request, invoking callback `fn(res)`
  1541. * with an instanceof `Response`.
  1542. *
  1543. * @param {Function} fn
  1544. * @return {Request} for chaining
  1545. * @api public
  1546. */
  1547. Request.prototype.end = function(fn){
  1548. if (this._endCalled) {
  1549. console.warn("Warning: .end() was called twice. This is not supported in superagent");
  1550. }
  1551. this._endCalled = true;
  1552. // store callback
  1553. this._callback = fn || noop;
  1554. // querystring
  1555. this._finalizeQueryString();
  1556. return this._end();
  1557. };
  1558. Request.prototype._end = function() {
  1559. var self = this;
  1560. var xhr = (this.xhr = request.getXHR());
  1561. var data = this._formData || this._data;
  1562. this._setTimeouts();
  1563. // state change
  1564. xhr.onreadystatechange = function(){
  1565. var readyState = xhr.readyState;
  1566. if (readyState >= 2 && self._responseTimeoutTimer) {
  1567. clearTimeout(self._responseTimeoutTimer);
  1568. }
  1569. if (4 != readyState) {
  1570. return;
  1571. }
  1572. // In IE9, reads to any property (e.g. status) off of an aborted XHR will
  1573. // result in the error "Could not complete the operation due to error c00c023f"
  1574. var status;
  1575. try { status = xhr.status } catch(e) { status = 0; }
  1576. if (!status) {
  1577. if (self.timedout || self._aborted) return;
  1578. return self.crossDomainError();
  1579. }
  1580. self.emit('end');
  1581. };
  1582. // progress
  1583. var handleProgress = function(direction, e) {
  1584. if (e.total > 0) {
  1585. e.percent = e.loaded / e.total * 100;
  1586. }
  1587. e.direction = direction;
  1588. self.emit('progress', e);
  1589. };
  1590. if (this.hasListeners('progress')) {
  1591. try {
  1592. xhr.onprogress = handleProgress.bind(null, 'download');
  1593. if (xhr.upload) {
  1594. xhr.upload.onprogress = handleProgress.bind(null, 'upload');
  1595. }
  1596. } catch(e) {
  1597. // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
  1598. // Reported here:
  1599. // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
  1600. }
  1601. }
  1602. // initiate request
  1603. try {
  1604. if (this.username && this.password) {
  1605. xhr.open(this.method, this.url, true, this.username, this.password);
  1606. } else {
  1607. xhr.open(this.method, this.url, true);
  1608. }
  1609. } catch (err) {
  1610. // see #1149
  1611. return this.callback(err);
  1612. }
  1613. // CORS
  1614. if (this._withCredentials) xhr.withCredentials = true;
  1615. // body
  1616. if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
  1617. // serialize stuff
  1618. var contentType = this._header['content-type'];
  1619. var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
  1620. if (!serialize && isJSON(contentType)) {
  1621. serialize = request.serialize['application/json'];
  1622. }
  1623. if (serialize) data = serialize(data);
  1624. }
  1625. // set header fields
  1626. for (var field in this.header) {
  1627. if (null == this.header[field]) continue;
  1628. if (this.header.hasOwnProperty(field))
  1629. xhr.setRequestHeader(field, this.header[field]);
  1630. }
  1631. if (this._responseType) {
  1632. xhr.responseType = this._responseType;
  1633. }
  1634. // send stuff
  1635. this.emit('request', this);
  1636. // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
  1637. // We need null here if data is undefined
  1638. xhr.send(typeof data !== 'undefined' ? data : null);
  1639. return this;
  1640. };
  1641. request.agent = function() {
  1642. return new Agent();
  1643. };
  1644. ["GET", "POST", "OPTIONS", "PATCH", "PUT", "DELETE"].forEach(function(method) {
  1645. Agent.prototype[method.toLowerCase()] = function(url, fn) {
  1646. var req = new request.Request(method, url);
  1647. this._setDefaults(req);
  1648. if (fn) {
  1649. req.end(fn);
  1650. }
  1651. return req;
  1652. };
  1653. });
  1654. Agent.prototype.del = Agent.prototype['delete'];
  1655. /**
  1656. * GET `url` with optional callback `fn(res)`.
  1657. *
  1658. * @param {String} url
  1659. * @param {Mixed|Function} [data] or fn
  1660. * @param {Function} [fn]
  1661. * @return {Request}
  1662. * @api public
  1663. */
  1664. request.get = function(url, data, fn) {
  1665. var req = request('GET', url);
  1666. if ('function' == typeof data) (fn = data), (data = null);
  1667. if (data) req.query(data);
  1668. if (fn) req.end(fn);
  1669. return req;
  1670. };
  1671. /**
  1672. * HEAD `url` with optional callback `fn(res)`.
  1673. *
  1674. * @param {String} url
  1675. * @param {Mixed|Function} [data] or fn
  1676. * @param {Function} [fn]
  1677. * @return {Request}
  1678. * @api public
  1679. */
  1680. request.head = function(url, data, fn) {
  1681. var req = request('HEAD', url);
  1682. if ('function' == typeof data) (fn = data), (data = null);
  1683. if (data) req.query(data);
  1684. if (fn) req.end(fn);
  1685. return req;
  1686. };
  1687. /**
  1688. * OPTIONS query to `url` with optional callback `fn(res)`.
  1689. *
  1690. * @param {String} url
  1691. * @param {Mixed|Function} [data] or fn
  1692. * @param {Function} [fn]
  1693. * @return {Request}
  1694. * @api public
  1695. */
  1696. request.options = function(url, data, fn) {
  1697. var req = request('OPTIONS', url);
  1698. if ('function' == typeof data) (fn = data), (data = null);
  1699. if (data) req.send(data);
  1700. if (fn) req.end(fn);
  1701. return req;
  1702. };
  1703. /**
  1704. * DELETE `url` with optional `data` and callback `fn(res)`.
  1705. *
  1706. * @param {String} url
  1707. * @param {Mixed} [data]
  1708. * @param {Function} [fn]
  1709. * @return {Request}
  1710. * @api public
  1711. */
  1712. function del(url, data, fn) {
  1713. var req = request('DELETE', url);
  1714. if ('function' == typeof data) (fn = data), (data = null);
  1715. if (data) req.send(data);
  1716. if (fn) req.end(fn);
  1717. return req;
  1718. }
  1719. request['del'] = del;
  1720. request['delete'] = del;
  1721. /**
  1722. * PATCH `url` with optional `data` and callback `fn(res)`.
  1723. *
  1724. * @param {String} url
  1725. * @param {Mixed} [data]
  1726. * @param {Function} [fn]
  1727. * @return {Request}
  1728. * @api public
  1729. */
  1730. request.patch = function(url, data, fn) {
  1731. var req = request('PATCH', url);
  1732. if ('function' == typeof data) (fn = data), (data = null);
  1733. if (data) req.send(data);
  1734. if (fn) req.end(fn);
  1735. return req;
  1736. };
  1737. /**
  1738. * POST `url` with optional `data` and callback `fn(res)`.
  1739. *
  1740. * @param {String} url
  1741. * @param {Mixed} [data]
  1742. * @param {Function} [fn]
  1743. * @return {Request}
  1744. * @api public
  1745. */
  1746. request.post = function(url, data, fn) {
  1747. var req = request('POST', url);
  1748. if ('function' == typeof data) (fn = data), (data = null);
  1749. if (data) req.send(data);
  1750. if (fn) req.end(fn);
  1751. return req;
  1752. };
  1753. /**
  1754. * PUT `url` with optional `data` and callback `fn(res)`.
  1755. *
  1756. * @param {String} url
  1757. * @param {Mixed|Function} [data] or fn
  1758. * @param {Function} [fn]
  1759. * @return {Request}
  1760. * @api public
  1761. */
  1762. request.put = function(url, data, fn) {
  1763. var req = request('PUT', url);
  1764. if ('function' == typeof data) (fn = data), (data = null);
  1765. if (data) req.send(data);
  1766. if (fn) req.end(fn);
  1767. return req;
  1768. };
  1769. },{"./agent-base":1,"./is-object":2,"./request-base":3,"./response-base":4,"component-emitter":6}]},{},[7])(7)
  1770. });