diff --git a/lib/graph-js-sdk-web.js b/lib/graph-js-sdk-web.js index 1b0cbeec6..74a78fac2 100644 --- a/lib/graph-js-sdk-web.js +++ b/lib/graph-js-sdk-web.js @@ -2,3787 +2,4364 @@ // make MicrosoftGraph globally accessible // MicrosoftGraph.api() can be called directly window.MicrosoftGraph = require('./lib/src/index.js'); -},{"./lib/src/index.js":5}],2:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var request = require("superagent"); -var es6_promise_1 = require("es6-promise"); -var common_1 = require("./common"); -var ResponseHandler_1 = require("./ResponseHandler"); -var GraphRequest = (function () { - function GraphRequest(config, path) { - this.config = config; - this._headers = {}; - this.urlComponents = { - host: this.config.baseUrl, - version: this.config.defaultVersion, - oDataQueryParams: {}, - otherURLQueryParams: {} - }; - this.parsePath(path); - } - GraphRequest.prototype.header = function (headerKey, headerValue) { - this._headers[headerKey] = headerValue; - return this; - }; - GraphRequest.prototype.headers = function (headers) { - for (var key in headers) { - this._headers[key] = headers[key]; - } - return this; - }; - GraphRequest.prototype.parsePath = function (rawPath) { - if (rawPath.indexOf("https://") != -1) { - rawPath = rawPath.replace("https://", ""); - var endOfHostStrPos = rawPath.indexOf("/"); - this.urlComponents.host = "https://" + rawPath.substring(0, endOfHostStrPos); - rawPath = rawPath.substring(endOfHostStrPos + 1, rawPath.length); - var endOfVersionStrPos = rawPath.indexOf("/"); - this.urlComponents.version = rawPath.substring(0, endOfVersionStrPos); - rawPath = rawPath.substring(endOfVersionStrPos + 1, rawPath.length); - } - if (rawPath.charAt(0) == "/") { - rawPath = rawPath.substr(1); - } - var queryStrPos = rawPath.indexOf("?"); - if (queryStrPos == -1) { - this.urlComponents.path = rawPath; - } - else { - this.urlComponents.path = rawPath.substr(0, queryStrPos); - var queryParams = rawPath.substring(queryStrPos + 1, rawPath.length).split("&"); - for (var _i = 0, queryParams_1 = queryParams; _i < queryParams_1.length; _i++) { - var queryParam = queryParams_1[_i]; - var queryParams_2 = queryParam.split("="); - var key = queryParams_2[0]; - var value = queryParams_2[1]; - if (common_1.oDataQueryNames.indexOf(key)) { - this.urlComponents.oDataQueryParams[key] = value; - } - else { - this.urlComponents.otherURLQueryParams[key] = value; - } - } - } - }; - GraphRequest.prototype.urlJoin = function (urlSegments) { - var tr = function (s) { return s.replace(/\/+$/, ''); }; - var tl = function (s) { return s.replace(/^\/+/, ''); }; - var joiner = function (pre, cur) { return [tr(pre), tl(cur)].join('/'); }; - var parts = Array.prototype.slice.call(urlSegments); - return parts.reduce(joiner); - }; - GraphRequest.prototype.buildFullUrl = function () { - var url = this.urlJoin([this.urlComponents.host, - this.urlComponents.version, - this.urlComponents.path]) - + this.createQueryString(); - if (this.config.debugLogging) { - console.log(url); - } - return url; - }; - GraphRequest.prototype.version = function (v) { - this.urlComponents.version = v; - return this; - }; - GraphRequest.prototype.select = function (properties) { - this.addCsvQueryParamater("$select", properties, arguments); - return this; - }; - GraphRequest.prototype.expand = function (properties) { - this.addCsvQueryParamater("$expand", properties, arguments); - return this; - }; - GraphRequest.prototype.orderby = function (properties) { - this.addCsvQueryParamater("$orderby", properties, arguments); - return this; - }; - GraphRequest.prototype.filter = function (filterStr) { - this.urlComponents.oDataQueryParams["$filter"] = filterStr; - return this; - }; - GraphRequest.prototype.top = function (n) { - this.urlComponents.oDataQueryParams["$top"] = n; - return this; - }; - GraphRequest.prototype.skip = function (n) { - this.urlComponents.oDataQueryParams["$skip"] = n; - return this; - }; - GraphRequest.prototype.skipToken = function (token) { - this.urlComponents.oDataQueryParams["$skipToken"] = token; - return this; - }; - GraphRequest.prototype.count = function (count) { - this.urlComponents.oDataQueryParams["$count"] = count.toString(); - return this; - }; - GraphRequest.prototype.responseType = function (responseType) { - this._responseType = responseType; - return this; - }; - GraphRequest.prototype.addCsvQueryParamater = function (propertyName, propertyValue, additionalProperties) { - this.urlComponents.oDataQueryParams[propertyName] = this.urlComponents.oDataQueryParams[propertyName] ? this.urlComponents.oDataQueryParams[propertyName] + "," : ""; - var allValues = []; - if (typeof propertyValue === "string") { - allValues.push(propertyValue); - } - else { - allValues = allValues.concat(propertyValue); - } - if (additionalProperties.length > 1 && typeof propertyValue === "string") { - allValues = Array.prototype.slice.call(additionalProperties); - } - this.urlComponents.oDataQueryParams[propertyName] += allValues.join(","); - }; - GraphRequest.prototype.delete = function (callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request.del(url), callback); - }; - GraphRequest.prototype.patch = function (content, callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .patch(url) - .send(content), callback); - }; - GraphRequest.prototype.post = function (content, callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .post(url) - .send(content), callback); - }; - GraphRequest.prototype.put = function (content, callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .put(url) - .type('application/octet-stream') - .send(content), callback); - }; - GraphRequest.prototype.create = function (content, callback) { - return this.post(content, callback); - }; - GraphRequest.prototype.update = function (content, callback) { - return this.patch(content, callback); - }; - GraphRequest.prototype.del = function (callback) { - return this.delete(callback); - }; - GraphRequest.prototype.get = function (callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .get(url), callback); - }; - GraphRequest.prototype.routeResponseToPromise = function (requestBuilder) { - var _this = this; - return new es6_promise_1.Promise(function (resolve, reject) { - _this.routeResponseToCallback(requestBuilder, function (err, body) { - if (err != null) { - reject(err); - } - else { - resolve(body); - } - }); - }); - }; - GraphRequest.prototype.routeResponseToCallback = function (requestBuilder, callback) { - var _this = this; - this.config.authProvider(function (err, accessToken) { - if (err == null && accessToken != null) { - var request_1 = _this.configureRequest(requestBuilder, accessToken); - request_1.end(function (err, res) { - ResponseHandler_1.ResponseHandler.init(err, res, callback); - }); - } - else { - callback(err, null, null); - } - }); - }; - GraphRequest.prototype.sendRequestAndRouteResponse = function (requestBuilder, callback) { - if (callback == null && typeof es6_promise_1.Promise !== "undefined") { - return this.routeResponseToPromise(requestBuilder); - } - else { - this.routeResponseToCallback(requestBuilder, callback || function () { }); - } - }; - GraphRequest.prototype.getStream = function (callback) { - var _this = this; - this.config.authProvider(function (err, accessToken) { - if (err === null && accessToken !== null) { - var url = _this.buildFullUrl(); - callback(null, _this.configureRequest(request.get(url), accessToken)); - } - else { - callback(err, null); - } - }); - }; - GraphRequest.prototype.putStream = function (stream, callback) { - var _this = this; - this.config.authProvider(function (err, accessToken) { - if (err === null && accessToken !== null) { - var url = _this.buildFullUrl(); - var req = _this.configureRequest(request.put(url), accessToken); - req.type('application/octet-stream'); - stream - .pipe(req) - .on('error', function (err) { - callback(err, null); - }) - .on('end', function () { - callback(null); - }); - } - }); - }; - GraphRequest.prototype.configureRequest = function (requestBuilder, accessToken) { - var request = requestBuilder - .set('Authorization', 'Bearer ' + accessToken) - .set(this._headers) - .set('SdkVersion', "graph-js-" + common_1.PACKAGE_VERSION); - if (this._responseType !== undefined) { - request.responseType(this._responseType); - } - return request; - }; - GraphRequest.prototype.query = function (queryDictionaryOrString) { - if (typeof queryDictionaryOrString === "string") { - var queryStr = queryDictionaryOrString; - var queryKey = queryStr.split("=")[0]; - var queryValue = queryStr.split("=")[1]; - this.urlComponents.otherURLQueryParams[queryKey] = queryValue; - } - else { - for (var key in queryDictionaryOrString) { - this.urlComponents.otherURLQueryParams[key] = queryDictionaryOrString[key]; - } - } - return this; - }; - GraphRequest.prototype.createQueryString = function () { - var q = []; - if (Object.keys(this.urlComponents.oDataQueryParams).length != 0) { - for (var property in this.urlComponents.oDataQueryParams) { - q.push(property + "=" + this.urlComponents.oDataQueryParams[property]); - } - } - if (Object.keys(this.urlComponents.otherURLQueryParams).length != 0) { - for (var property in this.urlComponents.otherURLQueryParams) { - q.push(property + "=" + this.urlComponents.otherURLQueryParams[property]); - } - } - if (q.length > 0) { - return "?" + q.join("&"); - } - return ""; - }; - return GraphRequest; -}()); -exports.GraphRequest = GraphRequest; - -},{"./ResponseHandler":3,"./common":4,"es6-promise":7,"superagent":10}],3:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var ResponseHandler = (function () { - function ResponseHandler() { - } - ResponseHandler.init = function (err, res, callback) { - if (res && res.ok) { - callback(null, res.body, res); - } - else { - if (err == null && res.error !== null) - callback(ResponseHandler.ParseError(res), null, res); - else - callback(ResponseHandler.ParseError(err), null, res); - } - }; - ResponseHandler.ParseError = function (rawErr) { - var errObj; - if (!('rawResponse' in rawErr)) { - if (rawErr.response !== undefined && rawErr.response.body !== null && 'error' in rawErr.response.body) { - errObj = rawErr.response.body.error; - } - } - else { - errObj = JSON.parse(rawErr.rawResponse.replace(/^\uFEFF/, '')).error; - } - var statusCode; - if (rawErr.response !== undefined && rawErr.response.status !== undefined) { - statusCode = rawErr.response.status; - } - else { - statusCode = rawErr.statusCode; - } - if (errObj === undefined) { - return { - statusCode: statusCode, - code: null, - message: null, - requestId: null, - date: new Date(), - body: null - }; - } - var err = { - statusCode: statusCode, - code: errObj.code, - message: errObj.message, - requestId: errObj.innerError["request-id"], - date: new Date(errObj.innerError.date), - body: errObj - }; - return err; - }; - return ResponseHandler; -}()); -exports.ResponseHandler = ResponseHandler; - -},{}],4:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.oDataQueryNames = ["select", "expand", "orderby", "filter", "top", "skip", "skipToken", "count"]; -exports.DEFAULT_VERSION = "v1.0"; -exports.GRAPH_BASE_URL = "https://graph.microsoft.com/"; -exports.PACKAGE_VERSION = "1.0.0"; -exports.oDataQueryNames = exports.oDataQueryNames.concat(exports.oDataQueryNames.map(function (s) { return "$" + s; })); +},{"./lib/src/index.js":7}],2:[function(require,module,exports){ +(function (Buffer){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var GraphHelper = (function () { + function GraphHelper() { + } + GraphHelper.serializeContent = function (content) { + var className = content.constructor.name; + if (className === 'Buffer' + || className === 'Blob' + || className === 'File' + || className === 'FormData' + || typeof content === 'string') { + return content; + } + if (className === 'ArrayBuffer') { + content = Buffer.from(content); + } + else if (className === 'Int8Array' + || className === 'Int16Array' + || className === 'Int32Array' + || className === 'Uint8Array' + || className === 'Uint16Array' + || className === 'Uint32Array' + || className === 'Uint8ClampedArray' + || className === 'Float32Array' + || className === 'Float64Array' + || className === 'DataView') { + content = Buffer.from(content.buffer); + } + else { + try { + content = JSON.stringify(content); + } + catch (error) { + console.log(error); + throw new Error('Invalid JSON content'); + } + } + return content; + }; + return GraphHelper; +}()); +exports.GraphHelper = GraphHelper; + +}).call(this,require("buffer").Buffer) +},{"buffer":9}],3:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var es6_promise_1 = require("es6-promise"); +require("isomorphic-fetch"); +var common_1 = require("./common"); +var ResponseHandler_1 = require("./ResponseHandler"); +var RequestMethod_1 = require("./RequestMethod"); +var GraphHelper_1 = require("./GraphHelper"); +var GraphRequest = (function () { + function GraphRequest(config, path) { + this.config = config; + this._headers = {}; + this.urlComponents = { + host: this.config.baseUrl, + version: this.config.defaultVersion, + oDataQueryParams: {}, + otherURLQueryParams: {} + }; + this.parsePath(path); + } + GraphRequest.prototype.header = function (headerKey, headerValue) { + this._headers[headerKey] = headerValue; + return this; + }; + GraphRequest.prototype.headers = function (headers) { + for (var key in headers) { + this._headers[key] = headers[key]; + } + return this; + }; + GraphRequest.prototype.parsePath = function (rawPath) { + if (rawPath.indexOf("https://") != -1) { + rawPath = rawPath.replace("https://", ""); + var endOfHostStrPos = rawPath.indexOf("/"); + this.urlComponents.host = "https://" + rawPath.substring(0, endOfHostStrPos); + rawPath = rawPath.substring(endOfHostStrPos + 1, rawPath.length); + var endOfVersionStrPos = rawPath.indexOf("/"); + this.urlComponents.version = rawPath.substring(0, endOfVersionStrPos); + rawPath = rawPath.substring(endOfVersionStrPos + 1, rawPath.length); + } + if (rawPath.charAt(0) == "/") { + rawPath = rawPath.substr(1); + } + var queryStrPos = rawPath.indexOf("?"); + if (queryStrPos == -1) { + this.urlComponents.path = rawPath; + } + else { + this.urlComponents.path = rawPath.substr(0, queryStrPos); + var queryParams = rawPath.substring(queryStrPos + 1, rawPath.length).split("&"); + for (var _i = 0, queryParams_1 = queryParams; _i < queryParams_1.length; _i++) { + var queryParam = queryParams_1[_i]; + var queryParams_2 = queryParam.split("="); + var key = queryParams_2[0]; + var value = queryParams_2[1]; + if (common_1.oDataQueryNames.indexOf(key)) { + this.urlComponents.oDataQueryParams[key] = value; + } + else { + this.urlComponents.otherURLQueryParams[key] = value; + } + } + } + }; + GraphRequest.prototype.urlJoin = function (urlSegments) { + var tr = function (s) { return s.replace(/\/+$/, ''); }; + var tl = function (s) { return s.replace(/^\/+/, ''); }; + var joiner = function (pre, cur) { return [tr(pre), tl(cur)].join('/'); }; + var parts = Array.prototype.slice.call(urlSegments); + return parts.reduce(joiner); + }; + GraphRequest.prototype.buildFullUrl = function () { + var url = this.urlJoin([this.urlComponents.host, + this.urlComponents.version, + this.urlComponents.path]) + + this.createQueryString(); + if (this.config.debugLogging) { + console.log(url); + } + return url; + }; + GraphRequest.prototype.version = function (v) { + this.urlComponents.version = v; + return this; + }; + GraphRequest.prototype.select = function (properties) { + this.addCsvQueryParamater("$select", properties, arguments); + return this; + }; + GraphRequest.prototype.expand = function (properties) { + this.addCsvQueryParamater("$expand", properties, arguments); + return this; + }; + GraphRequest.prototype.orderby = function (properties) { + this.addCsvQueryParamater("$orderby", properties, arguments); + return this; + }; + GraphRequest.prototype.filter = function (filterStr) { + this.urlComponents.oDataQueryParams["$filter"] = filterStr; + return this; + }; + GraphRequest.prototype.top = function (n) { + this.urlComponents.oDataQueryParams["$top"] = n; + return this; + }; + GraphRequest.prototype.skip = function (n) { + this.urlComponents.oDataQueryParams["$skip"] = n; + return this; + }; + GraphRequest.prototype.skipToken = function (token) { + this.urlComponents.oDataQueryParams["$skipToken"] = token; + return this; + }; + GraphRequest.prototype.count = function (count) { + this.urlComponents.oDataQueryParams["$count"] = count.toString(); + return this; + }; + GraphRequest.prototype.responseType = function (responseType) { + this._responseType = responseType; + return this; + }; + GraphRequest.prototype.addCsvQueryParamater = function (propertyName, propertyValue, additionalProperties) { + this.urlComponents.oDataQueryParams[propertyName] = this.urlComponents.oDataQueryParams[propertyName] ? this.urlComponents.oDataQueryParams[propertyName] + "," : ""; + var allValues = []; + if (typeof propertyValue === "string") { + allValues.push(propertyValue); + } + else { + allValues = allValues.concat(propertyValue); + } + if (additionalProperties.length > 1 && typeof propertyValue === "string") { + allValues = Array.prototype.slice.call(additionalProperties); + } + this.urlComponents.oDataQueryParams[propertyName] += allValues.join(","); + }; + GraphRequest.prototype.delete = function (callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { method: RequestMethod_1.RequestMethod.DELETE, headers: new Headers() }), callback); + }; + GraphRequest.prototype.patch = function (content, callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { + method: RequestMethod_1.RequestMethod.PATCH, + body: GraphHelper_1.GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/json' }) + }), callback); + }; + GraphRequest.prototype.post = function (content, callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { + method: RequestMethod_1.RequestMethod.POST, + body: GraphHelper_1.GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/json' }) + }), callback); + }; + GraphRequest.prototype.put = function (content, callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { + method: RequestMethod_1.RequestMethod.PUT, + body: GraphHelper_1.GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/octet-stream' }) + }), callback); + }; + GraphRequest.prototype.create = function (content, callback) { + return this.post(content, callback); + }; + GraphRequest.prototype.update = function (content, callback) { + return this.patch(content, callback); + }; + GraphRequest.prototype.del = function (callback) { + return this.delete(callback); + }; + GraphRequest.prototype.get = function (callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { method: RequestMethod_1.RequestMethod.GET, headers: new Headers() }), callback); + }; + GraphRequest.prototype.routeResponseToPromise = function (request) { + var _this = this; + return new es6_promise_1.Promise(function (resolve, reject) { + _this.routeResponseToCallback(request, function (err, body) { + if (err != null) { + reject(err); + } + else { + resolve(body); + } + }); + }); + }; + GraphRequest.prototype.routeResponseToCallback = function (request, callback) { + var _this = this; + this.config.authProvider(function (err, accessToken) { + if (err == null && accessToken != null) { + fetch(_this.configureRequest(request, accessToken)).then(function (response) { + _this.convertResponseType(response).then(function (responseValue) { + ResponseHandler_1.ResponseHandler.init(response, undefined, responseValue, callback); + }).catch(function (error) { + ResponseHandler_1.ResponseHandler.init(response, error, undefined, callback); + }); + }).catch(function (error) { + ResponseHandler_1.ResponseHandler.init(undefined, error, undefined, callback); + }); + } + else { + callback(err, null, null); + } + }); + }; + GraphRequest.prototype.sendRequestAndRouteResponse = function (request, callback) { + if (callback == null && typeof es6_promise_1.Promise !== "undefined") { + return this.routeResponseToPromise(request); + } + else { + this.routeResponseToCallback(request, callback || function () { }); + } + }; + GraphRequest.prototype.getStream = function (callback) { + var _this = this; + this.config.authProvider(function (err, accessToken) { + if (err === null && accessToken !== null) { + var url = _this.buildFullUrl(); + callback(null, _this.configureRequest(new Request(url, { method: RequestMethod_1.RequestMethod.GET, headers: new Headers() }), accessToken)); + } + else { + callback(err, null); + } + }); + }; + GraphRequest.prototype.putStream = function (stream, callback) { + var _this = this; + this.config.authProvider(function (err, accessToken) { + if (err === null && accessToken !== null) { + var url = _this.buildFullUrl(); + var req = _this.configureRequest(new Request(url, { + method: RequestMethod_1.RequestMethod.PUT, + headers: new Headers({ 'Content-Type': 'application/octet-stream' }) + }), accessToken); + stream + .pipe(req) + .on('error', function (err) { + callback(err, null); + }) + .on('end', function () { + callback(null); + }); + } + }); + }; + GraphRequest.prototype.configureRequest = function (request, accessToken) { + var _this = this; + request.headers.append('Authorization', 'Bearer ' + accessToken); + request.headers.append('SdkVersion', "graph-js-" + common_1.PACKAGE_VERSION); + Object.keys(this._headers).forEach(function (key) { return request.headers.set(key, _this._headers[key]); }); + return request; + }; + GraphRequest.prototype.query = function (queryDictionaryOrString) { + if (typeof queryDictionaryOrString === "string") { + var queryStr = queryDictionaryOrString; + var queryKey = queryStr.split("=")[0]; + var queryValue = queryStr.split("=")[1]; + this.urlComponents.otherURLQueryParams[queryKey] = queryValue; + } + else { + for (var key in queryDictionaryOrString) { + this.urlComponents.otherURLQueryParams[key] = queryDictionaryOrString[key]; + } + } + return this; + }; + GraphRequest.prototype.createQueryString = function () { + var q = []; + if (Object.keys(this.urlComponents.oDataQueryParams).length != 0) { + for (var property in this.urlComponents.oDataQueryParams) { + q.push(property + "=" + this.urlComponents.oDataQueryParams[property]); + } + } + if (Object.keys(this.urlComponents.otherURLQueryParams).length != 0) { + for (var property in this.urlComponents.otherURLQueryParams) { + q.push(property + "=" + this.urlComponents.otherURLQueryParams[property]); + } + } + if (q.length > 0) { + return "?" + q.join("&"); + } + return ""; + }; + GraphRequest.prototype.convertResponseType = function (response) { + var responseValue; + if (!this._responseType) { + this._responseType = ''; + } + switch (this._responseType.toLowerCase()) { + case "arraybuffer": + responseValue = response.arrayBuffer(); + break; + case "blob": + responseValue = response.blob(); + break; + case "document": + responseValue = response.json(); + break; + case "json": + responseValue = response.json(); + break; + case "text": + responseValue = response.text(); + break; + default: + responseValue = response.json(); + break; + } + return responseValue; + }; + return GraphRequest; +}()); +exports.GraphRequest = GraphRequest; + +},{"./GraphHelper":2,"./RequestMethod":4,"./ResponseHandler":5,"./common":6,"es6-promise":10,"isomorphic-fetch":13}],4:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var RequestMethod; +(function (RequestMethod) { + RequestMethod["GET"] = "GET"; + RequestMethod["PATCH"] = "PATCH"; + RequestMethod["POST"] = "POST"; + RequestMethod["PUT"] = "PUT"; + RequestMethod["DELETE"] = "DELETE"; +})(RequestMethod = exports.RequestMethod || (exports.RequestMethod = {})); },{}],5:[function(require,module,exports){ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -Object.defineProperty(exports, "__esModule", { value: true }); -var common_1 = require("./common"); -var GraphRequest_1 = require("./GraphRequest"); -var Client = (function () { - function Client() { - this.config = { - debugLogging: false, - defaultVersion: common_1.DEFAULT_VERSION, - baseUrl: common_1.GRAPH_BASE_URL - }; - } - Client.init = function (clientOptions) { - var graphClient = new Client(); - for (var key in clientOptions) { - graphClient.config[key] = clientOptions[key]; - } - return graphClient; - }; - Client.prototype.api = function (path) { - return new GraphRequest_1.GraphRequest(this.config, path); - }; - return Client; -}()); -exports.Client = Client; -__export(require("./GraphRequest")); -__export(require("./common")); -__export(require("./ResponseHandler")); +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ResponseHandler = (function () { + function ResponseHandler() { + } + ResponseHandler.init = function (res, err, resContents, callback) { + if (res && res.ok) { + callback(null, resContents, res); + } + else { + if (err == null && res != null) + if (resContents != null && resContents.error != null) + callback(ResponseHandler.buildGraphErrorFromResponseObject(resContents.error, res.status), null, res); + else + callback(ResponseHandler.defaultGraphError(res.status), null, res); + else + callback(ResponseHandler.ParseError(err), null, res); + } + }; + ResponseHandler.ParseError = function (rawErr) { + if (!rawErr) { + return ResponseHandler.defaultGraphError(-1); + } + return ResponseHandler.buildGraphErrorFromErrorObject(rawErr); + }; + ResponseHandler.defaultGraphError = function (statusCode) { + return { + statusCode: statusCode, + code: null, + message: null, + requestId: null, + date: new Date(), + body: null + }; + }; + ResponseHandler.buildGraphErrorFromErrorObject = function (errObj) { + var error = ResponseHandler.defaultGraphError(-1); + error.body = errObj.toString(); + error.message = errObj.message; + error.date = new Date(); + return error; + }; + ResponseHandler.buildGraphErrorFromResponseObject = function (errObj, statusCode) { + return { + statusCode: statusCode, + code: errObj.code, + message: errObj.message, + requestId: errObj.innerError["request-id"], + date: new Date(errObj.innerError.date), + body: errObj + }; + }; + return ResponseHandler; +}()); +exports.ResponseHandler = ResponseHandler; + +},{}],6:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.oDataQueryNames = ["select", "expand", "orderby", "filter", "top", "skip", "skipToken", "count"]; +exports.DEFAULT_VERSION = "v1.0"; +exports.GRAPH_BASE_URL = "https://graph.microsoft.com/"; +exports.PACKAGE_VERSION = "1.0.0"; +exports.oDataQueryNames = exports.oDataQueryNames.concat(exports.oDataQueryNames.map(function (s) { return "$" + s; })); + +},{}],7:[function(require,module,exports){ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("./common"); +var GraphRequest_1 = require("./GraphRequest"); +var Client = (function () { + function Client() { + this.config = { + debugLogging: false, + defaultVersion: common_1.DEFAULT_VERSION, + baseUrl: common_1.GRAPH_BASE_URL + }; + } + Client.init = function (clientOptions) { + var graphClient = new Client(); + for (var key in clientOptions) { + graphClient.config[key] = clientOptions[key]; + } + return graphClient; + }; + Client.prototype.api = function (path) { + return new GraphRequest_1.GraphRequest(this.config, path); + }; + return Client; +}()); +exports.Client = Client; +__export(require("./GraphRequest")); +__export(require("./common")); +__export(require("./ResponseHandler")); + +},{"./GraphRequest":3,"./ResponseHandler":5,"./common":6}],8:[function(require,module,exports){ +'use strict' + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} -},{"./GraphRequest":2,"./ResponseHandler":3,"./common":4}],6:[function(require,module,exports){ +// Support decoding URL-safe base64 strings, as Node.js does. +// See: https://en.wikipedia.org/wiki/Base64#URL_applications +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 -/** - * Expose `Emitter`. - */ +function getLens (b64) { + var len = b64.length -if (typeof module !== 'undefined') { - module.exports = Emitter; + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // Trim off extra bytes after placeholder bytes are found + // See: https://github.com/beatgammit/base64-js/issues/42 + var validLen = b64.indexOf('=') + if (validLen === -1) validLen = len + + var placeHoldersLen = validLen === len + ? 0 + : 4 - (validLen % 4) + + return [validLen, placeHoldersLen] } -/** - * Initialize a new `Emitter`. - * - * @api public - */ +// base64 is 4/3 + up to two characters of the original data +function byteLength (b64) { + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} -function Emitter(obj) { - if (obj) return mixin(obj); -}; +function _byteLength (b64, validLen, placeHoldersLen) { + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ +function toByteArray (b64) { + var tmp + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) + + var curByte = 0 + + // if there are placeholders, only get up to the last complete 4 chars + var len = placeHoldersLen > 0 + ? validLen - 4 + : validLen + + for (var i = 0; i < len; i += 4) { + tmp = + (revLookup[b64.charCodeAt(i)] << 18) | + (revLookup[b64.charCodeAt(i + 1)] << 12) | + (revLookup[b64.charCodeAt(i + 2)] << 6) | + revLookup[b64.charCodeAt(i + 3)] + arr[curByte++] = (tmp >> 16) & 0xFF + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 2) { + tmp = + (revLookup[b64.charCodeAt(i)] << 2) | + (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[curByte++] = tmp & 0xFF + } -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; + if (placeHoldersLen === 1) { + tmp = + (revLookup[b64.charCodeAt(i)] << 10) | + (revLookup[b64.charCodeAt(i + 1)] << 4) | + (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF } - return obj; + + return arr } -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + + lookup[num >> 12 & 0x3F] + + lookup[num >> 6 & 0x3F] + + lookup[num & 0x3F] +} -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks['$' + event] = this._callbacks['$' + event] || []) - .push(fn); - return this; -}; +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = + ((uint8[i] << 16) & 0xFF0000) + + ((uint8[i + 1] << 8) & 0xFF00) + + (uint8[i + 2] & 0xFF) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk( + uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) + )) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + parts.push( + lookup[tmp >> 2] + + lookup[(tmp << 4) & 0x3F] + + '==' + ) + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + uint8[len - 1] + parts.push( + lookup[tmp >> 10] + + lookup[(tmp >> 4) & 0x3F] + + lookup[(tmp << 2) & 0x3F] + + '=' + ) + } + + return parts.join('') +} + +},{}],9:[function(require,module,exports){ +(function (global){ +/*! + * The buffer module from node.js, for the browser. * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public + * @author Feross Aboukhadijeh + * @license MIT */ +/* eslint-disable no-proto */ -Emitter.prototype.once = function(event, fn){ - function on() { - this.off(event, on); - fn.apply(this, arguments); - } +'use strict' - on.fn = fn; - this.on(event, on); - return this; -}; +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('isarray') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 /** - * Remove the given callback for `event` or all - * registered callbacks. + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; +/* + * Export kMaxLength after typed array support is determined. + */ +exports.kMaxLength = kMaxLength() - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; +function typedArraySupport () { + try { + var arr = new Uint8Array(1) + arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false } +} - // specific event - var callbacks = this._callbacks['$' + event]; - if (!callbacks) return this; +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks['$' + event]; - return this; +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length) } + that.length = length } - return this; -}; + + return that +} /** - * Emit `event` with the given args. + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} + * The `Uint8Array` prototype remains unmodified. */ -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks['$' + event]; +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) } + return allocUnsafe(this, arg) } + return from(this, arg, encodingOrOffset, length) +} - return this; -}; +Buffer.poolSize = 8192 // not used by this implementation -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr +} -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks['$' + event] || []; -}; +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } -},{}],7:[function(require,module,exports){ -(function (process,global){ -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE - * @version v4.2.4+314e4831 - */ + return fromObject(that, value) +} -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.ES6Promise = factory()); -}(this, (function () { 'use strict'; +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +} -function objectOrFunction(x) { - var type = typeof x; - return x !== null && (type === 'object' || type === 'function'); +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true + }) + } } -function isFunction(x) { - return typeof x === 'function'; +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } } +function alloc (that, size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +} -var _isArray = void 0; -if (Array.isArray) { - _isArray = Array.isArray; -} else { - _isArray = function (x) { - return Object.prototype.toString.call(x) === '[object Array]'; - }; +function allocUnsafe (that, size) { + assertSize(size) + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0 + } + } + return that } -var isArray = _isArray; +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +} -var len = 0; -var vertxNext = void 0; -var customSchedulerFn = void 0; +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } -var asap = function asap(callback, arg) { - queue[len] = callback; - queue[len + 1] = arg; - len += 2; - if (len === 2) { - // If len is 2, that means that we need to schedule an async flush. - // If additional callbacks are queued before the queue is flushed, they - // will be processed by this flush that we are scheduling. - if (customSchedulerFn) { - customSchedulerFn(flush); - } else { - scheduleFlush(); - } + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') } -}; -function setScheduler(scheduleFn) { - customSchedulerFn = scheduleFn; + var length = byteLength(string, encoding) | 0 + that = createBuffer(that, length) + + var actual = that.write(string, encoding) + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual) + } + + return that } -function setAsap(asapFn) { - asap = asapFn; +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0 + that = createBuffer(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that } -var browserWindow = typeof window !== 'undefined' ? window : undefined; -var browserGlobal = browserWindow || {}; -var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; -var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer -// test for web worker but not in IE10 -var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } -// node -function useNextTick() { - // node version 0.10.x displays a deprecation warning when nextTick is used recursively - // see https://github.com/cujojs/when/issues/410 for details - return function () { - return process.nextTick(flush); - }; -} + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } -// vertx -function useVertxTimer() { - if (typeof vertxNext !== 'undefined') { - return function () { - vertxNext(flush); - }; + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array) + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset) + } else { + array = new Uint8Array(array, byteOffset, length) } - return useSetTimeout(); + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array) + } + return that } -function useMutationObserver() { - var iterations = 0; - var observer = new BrowserMutationObserver(flush); - var node = document.createTextNode(''); - observer.observe(node, { characterData: true }); +function fromObject (that, obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + that = createBuffer(that, len) - return function () { - node.data = iterations = ++iterations % 2; - }; -} + if (that.length === 0) { + return that + } -// web worker -function useMessageChannel() { - var channel = new MessageChannel(); - channel.port1.onmessage = flush; - return function () { - return channel.port2.postMessage(0); - }; -} + obj.copy(that, 0, 0, len) + return that + } -function useSetTimeout() { - // Store setTimeout reference so es6-promise will be unaffected by - // other code modifying setTimeout (like sinon.useFakeTimers()) - var globalSetTimeout = setTimeout; - return function () { - return globalSetTimeout(flush, 1); - }; -} + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } -var queue = new Array(1000); -function flush() { - for (var i = 0; i < len; i += 2) { - var callback = queue[i]; - var arg = queue[i + 1]; + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } - callback(arg); + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} - queue[i] = undefined; - queue[i + 1] = undefined; +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') } - - len = 0; + return length | 0 } -function attemptVertx() { - try { - var vertx = Function('return this')().require('vertx'); - vertxNext = vertx.runOnLoop || vertx.runOnContext; - return useVertxTimer(); - } catch (e) { - return useSetTimeout(); +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 } + return Buffer.alloc(+length) } -var scheduleFlush = void 0; -// Decide what async method to use to triggering processing of queued callbacks: -if (isNode) { - scheduleFlush = useNextTick(); -} else if (BrowserMutationObserver) { - scheduleFlush = useMutationObserver(); -} else if (isWorker) { - scheduleFlush = useMessageChannel(); -} else if (browserWindow === undefined && typeof require === 'function') { - scheduleFlush = attemptVertx(); -} else { - scheduleFlush = useSetTimeout(); +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) } -function then(onFulfillment, onRejection) { - var parent = this; +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } - var child = new this.constructor(noop); + if (a === b) return 0 - if (child[PROMISE_ID] === undefined) { - makePromise(child); + var x = a.length + var y = b.length + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break + } } - var _state = parent._state; + if (x < y) return -1 + if (y < x) return 1 + return 0 +} +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} - if (_state) { - var callback = arguments[_state - 1]; - asap(function () { - return invokeCallback(_state, child, callback, parent._result); - }); - } else { - subscribe(parent, child, onFulfillment, onRejection); +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') } - return child; -} + if (list.length === 0) { + return Buffer.alloc(0) + } -/** - `Promise.resolve` returns a promise that will become resolved with the - passed `value`. It is shorthand for the following: + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; ++i) { + length += list[i].length + } + } - ```javascript - let promise = new Promise(function(resolve, reject){ - resolve(1); - }); + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; ++i) { + var buf = list[i] + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length + } + return buffer +} - promise.then(function(value){ - // value === 1 - }); - ``` +function byteLength (string, encoding) { + if (Buffer.isBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string + } - Instead of writing the above, your code now simply becomes the following: + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength - ```javascript - let promise = Promise.resolve(1); +function slowToString (encoding, start, end) { + var loweredCase = false - promise.then(function(value){ - // value === 1 - }); - ``` + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. - @method resolve - @static - @param {Any} value value that the returned promise will be resolved with - Useful for tooling. - @return {Promise} a promise that will become fulfilled with the given - `value` -*/ -function resolve$1(object) { - /*jshint validthis:true */ - var Constructor = this; + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } - if (object && typeof object === 'object' && object.constructor === Constructor) { - return object; + if (end === undefined || end > this.length) { + end = this.length } - var promise = new Constructor(noop); - resolve(promise, object); - return promise; -} + if (end <= 0) { + return '' + } -var PROMISE_ID = Math.random().toString(36).substring(2); + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 -function noop() {} + if (end <= start) { + return '' + } -var PENDING = void 0; -var FULFILLED = 1; -var REJECTED = 2; + if (!encoding) encoding = 'utf8' -var TRY_CATCH_ERROR = { error: null }; + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) -function selfFulfillment() { - return new TypeError("You cannot resolve a promise with itself"); -} + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) -function cannotReturnOwn() { - return new TypeError('A promises callback cannot return that same promise.'); -} + case 'ascii': + return asciiSlice(this, start, end) -function getThen(promise) { - try { - return promise.then; - } catch (error) { - TRY_CATCH_ERROR.error = error; - return TRY_CATCH_ERROR; - } -} + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) -function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) { - try { - then$$1.call(value, fulfillmentHandler, rejectionHandler); - } catch (e) { - return e; + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } } } -function handleForeignThenable(promise, thenable, then$$1) { - asap(function (promise) { - var sealed = false; - var error = tryThen(then$$1, thenable, function (value) { - if (sealed) { - return; - } - sealed = true; - if (thenable !== value) { - resolve(promise, value); - } else { - fulfill(promise, value); - } - }, function (reason) { - if (sealed) { - return; - } - sealed = true; - - reject(promise, reason); - }, 'Settle: ' + (promise._label || ' unknown promise')); +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true - if (!sealed && error) { - sealed = true; - reject(promise, error); - } - }, promise); +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i } -function handleOwnThenable(promise, thenable) { - if (thenable._state === FULFILLED) { - fulfill(promise, thenable._result); - } else if (thenable._state === REJECTED) { - reject(promise, thenable._result); - } else { - subscribe(thenable, undefined, function (value) { - return resolve(promise, value); - }, function (reason) { - return reject(promise, reason); - }); +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) } + return this } -function handleMaybeThenable(promise, maybeThenable, then$$1) { - if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) { - handleOwnThenable(promise, maybeThenable); - } else { - if (then$$1 === TRY_CATCH_ERROR) { - reject(promise, TRY_CATCH_ERROR.error); - TRY_CATCH_ERROR.error = null; - } else if (then$$1 === undefined) { - fulfill(promise, maybeThenable); - } else if (isFunction(then$$1)) { - handleForeignThenable(promise, maybeThenable, then$$1); - } else { - fulfill(promise, maybeThenable); - } +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) } + return this } -function resolve(promise, value) { - if (promise === value) { - reject(promise, selfFulfillment()); - } else if (objectOrFunction(value)) { - handleMaybeThenable(promise, value, getThen(value)); - } else { - fulfill(promise, value); +Buffer.prototype.swap64 = function swap64 () { + var len = this.length + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7) + swap(this, i + 1, i + 6) + swap(this, i + 2, i + 5) + swap(this, i + 3, i + 4) } + return this } -function publishRejection(promise) { - if (promise._onerror) { - promise._onerror(promise._result); - } +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} - publish(promise); +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 } -function fulfill(promise, value) { - if (promise._state !== PENDING) { - return; +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' } + return '' +} - promise._result = value; - promise._state = FULFILLED; +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!Buffer.isBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } - if (promise._subscribers.length !== 0) { - asap(publish, promise); + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length } -} -function reject(promise, reason) { - if (promise._state !== PENDING) { - return; + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') } - promise._state = REJECTED; - promise._result = reason; - asap(publishRejection, promise); -} + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } -function subscribe(parent, child, onFulfillment, onRejection) { - var _subscribers = parent._subscribers; - var length = _subscribers.length; + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 + if (this === target) return 0 - parent._onerror = null; + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) - _subscribers[length] = child; - _subscribers[length + FULFILLED] = onFulfillment; - _subscribers[length + REJECTED] = onRejection; + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) - if (length === 0 && parent._state) { - asap(publish, parent); + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break + } } -} -function publish(promise) { - var subscribers = promise._subscribers; - var settled = promise._state; + if (x < y) return -1 + if (y < x) return 1 + return 0 +} - if (subscribers.length === 0) { - return; +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } + byteOffset = +byteOffset // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1) } - var child = void 0, - callback = void 0, - detail = promise._result; + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1 + } else if (byteOffset < 0) { + if (dir) byteOffset = 0 + else return -1 + } - for (var i = 0; i < subscribers.length; i += 3) { - child = subscribers[i]; - callback = subscribers[i + settled]; + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding) + } - if (child) { - invokeCallback(settled, child, callback, detail); - } else { - callback(detail); + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (Buffer.isBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } - promise._subscribers.length = 0; + throw new TypeError('val must be string, number or Buffer') } -function tryCatch(callback, detail) { - try { - return callback(detail); - } catch (e) { - TRY_CATCH_ERROR.error = e; - return TRY_CATCH_ERROR; +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 + } } -} - -function invokeCallback(settled, promise, callback, detail) { - var hasCallback = isFunction(callback), - value = void 0, - error = void 0, - succeeded = void 0, - failed = void 0; - - if (hasCallback) { - value = tryCatch(callback, detail); - if (value === TRY_CATCH_ERROR) { - failed = true; - error = value.error; - value.error = null; + function read (buf, i) { + if (indexSize === 1) { + return buf[i] } else { - succeeded = true; + return buf.readUInt16BE(i * indexSize) } + } - if (promise === value) { - reject(promise, cannotReturnOwn()); - return; + var i + if (dir) { + var foundIndex = -1 + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 + } } } else { - value = detail; - succeeded = true; + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength + for (i = byteOffset; i >= 0; i--) { + var found = true + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false + break + } + } + if (found) return i + } } - if (promise._state !== PENDING) { - // noop - } else if (hasCallback && succeeded) { - resolve(promise, value); - } else if (failed) { - reject(promise, error); - } else if (settled === FULFILLED) { - fulfill(promise, value); - } else if (settled === REJECTED) { - reject(promise, value); - } + return -1 } -function initializePromise(promise, resolver) { - try { - resolver(function resolvePromise(value) { - resolve(promise, value); - }, function rejectPromise(reason) { - reject(promise, reason); - }); - } catch (e) { - reject(promise, e); - } +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 } -var id = 0; -function nextId() { - return id++; +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) } -function makePromise(promise) { - promise[PROMISE_ID] = id++; - promise._state = undefined; - promise._result = undefined; - promise._subscribers = []; +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) } -function validationError() { - return new Error('Array Methods must be provided an Array'); +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) return i + buf[offset + i] = parsed + } + return i } -var Enumerator = function () { - function Enumerator(Constructor, input) { - this._instanceConstructor = Constructor; - this.promise = new Constructor(noop); +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} - if (!this.promise[PROMISE_ID]) { - makePromise(this.promise); - } +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} - if (isArray(input)) { - this.length = input.length; - this._remaining = input.length; +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} - this._result = new Array(this.length); +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} - if (this.length === 0) { - fulfill(this.promise, this._result); - } else { - this.length = this.length || 0; - this._enumerate(input); - if (this._remaining === 0) { - fulfill(this.promise, this._result); - } - } +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' } else { - reject(this.promise, validationError()); + encoding = length + length = undefined } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) } - Enumerator.prototype._enumerate = function _enumerate(input) { - for (var i = 0; this._state === PENDING && i < input.length; i++) { - this._eachEntry(input[i], i); - } - }; + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining - Enumerator.prototype._eachEntry = function _eachEntry(entry, i) { - var c = this._instanceConstructor; - var resolve$$1 = c.resolve; + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + if (!encoding) encoding = 'utf8' - if (resolve$$1 === resolve$1) { - var _then = getThen(entry); + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) - if (_then === then && entry._state !== PENDING) { - this._settledAt(entry._state, i, entry._result); - } else if (typeof _then !== 'function') { - this._remaining--; - this._result[i] = entry; - } else if (c === Promise$1) { - var promise = new c(noop); - handleMaybeThenable(promise, entry, _then); - this._willSettleAt(promise, i); - } else { - this._willSettleAt(new c(function (resolve$$1) { - return resolve$$1(entry); - }), i); - } - } else { - this._willSettleAt(resolve$$1(entry), i); - } - }; + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) - Enumerator.prototype._settledAt = function _settledAt(state, i, value) { - var promise = this.promise; + case 'ascii': + return asciiWrite(this, string, offset, length) + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) - if (promise._state === PENDING) { - this._remaining--; + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) - if (state === REJECTED) { - reject(promise, value); - } else { - this._result[i] = value; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } } } - if (this._remaining === 0) { - fulfill(promise, this._result); + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF } - }; - Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) { - var enumerator = this; + res.push(codePoint) + i += bytesPerSequence + } - subscribe(promise, undefined, function (value) { - return enumerator._settledAt(FULFILLED, i, value); - }, function (reason) { - return enumerator._settledAt(REJECTED, i, reason); - }); - }; + return decodeCodePointsArray(res) +} - return Enumerator; -}(); +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 -/** - `Promise.all` accepts an array of promises, and returns a new promise which - is fulfilled with an array of fulfillment values for the passed promises, or - rejected with the reason of the first passed promise to be rejected. It casts all - elements of the passed iterable to promises as it runs this algorithm. +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } - Example: + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} - ```javascript - let promise1 = resolve(1); - let promise2 = resolve(2); - let promise3 = resolve(3); - let promises = [ promise1, promise2, promise3 ]; +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) - Promise.all(promises).then(function(array){ - // The array here would be [ 1, 2, 3 ]; - }); - ``` + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} - If any of the `promises` given to `all` are rejected, the first promise - that is rejected will be given as an argument to the returned promises's - rejection handler. For example: +function latin1Slice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) - Example: + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]) + } + return ret +} - ```javascript - let promise1 = resolve(1); - let promise2 = reject(new Error("2")); - let promise3 = reject(new Error("3")); - let promises = [ promise1, promise2, promise3 ]; +function hexSlice (buf, start, end) { + var len = buf.length - Promise.all(promises).then(function(array){ - // Code here never runs because there are rejected promises! - }, function(error) { - // error.message === "2" - }); - ``` + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len - @method all - @static - @param {Array} entries array of promises - @param {String} label optional string for labeling the promise. - Useful for tooling. - @return {Promise} promise that is fulfilled when all `promises` have been - fulfilled, or rejected if any of them become rejected. - @static -*/ -function all(entries) { - return new Enumerator(this, entries).promise; + var out = '' + for (var i = start; i < end; ++i) { + out += toHex(buf[i]) + } + return out } -/** - `Promise.race` returns a new promise which is settled in the same way as the - first passed promise to settle. +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} - Example: +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end - ```javascript - let promise1 = new Promise(function(resolve, reject){ - setTimeout(function(){ - resolve('promise 1'); - }, 200); - }); + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } - let promise2 = new Promise(function(resolve, reject){ - setTimeout(function(){ - resolve('promise 2'); - }, 100); - }); + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } - Promise.race([promise1, promise2]).then(function(result){ - // result === 'promise 2' because it was resolved before promise1 - // was resolved. - }); - ``` + if (end < start) end = start - `Promise.race` is deterministic in that only the state of the first - settled promise matters. For example, even if other promises given to the - `promises` array argument are resolved, but the first settled promise has - become rejected before the other promises became fulfilled, the returned - promise will become rejected: + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start] + } + } - ```javascript - let promise1 = new Promise(function(resolve, reject){ - setTimeout(function(){ - resolve('promise 1'); - }, 200); - }); + return newBuf +} - let promise2 = new Promise(function(resolve, reject){ - setTimeout(function(){ - reject(new Error('promise 2')); - }, 100); - }); +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} - Promise.race([promise1, promise2]).then(function(result){ - // Code here never runs - }, function(reason){ - // reason.message === 'promise 2' because promise 2 became rejected before - // promise 1 became fulfilled - }); - ``` +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) - An example real-world use case is implementing timeouts: + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } - ```javascript - Promise.race([ajax('foo.json'), timeout(5000)]) - ``` + return val +} - @method race - @static - @param {Array} promises array of promises to observe - Useful for tooling. - @return {Promise} a promise which settles in the same way as the first passed - promise to settle. -*/ -function race(entries) { - /*jshint validthis:true */ - var Constructor = this; +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } - if (!isArray(entries)) { - return new Constructor(function (_, reject) { - return reject(new TypeError('You must pass an array to race.')); - }); - } else { - return new Constructor(function (resolve, reject) { - var length = entries.length; - for (var i = 0; i < length; i++) { - Constructor.resolve(entries[i]).then(resolve, reject); - } - }); + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul } + + return val } -/** - `Promise.reject` returns a promise rejected with the passed `reason`. - It is shorthand for the following: +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} - ```javascript - let promise = new Promise(function(resolve, reject){ - reject(new Error('WHOOPS')); - }); +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} - promise.then(function(value){ - // Code here doesn't run because the promise is rejected! - }, function(reason){ - // reason.message === 'WHOOPS' - }); - ``` +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} - Instead of writing the above, your code now simply becomes the following: +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) - ```javascript - let promise = Promise.reject(new Error('WHOOPS')); + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} - promise.then(function(value){ - // Code here doesn't run because the promise is rejected! - }, function(reason){ - // reason.message === 'WHOOPS' - }); - ``` +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) - @method reject - @static - @param {Any} reason value that the returned promise will be rejected with. - Useful for tooling. - @return {Promise} a promise rejected with the given `reason`. -*/ -function reject$1(reason) { - /*jshint validthis:true */ - var Constructor = this; - var promise = new Constructor(noop); - reject(promise, reason); - return promise; + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) } -function needsResolver() { - throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val } -function needsNew() { - throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val } -/** - Promise objects represent the eventual result of an asynchronous operation. The - primary way of interacting with a promise is through its `then` method, which - registers callbacks to receive either a promise's eventual value or the reason - why the promise cannot be fulfilled. +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} - Terminology - ----------- +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} - - `promise` is an object or function with a `then` method whose behavior conforms to this specification. - - `thenable` is an object or function that defines a `then` method. - - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). - - `exception` is a value that is thrown using the throw statement. - - `reason` is a value that indicates why a promise was rejected. - - `settled` the final resting state of a promise, fulfilled or rejected. +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} - A promise can be in one of three states: pending, fulfilled, or rejected. +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) - Promises that are fulfilled have a fulfillment value and are in the fulfilled - state. Promises that are rejected have a rejection reason and are in the - rejected state. A fulfillment value is never a thenable. + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} - Promises can also be said to *resolve* a value. If this value is also a - promise, then the original promise's settled state will match the value's - settled state. So a promise that *resolves* a promise that rejects will - itself reject, and a promise that *resolves* a promise that fulfills will - itself fulfill. +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} - Basic Usage: - ------------ +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} - ```js - let promise = new Promise(function(resolve, reject) { - // on success - resolve(value); +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} - // on failure - reject(reason); - }); +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} - promise.then(function(value) { - // on fulfillment - }, function(reason) { - // on rejection - }); - ``` +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} - Advanced Usage: - --------------- +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') +} - Promises shine when abstracting away asynchronous interactions such as - `XMLHttpRequest`s. +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } - ```js - function getJSON(url) { - return new Promise(function(resolve, reject){ - let xhr = new XMLHttpRequest(); + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } - xhr.open('GET', url); - xhr.onreadystatechange = handler; - xhr.responseType = 'json'; - xhr.setRequestHeader('Accept', 'application/json'); - xhr.send(); + return offset + byteLength +} - function handler() { - if (this.readyState === this.DONE) { - if (this.status === 200) { - resolve(this.response); - } else { - reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); - } - } - }; - }); +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) } - getJSON('/posts.json').then(function(json) { - // on fulfillment - }, function(reason) { - // on rejection - }); - ``` + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } - Unlike callbacks, promises are great composable primitives. + return offset + byteLength +} - ```js - Promise.all([ - getJSON('/posts'), - getJSON('/comments') - ]).then(function(values){ - values[0] // => postsJSON - values[1] // => commentsJSON +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} - return values; - }); - ``` +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} - @class Promise - @param {Function} resolver - Useful for tooling. - @constructor -*/ +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} -var Promise$1 = function () { - function Promise(resolver) { - this[PROMISE_ID] = nextId(); - this._result = this._state = undefined; - this._subscribers = []; +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} - if (noop !== resolver) { - typeof resolver !== 'function' && needsResolver(); - this instanceof Promise ? initializePromise(this, resolver) : needsNew(); +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } - /** - The primary way of interacting with a promise is through its `then` method, - which registers callbacks to receive either a promise's eventual value or the - reason why the promise cannot be fulfilled. - ```js - findUser().then(function(user){ - // user is available - }, function(reason){ - // user is unavailable, and you are given the reason why - }); - ``` - Chaining - -------- - The return value of `then` is itself a promise. This second, 'downstream' - promise is resolved with the return value of the first promise's fulfillment - or rejection handler, or rejected if the handler throws an exception. - ```js - findUser().then(function (user) { - return user.name; - }, function (reason) { - return 'default name'; - }).then(function (userName) { - // If `findUser` fulfilled, `userName` will be the user's name, otherwise it - // will be `'default name'` - }); - findUser().then(function (user) { - throw new Error('Found user, but still unhappy'); - }, function (reason) { - throw new Error('`findUser` rejected and we're unhappy'); - }).then(function (value) { - // never reached - }, function (reason) { - // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. - // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. - }); - ``` - If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. - ```js - findUser().then(function (user) { - throw new PedagogicalException('Upstream error'); - }).then(function (value) { - // never reached - }).then(function (value) { - // never reached - }, function (reason) { - // The `PedgagocialException` is propagated all the way down to here - }); - ``` - Assimilation - ------------ - Sometimes the value you want to propagate to a downstream promise can only be - retrieved asynchronously. This can be achieved by returning a promise in the - fulfillment or rejection handler. The downstream promise will then be pending - until the returned promise is settled. This is called *assimilation*. - ```js - findUser().then(function (user) { - return findCommentsByAuthor(user); - }).then(function (comments) { - // The user's comments are now available - }); - ``` - If the assimliated promise rejects, then the downstream promise will also reject. - ```js - findUser().then(function (user) { - return findCommentsByAuthor(user); - }).then(function (comments) { - // If `findCommentsByAuthor` fulfills, we'll have the value here - }, function (reason) { - // If `findCommentsByAuthor` rejects, we'll have the reason here - }); - ``` - Simple Example - -------------- - Synchronous Example - ```javascript - let result; - try { - result = findResult(); - // success - } catch(reason) { - // failure + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) } - ``` - Errback Example - ```js - findResult(function(result, err){ - if (err) { - // failure + + var i = byteLength - 1 + var mul = 1 + var sub = 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start] + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) + } + + return len +} + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if (code < 256) { + val = code + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255 + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 + + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val + } + } else { + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) + var len = bytes.length + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len] + } + } + + return this +} + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) } else { - // success + throw new Error('Invalid code point') } - }); - ``` - Promise Example; - ```javascript - findResult().then(function(result){ - // success - }, function(reason){ - // failure - }); - ``` - Advanced Example - -------------- - Synchronous Example - ```javascript - let author, books; - try { - author = findAuthor(); - books = findBooksByAuthor(author); - // success - } catch(reason) { - // failure } - ``` - Errback Example - ```js - function foundBooks(books) { - } - function failure(reason) { - } - findAuthor(function(author, err){ - if (err) { - failure(err); - // failure + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"base64-js":8,"ieee754":11,"isarray":12}],10:[function(require,module,exports){ +(function (process,global){ +/*! + * @overview es6-promise - a tiny implementation of Promises/A+. + * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) + * @license Licensed under MIT license + * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE + * @version v4.2.4+314e4831 + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.ES6Promise = factory()); +}(this, (function () { 'use strict'; + +function objectOrFunction(x) { + var type = typeof x; + return x !== null && (type === 'object' || type === 'function'); +} + +function isFunction(x) { + return typeof x === 'function'; +} + + + +var _isArray = void 0; +if (Array.isArray) { + _isArray = Array.isArray; +} else { + _isArray = function (x) { + return Object.prototype.toString.call(x) === '[object Array]'; + }; +} + +var isArray = _isArray; + +var len = 0; +var vertxNext = void 0; +var customSchedulerFn = void 0; + +var asap = function asap(callback, arg) { + queue[len] = callback; + queue[len + 1] = arg; + len += 2; + if (len === 2) { + // If len is 2, that means that we need to schedule an async flush. + // If additional callbacks are queued before the queue is flushed, they + // will be processed by this flush that we are scheduling. + if (customSchedulerFn) { + customSchedulerFn(flush); } else { - try { - findBoooksByAuthor(author, function(books, err) { - if (err) { - failure(err); - } else { - try { - foundBooks(books); - } catch(reason) { - failure(reason); - } - } - }); - } catch(error) { - failure(err); - } - // success + scheduleFlush(); } + } +}; + +function setScheduler(scheduleFn) { + customSchedulerFn = scheduleFn; +} + +function setAsap(asapFn) { + asap = asapFn; +} + +var browserWindow = typeof window !== 'undefined' ? window : undefined; +var browserGlobal = browserWindow || {}; +var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; +var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; + +// test for web worker but not in IE10 +var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; + +// node +function useNextTick() { + // node version 0.10.x displays a deprecation warning when nextTick is used recursively + // see https://github.com/cujojs/when/issues/410 for details + return function () { + return process.nextTick(flush); + }; +} + +// vertx +function useVertxTimer() { + if (typeof vertxNext !== 'undefined') { + return function () { + vertxNext(flush); + }; + } + + return useSetTimeout(); +} + +function useMutationObserver() { + var iterations = 0; + var observer = new BrowserMutationObserver(flush); + var node = document.createTextNode(''); + observer.observe(node, { characterData: true }); + + return function () { + node.data = iterations = ++iterations % 2; + }; +} + +// web worker +function useMessageChannel() { + var channel = new MessageChannel(); + channel.port1.onmessage = flush; + return function () { + return channel.port2.postMessage(0); + }; +} + +function useSetTimeout() { + // Store setTimeout reference so es6-promise will be unaffected by + // other code modifying setTimeout (like sinon.useFakeTimers()) + var globalSetTimeout = setTimeout; + return function () { + return globalSetTimeout(flush, 1); + }; +} + +var queue = new Array(1000); +function flush() { + for (var i = 0; i < len; i += 2) { + var callback = queue[i]; + var arg = queue[i + 1]; + + callback(arg); + + queue[i] = undefined; + queue[i + 1] = undefined; + } + + len = 0; +} + +function attemptVertx() { + try { + var vertx = Function('return this')().require('vertx'); + vertxNext = vertx.runOnLoop || vertx.runOnContext; + return useVertxTimer(); + } catch (e) { + return useSetTimeout(); + } +} + +var scheduleFlush = void 0; +// Decide what async method to use to triggering processing of queued callbacks: +if (isNode) { + scheduleFlush = useNextTick(); +} else if (BrowserMutationObserver) { + scheduleFlush = useMutationObserver(); +} else if (isWorker) { + scheduleFlush = useMessageChannel(); +} else if (browserWindow === undefined && typeof require === 'function') { + scheduleFlush = attemptVertx(); +} else { + scheduleFlush = useSetTimeout(); +} + +function then(onFulfillment, onRejection) { + var parent = this; + + var child = new this.constructor(noop); + + if (child[PROMISE_ID] === undefined) { + makePromise(child); + } + + var _state = parent._state; + + + if (_state) { + var callback = arguments[_state - 1]; + asap(function () { + return invokeCallback(_state, child, callback, parent._result); + }); + } else { + subscribe(parent, child, onFulfillment, onRejection); + } + + return child; +} + +/** + `Promise.resolve` returns a promise that will become resolved with the + passed `value`. It is shorthand for the following: + + ```javascript + let promise = new Promise(function(resolve, reject){ + resolve(1); + }); + + promise.then(function(value){ + // value === 1 }); ``` - Promise Example; - ```javascript - findAuthor(). - then(findBooksByAuthor). - then(function(books){ - // found books - }).catch(function(reason){ - // something went wrong + + Instead of writing the above, your code now simply becomes the following: + + ```javascript + let promise = Promise.resolve(1); + + promise.then(function(value){ + // value === 1 }); ``` - @method then - @param {Function} onFulfilled - @param {Function} onRejected + + @method resolve + @static + @param {Any} value value that the returned promise will be resolved with Useful for tooling. - @return {Promise} - */ + @return {Promise} a promise that will become fulfilled with the given + `value` +*/ +function resolve$1(object) { + /*jshint validthis:true */ + var Constructor = this; + + if (object && typeof object === 'object' && object.constructor === Constructor) { + return object; + } + + var promise = new Constructor(noop); + resolve(promise, object); + return promise; +} + +var PROMISE_ID = Math.random().toString(36).substring(2); + +function noop() {} + +var PENDING = void 0; +var FULFILLED = 1; +var REJECTED = 2; + +var TRY_CATCH_ERROR = { error: null }; + +function selfFulfillment() { + return new TypeError("You cannot resolve a promise with itself"); +} + +function cannotReturnOwn() { + return new TypeError('A promises callback cannot return that same promise.'); +} - /** - `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same - as the catch block of a try/catch statement. - ```js - function findAuthor(){ - throw new Error('couldn't find that author'); +function getThen(promise) { + try { + return promise.then; + } catch (error) { + TRY_CATCH_ERROR.error = error; + return TRY_CATCH_ERROR; } - // synchronous +} + +function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) { try { - findAuthor(); - } catch(reason) { - // something went wrong + then$$1.call(value, fulfillmentHandler, rejectionHandler); + } catch (e) { + return e; } - // async with promises - findAuthor().catch(function(reason){ - // something went wrong - }); - ``` - @method catch - @param {Function} onRejection - Useful for tooling. - @return {Promise} - */ +} +function handleForeignThenable(promise, thenable, then$$1) { + asap(function (promise) { + var sealed = false; + var error = tryThen(then$$1, thenable, function (value) { + if (sealed) { + return; + } + sealed = true; + if (thenable !== value) { + resolve(promise, value); + } else { + fulfill(promise, value); + } + }, function (reason) { + if (sealed) { + return; + } + sealed = true; - Promise.prototype.catch = function _catch(onRejection) { - return this.then(null, onRejection); - }; + reject(promise, reason); + }, 'Settle: ' + (promise._label || ' unknown promise')); - /** - `finally` will be invoked regardless of the promise's fate just as native - try/catch/finally behaves - - Synchronous example: - - ```js - findAuthor() { - if (Math.random() > 0.5) { - throw new Error(); - } - return new Author(); - } - - try { - return findAuthor(); // succeed or fail - } catch(error) { - return findOtherAuther(); - } finally { - // always runs - // doesn't affect the return value + if (!sealed && error) { + sealed = true; + reject(promise, error); } - ``` - - Asynchronous example: - - ```js - findAuthor().catch(function(reason){ - return findOtherAuther(); - }).finally(function(){ - // author was either found, or not + }, promise); +} + +function handleOwnThenable(promise, thenable) { + if (thenable._state === FULFILLED) { + fulfill(promise, thenable._result); + } else if (thenable._state === REJECTED) { + reject(promise, thenable._result); + } else { + subscribe(thenable, undefined, function (value) { + return resolve(promise, value); + }, function (reason) { + return reject(promise, reason); }); - ``` - - @method finally - @param {Function} callback - @return {Promise} - */ + } +} + +function handleMaybeThenable(promise, maybeThenable, then$$1) { + if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) { + handleOwnThenable(promise, maybeThenable); + } else { + if (then$$1 === TRY_CATCH_ERROR) { + reject(promise, TRY_CATCH_ERROR.error); + TRY_CATCH_ERROR.error = null; + } else if (then$$1 === undefined) { + fulfill(promise, maybeThenable); + } else if (isFunction(then$$1)) { + handleForeignThenable(promise, maybeThenable, then$$1); + } else { + fulfill(promise, maybeThenable); + } + } +} +function resolve(promise, value) { + if (promise === value) { + reject(promise, selfFulfillment()); + } else if (objectOrFunction(value)) { + handleMaybeThenable(promise, value, getThen(value)); + } else { + fulfill(promise, value); + } +} - Promise.prototype.finally = function _finally(callback) { - var promise = this; - var constructor = promise.constructor; +function publishRejection(promise) { + if (promise._onerror) { + promise._onerror(promise._result); + } - return promise.then(function (value) { - return constructor.resolve(callback()).then(function () { - return value; - }); - }, function (reason) { - return constructor.resolve(callback()).then(function () { - throw reason; - }); - }); - }; + publish(promise); +} - return Promise; -}(); +function fulfill(promise, value) { + if (promise._state !== PENDING) { + return; + } -Promise$1.prototype.then = then; -Promise$1.all = all; -Promise$1.race = race; -Promise$1.resolve = resolve$1; -Promise$1.reject = reject$1; -Promise$1._setScheduler = setScheduler; -Promise$1._setAsap = setAsap; -Promise$1._asap = asap; + promise._result = value; + promise._state = FULFILLED; -/*global self*/ -function polyfill() { - var local = void 0; + if (promise._subscribers.length !== 0) { + asap(publish, promise); + } +} - if (typeof global !== 'undefined') { - local = global; - } else if (typeof self !== 'undefined') { - local = self; - } else { - try { - local = Function('return this')(); - } catch (e) { - throw new Error('polyfill failed because global object is unavailable in this environment'); +function reject(promise, reason) { + if (promise._state !== PENDING) { + return; + } + promise._state = REJECTED; + promise._result = reason; + + asap(publishRejection, promise); +} + +function subscribe(parent, child, onFulfillment, onRejection) { + var _subscribers = parent._subscribers; + var length = _subscribers.length; + + + parent._onerror = null; + + _subscribers[length] = child; + _subscribers[length + FULFILLED] = onFulfillment; + _subscribers[length + REJECTED] = onRejection; + + if (length === 0 && parent._state) { + asap(publish, parent); + } +} + +function publish(promise) { + var subscribers = promise._subscribers; + var settled = promise._state; + + if (subscribers.length === 0) { + return; + } + + var child = void 0, + callback = void 0, + detail = promise._result; + + for (var i = 0; i < subscribers.length; i += 3) { + child = subscribers[i]; + callback = subscribers[i + settled]; + + if (child) { + invokeCallback(settled, child, callback, detail); + } else { + callback(detail); } } - var P = local.Promise; + promise._subscribers.length = 0; +} + +function tryCatch(callback, detail) { + try { + return callback(detail); + } catch (e) { + TRY_CATCH_ERROR.error = e; + return TRY_CATCH_ERROR; + } +} + +function invokeCallback(settled, promise, callback, detail) { + var hasCallback = isFunction(callback), + value = void 0, + error = void 0, + succeeded = void 0, + failed = void 0; + + if (hasCallback) { + value = tryCatch(callback, detail); - if (P) { - var promiseToString = null; - try { - promiseToString = Object.prototype.toString.call(P.resolve()); - } catch (e) { - // silently ignored + if (value === TRY_CATCH_ERROR) { + failed = true; + error = value.error; + value.error = null; + } else { + succeeded = true; } - if (promiseToString === '[object Promise]' && !P.cast) { + if (promise === value) { + reject(promise, cannotReturnOwn()); return; } + } else { + value = detail; + succeeded = true; } - local.Promise = Promise$1; + if (promise._state !== PENDING) { + // noop + } else if (hasCallback && succeeded) { + resolve(promise, value); + } else if (failed) { + reject(promise, error); + } else if (settled === FULFILLED) { + fulfill(promise, value); + } else if (settled === REJECTED) { + reject(promise, value); + } } -// Strange compat.. -Promise$1.polyfill = polyfill; -Promise$1.Promise = Promise$1; - -return Promise$1; - -}))); +function initializePromise(promise, resolver) { + try { + resolver(function resolvePromise(value) { + resolve(promise, value); + }, function rejectPromise(reason) { + reject(promise, reason); + }); + } catch (e) { + reject(promise, e); + } +} +var id = 0; +function nextId() { + return id++; +} +function makePromise(promise) { + promise[PROMISE_ID] = id++; + promise._state = undefined; + promise._result = undefined; + promise._subscribers = []; +} +function validationError() { + return new Error('Array Methods must be provided an Array'); +} +var Enumerator = function () { + function Enumerator(Constructor, input) { + this._instanceConstructor = Constructor; + this.promise = new Constructor(noop); -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"_process":8}],8:[function(require,module,exports){ -// shim for using process in browser -var process = module.exports = {}; + if (!this.promise[PROMISE_ID]) { + makePromise(this.promise); + } -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. + if (isArray(input)) { + this.length = input.length; + this._remaining = input.length; -var cachedSetTimeout; -var cachedClearTimeout; + this._result = new Array(this.length); -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); + if (this.length === 0) { + fulfill(this.promise, this._result); + } else { + this.length = this.length || 0; + this._enumerate(input); + if (this._remaining === 0) { + fulfill(this.promise, this._result); } + } + } else { + reject(this.promise, validationError()); } + } - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } + Enumerator.prototype._enumerate = function _enumerate(input) { + for (var i = 0; this._state === PENDING && i < input.length; i++) { + this._eachEntry(input[i], i); } + }; + Enumerator.prototype._eachEntry = function _eachEntry(entry, i) { + var c = this._instanceConstructor; + var resolve$$1 = c.resolve; -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; + if (resolve$$1 === resolve$1) { + var _then = getThen(entry); -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); + if (_then === then && entry._state !== PENDING) { + this._settledAt(entry._state, i, entry._result); + } else if (typeof _then !== 'function') { + this._remaining--; + this._result[i] = entry; + } else if (c === Promise$1) { + var promise = new c(noop); + handleMaybeThenable(promise, entry, _then); + this._willSettleAt(promise, i); + } else { + this._willSettleAt(new c(function (resolve$$1) { + return resolve$$1(entry); + }), i); + } } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); + this._willSettleAt(resolve$$1(entry), i); } -} + }; -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; + Enumerator.prototype._settledAt = function _settledAt(state, i, value) { + var promise = this.promise; - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } + if (promise._state === PENDING) { + this._remaining--; + + if (state === REJECTED) { + reject(promise, value); + } else { + this._result[i] = value; + } } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); + + if (this._remaining === 0) { + fulfill(promise, this._result); } -}; + }; + + Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) { + var enumerator = this; + + subscribe(promise, undefined, function (value) { + return enumerator._settledAt(FULFILLED, i, value); + }, function (reason) { + return enumerator._settledAt(REJECTED, i, reason); + }); + }; -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; + return Enumerator; +}(); -function noop() {} +/** + `Promise.all` accepts an array of promises, and returns a new promise which + is fulfilled with an array of fulfillment values for the passed promises, or + rejected with the reason of the first passed promise to be rejected. It casts all + elements of the passed iterable to promises as it runs this algorithm. -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; + Example: -process.listeners = function (name) { return [] } + ```javascript + let promise1 = resolve(1); + let promise2 = resolve(2); + let promise3 = resolve(3); + let promises = [ promise1, promise2, promise3 ]; -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; + Promise.all(promises).then(function(array){ + // The array here would be [ 1, 2, 3 ]; + }); + ``` -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; + If any of the `promises` given to `all` are rejected, the first promise + that is rejected will be given as an argument to the returned promises's + rejection handler. For example: -},{}],9:[function(require,module,exports){ -function Agent() { - this._defaults = []; -} + Example: -["use", "on", "once", "set", "query", "type", "accept", "auth", "withCredentials", "sortQuery", "retry", "ok", "redirects", - "timeout", "buffer", "serialize", "parse", "ca", "key", "pfx", "cert"].forEach(function(fn) { - /** Default setting for all requests from this agent */ - Agent.prototype[fn] = function(/*varargs*/) { - this._defaults.push({fn:fn, arguments:arguments}); - return this; - } -}); + ```javascript + let promise1 = resolve(1); + let promise2 = reject(new Error("2")); + let promise3 = reject(new Error("3")); + let promises = [ promise1, promise2, promise3 ]; -Agent.prototype._setDefaults = function(req) { - this._defaults.forEach(function(def) { - req[def.fn].apply(req, def.arguments); - }); -}; + Promise.all(promises).then(function(array){ + // Code here never runs because there are rejected promises! + }, function(error) { + // error.message === "2" + }); + ``` -module.exports = Agent; + @method all + @static + @param {Array} entries array of promises + @param {String} label optional string for labeling the promise. + Useful for tooling. + @return {Promise} promise that is fulfilled when all `promises` have been + fulfilled, or rejected if any of them become rejected. + @static +*/ +function all(entries) { + return new Enumerator(this, entries).promise; +} -},{}],10:[function(require,module,exports){ /** - * Root reference for iframes. - */ + `Promise.race` returns a new promise which is settled in the same way as the + first passed promise to settle. -var root; -if (typeof window !== 'undefined') { // Browser window - root = window; -} else if (typeof self !== 'undefined') { // Web Worker - root = self; -} else { // Other environments - console.warn("Using browser-only version of superagent in non-browser environment"); - root = this; -} + Example: -var Emitter = require('component-emitter'); -var RequestBase = require('./request-base'); -var isObject = require('./is-object'); -var ResponseBase = require('./response-base'); -var Agent = require('./agent-base'); + ```javascript + let promise1 = new Promise(function(resolve, reject){ + setTimeout(function(){ + resolve('promise 1'); + }, 200); + }); -/** - * Noop. - */ + let promise2 = new Promise(function(resolve, reject){ + setTimeout(function(){ + resolve('promise 2'); + }, 100); + }); -function noop(){}; + Promise.race([promise1, promise2]).then(function(result){ + // result === 'promise 2' because it was resolved before promise1 + // was resolved. + }); + ``` -/** - * Expose `request`. - */ + `Promise.race` is deterministic in that only the state of the first + settled promise matters. For example, even if other promises given to the + `promises` array argument are resolved, but the first settled promise has + become rejected before the other promises became fulfilled, the returned + promise will become rejected: -var request = exports = module.exports = function(method, url) { - // callback - if ('function' == typeof url) { - return new exports.Request('GET', method).end(url); - } + ```javascript + let promise1 = new Promise(function(resolve, reject){ + setTimeout(function(){ + resolve('promise 1'); + }, 200); + }); - // url first - if (1 == arguments.length) { - return new exports.Request('GET', method); - } + let promise2 = new Promise(function(resolve, reject){ + setTimeout(function(){ + reject(new Error('promise 2')); + }, 100); + }); - return new exports.Request(method, url); -} + Promise.race([promise1, promise2]).then(function(result){ + // Code here never runs + }, function(reason){ + // reason.message === 'promise 2' because promise 2 became rejected before + // promise 1 became fulfilled + }); + ``` -exports.Request = Request; + An example real-world use case is implementing timeouts: -/** - * Determine XHR. - */ + ```javascript + Promise.race([ajax('foo.json'), timeout(5000)]) + ``` -request.getXHR = function () { - if (root.XMLHttpRequest - && (!root.location || 'file:' != root.location.protocol - || !root.ActiveXObject)) { - return new XMLHttpRequest; + @method race + @static + @param {Array} promises array of promises to observe + Useful for tooling. + @return {Promise} a promise which settles in the same way as the first passed + promise to settle. +*/ +function race(entries) { + /*jshint validthis:true */ + var Constructor = this; + + if (!isArray(entries)) { + return new Constructor(function (_, reject) { + return reject(new TypeError('You must pass an array to race.')); + }); } else { - try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + return new Constructor(function (resolve, reject) { + var length = entries.length; + for (var i = 0; i < length; i++) { + Constructor.resolve(entries[i]).then(resolve, reject); + } + }); } - throw Error("Browser-only version of superagent could not find XHR"); -}; +} /** - * Removes leading and trailing whitespace, added to support IE. - * - * @param {String} s - * @return {String} - * @api private - */ + `Promise.reject` returns a promise rejected with the passed `reason`. + It is shorthand for the following: -var trim = ''.trim - ? function(s) { return s.trim(); } - : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + ```javascript + let promise = new Promise(function(resolve, reject){ + reject(new Error('WHOOPS')); + }); -/** - * Serialize the given `obj`. - * - * @param {Object} obj - * @return {String} - * @api private - */ + promise.then(function(value){ + // Code here doesn't run because the promise is rejected! + }, function(reason){ + // reason.message === 'WHOOPS' + }); + ``` -function serialize(obj) { - if (!isObject(obj)) return obj; - var pairs = []; - for (var key in obj) { - pushEncodedKeyValuePair(pairs, key, obj[key]); - } - return pairs.join('&'); + Instead of writing the above, your code now simply becomes the following: + + ```javascript + let promise = Promise.reject(new Error('WHOOPS')); + + promise.then(function(value){ + // Code here doesn't run because the promise is rejected! + }, function(reason){ + // reason.message === 'WHOOPS' + }); + ``` + + @method reject + @static + @param {Any} reason value that the returned promise will be rejected with. + Useful for tooling. + @return {Promise} a promise rejected with the given `reason`. +*/ +function reject$1(reason) { + /*jshint validthis:true */ + var Constructor = this; + var promise = new Constructor(noop); + reject(promise, reason); + return promise; } -/** - * Helps 'serialize' with serializing arrays. - * Mutates the pairs array. - * - * @param {Array} pairs - * @param {String} key - * @param {Mixed} val - */ +function needsResolver() { + throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); +} -function pushEncodedKeyValuePair(pairs, key, val) { - if (val != null) { - if (Array.isArray(val)) { - val.forEach(function(v) { - pushEncodedKeyValuePair(pairs, key, v); - }); - } else if (isObject(val)) { - for(var subkey in val) { - pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); - } - } else { - pairs.push(encodeURIComponent(key) - + '=' + encodeURIComponent(val)); - } - } else if (val === null) { - pairs.push(encodeURIComponent(key)); - } +function needsNew() { + throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); } /** - * Expose serialization method. - */ + Promise objects represent the eventual result of an asynchronous operation. The + primary way of interacting with a promise is through its `then` method, which + registers callbacks to receive either a promise's eventual value or the reason + why the promise cannot be fulfilled. -request.serializeObject = serialize; + Terminology + ----------- -/** - * Parse the given x-www-form-urlencoded `str`. - * - * @param {String} str - * @return {Object} - * @api private - */ + - `promise` is an object or function with a `then` method whose behavior conforms to this specification. + - `thenable` is an object or function that defines a `then` method. + - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). + - `exception` is a value that is thrown using the throw statement. + - `reason` is a value that indicates why a promise was rejected. + - `settled` the final resting state of a promise, fulfilled or rejected. -function parseString(str) { - var obj = {}; - var pairs = str.split('&'); - var pair; - var pos; - - for (var i = 0, len = pairs.length; i < len; ++i) { - pair = pairs[i]; - pos = pair.indexOf('='); - if (pos == -1) { - obj[decodeURIComponent(pair)] = ''; - } else { - obj[decodeURIComponent(pair.slice(0, pos))] = - decodeURIComponent(pair.slice(pos + 1)); - } - } + A promise can be in one of three states: pending, fulfilled, or rejected. - return obj; -} + Promises that are fulfilled have a fulfillment value and are in the fulfilled + state. Promises that are rejected have a rejection reason and are in the + rejected state. A fulfillment value is never a thenable. -/** - * Expose parser. - */ + Promises can also be said to *resolve* a value. If this value is also a + promise, then the original promise's settled state will match the value's + settled state. So a promise that *resolves* a promise that rejects will + itself reject, and a promise that *resolves* a promise that fulfills will + itself fulfill. + + + Basic Usage: + ------------ -request.parseString = parseString; + ```js + let promise = new Promise(function(resolve, reject) { + // on success + resolve(value); -/** - * Default MIME type map. - * - * superagent.types.xml = 'application/xml'; - * - */ + // on failure + reject(reason); + }); -request.types = { - html: 'text/html', - json: 'application/json', - xml: 'text/xml', - urlencoded: 'application/x-www-form-urlencoded', - 'form': 'application/x-www-form-urlencoded', - 'form-data': 'application/x-www-form-urlencoded' -}; + promise.then(function(value) { + // on fulfillment + }, function(reason) { + // on rejection + }); + ``` -/** - * Default serialization map. - * - * superagent.serialize['application/xml'] = function(obj){ - * return 'generated xml here'; - * }; - * - */ + Advanced Usage: + --------------- -request.serialize = { - 'application/x-www-form-urlencoded': serialize, - 'application/json': JSON.stringify -}; + Promises shine when abstracting away asynchronous interactions such as + `XMLHttpRequest`s. -/** - * Default parsers. - * - * superagent.parse['application/xml'] = function(str){ - * return { object parsed from str }; - * }; - * - */ + ```js + function getJSON(url) { + return new Promise(function(resolve, reject){ + let xhr = new XMLHttpRequest(); -request.parse = { - 'application/x-www-form-urlencoded': parseString, - 'application/json': JSON.parse -}; + xhr.open('GET', url); + xhr.onreadystatechange = handler; + xhr.responseType = 'json'; + xhr.setRequestHeader('Accept', 'application/json'); + xhr.send(); -/** - * Parse the given header `str` into - * an object containing the mapped fields. - * - * @param {String} str - * @return {Object} - * @api private - */ + function handler() { + if (this.readyState === this.DONE) { + if (this.status === 200) { + resolve(this.response); + } else { + reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); + } + } + }; + }); + } -function parseHeader(str) { - var lines = str.split(/\r?\n/); - var fields = {}; - var index; - var line; - var field; - var val; + getJSON('/posts.json').then(function(json) { + // on fulfillment + }, function(reason) { + // on rejection + }); + ``` - for (var i = 0, len = lines.length; i < len; ++i) { - line = lines[i]; - index = line.indexOf(':'); - if (index === -1) { // could be empty line, just skip it - continue; - } - field = line.slice(0, index).toLowerCase(); - val = trim(line.slice(index + 1)); - fields[field] = val; - } + Unlike callbacks, promises are great composable primitives. - return fields; -} + ```js + Promise.all([ + getJSON('/posts'), + getJSON('/comments') + ]).then(function(values){ + values[0] // => postsJSON + values[1] // => commentsJSON -/** - * Check if `mime` is json or has +json structured syntax suffix. - * - * @param {String} mime - * @return {Boolean} - * @api private - */ + return values; + }); + ``` -function isJSON(mime) { - // should match /json or +json - // but not /json-seq - return /[\/+]json($|[^-\w])/.test(mime); -} + @class Promise + @param {Function} resolver + Useful for tooling. + @constructor +*/ -/** - * Initialize a new `Response` with the given `xhr`. - * - * - set flags (.ok, .error, etc) - * - parse header - * - * Examples: - * - * Aliasing `superagent` as `request` is nice: - * - * request = superagent; - * - * We can use the promise-like API, or pass callbacks: - * - * request.get('/').end(function(res){}); - * request.get('/', function(res){}); - * - * Sending data can be chained: - * - * request - * .post('/user') - * .send({ name: 'tj' }) - * .end(function(res){}); - * - * Or passed to `.send()`: - * - * request - * .post('/user') - * .send({ name: 'tj' }, function(res){}); - * - * Or passed to `.post()`: - * - * request - * .post('/user', { name: 'tj' }) - * .end(function(res){}); - * - * Or further reduced to a single call for simple cases: - * - * request - * .post('/user', { name: 'tj' }, function(res){}); - * - * @param {XMLHTTPRequest} xhr - * @param {Object} options - * @api private - */ +var Promise$1 = function () { + function Promise(resolver) { + this[PROMISE_ID] = nextId(); + this._result = this._state = undefined; + this._subscribers = []; -function Response(req) { - this.req = req; - this.xhr = this.req.xhr; - // responseText is accessible only if responseType is '' or 'text' and on older browsers - this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') - ? this.xhr.responseText - : null; - this.statusText = this.req.xhr.statusText; - var status = this.xhr.status; - // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request - if (status === 1223) { - status = 204; - } - this._setStatusProperties(status); - this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); - // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but - // getResponseHeader still works. so we get content-type even if getting - // other headers fails. - this.header['content-type'] = this.xhr.getResponseHeader('content-type'); - this._setHeaderProperties(this.header); - - if (null === this.text && req._responseType) { - this.body = this.xhr.response; - } else { - this.body = this.req.method != 'HEAD' - ? this._parseBody(this.text ? this.text : this.xhr.response) - : null; + if (noop !== resolver) { + typeof resolver !== 'function' && needsResolver(); + this instanceof Promise ? initializePromise(this, resolver) : needsNew(); + } } -} -ResponseBase(Response.prototype); - -/** - * Parse the given body `str`. - * - * Used for auto-parsing of bodies. Parsers - * are defined on the `superagent.parse` object. - * - * @param {String} str - * @return {Mixed} - * @api private - */ + /** + The primary way of interacting with a promise is through its `then` method, + which registers callbacks to receive either a promise's eventual value or the + reason why the promise cannot be fulfilled. + ```js + findUser().then(function(user){ + // user is available + }, function(reason){ + // user is unavailable, and you are given the reason why + }); + ``` + Chaining + -------- + The return value of `then` is itself a promise. This second, 'downstream' + promise is resolved with the return value of the first promise's fulfillment + or rejection handler, or rejected if the handler throws an exception. + ```js + findUser().then(function (user) { + return user.name; + }, function (reason) { + return 'default name'; + }).then(function (userName) { + // If `findUser` fulfilled, `userName` will be the user's name, otherwise it + // will be `'default name'` + }); + findUser().then(function (user) { + throw new Error('Found user, but still unhappy'); + }, function (reason) { + throw new Error('`findUser` rejected and we're unhappy'); + }).then(function (value) { + // never reached + }, function (reason) { + // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. + // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. + }); + ``` + If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. + ```js + findUser().then(function (user) { + throw new PedagogicalException('Upstream error'); + }).then(function (value) { + // never reached + }).then(function (value) { + // never reached + }, function (reason) { + // The `PedgagocialException` is propagated all the way down to here + }); + ``` + Assimilation + ------------ + Sometimes the value you want to propagate to a downstream promise can only be + retrieved asynchronously. This can be achieved by returning a promise in the + fulfillment or rejection handler. The downstream promise will then be pending + until the returned promise is settled. This is called *assimilation*. + ```js + findUser().then(function (user) { + return findCommentsByAuthor(user); + }).then(function (comments) { + // The user's comments are now available + }); + ``` + If the assimliated promise rejects, then the downstream promise will also reject. + ```js + findUser().then(function (user) { + return findCommentsByAuthor(user); + }).then(function (comments) { + // If `findCommentsByAuthor` fulfills, we'll have the value here + }, function (reason) { + // If `findCommentsByAuthor` rejects, we'll have the reason here + }); + ``` + Simple Example + -------------- + Synchronous Example + ```javascript + let result; + try { + result = findResult(); + // success + } catch(reason) { + // failure + } + ``` + Errback Example + ```js + findResult(function(result, err){ + if (err) { + // failure + } else { + // success + } + }); + ``` + Promise Example; + ```javascript + findResult().then(function(result){ + // success + }, function(reason){ + // failure + }); + ``` + Advanced Example + -------------- + Synchronous Example + ```javascript + let author, books; + try { + author = findAuthor(); + books = findBooksByAuthor(author); + // success + } catch(reason) { + // failure + } + ``` + Errback Example + ```js + function foundBooks(books) { + } + function failure(reason) { + } + findAuthor(function(author, err){ + if (err) { + failure(err); + // failure + } else { + try { + findBoooksByAuthor(author, function(books, err) { + if (err) { + failure(err); + } else { + try { + foundBooks(books); + } catch(reason) { + failure(reason); + } + } + }); + } catch(error) { + failure(err); + } + // success + } + }); + ``` + Promise Example; + ```javascript + findAuthor(). + then(findBooksByAuthor). + then(function(books){ + // found books + }).catch(function(reason){ + // something went wrong + }); + ``` + @method then + @param {Function} onFulfilled + @param {Function} onRejected + Useful for tooling. + @return {Promise} + */ -Response.prototype._parseBody = function(str) { - var parse = request.parse[this.type]; - if (this.req._parser) { - return this.req._parser(this, str); + /** + `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same + as the catch block of a try/catch statement. + ```js + function findAuthor(){ + throw new Error('couldn't find that author'); } - if (!parse && isJSON(this.type)) { - parse = request.parse['application/json']; + // synchronous + try { + findAuthor(); + } catch(reason) { + // something went wrong } - return parse && str && (str.length || str instanceof Object) - ? parse(str) - : null; -}; - -/** - * Return an `Error` representative of this response. - * - * @return {Error} - * @api public - */ - -Response.prototype.toError = function(){ - var req = this.req; - var method = req.method; - var url = req.url; - - var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; - var err = new Error(msg); - err.status = this.status; - err.method = method; - err.url = url; - - return err; -}; - -/** - * Expose `Response`. - */ - -request.Response = Response; + // async with promises + findAuthor().catch(function(reason){ + // something went wrong + }); + ``` + @method catch + @param {Function} onRejection + Useful for tooling. + @return {Promise} + */ -/** - * Initialize a new `Request` with the given `method` and `url`. - * - * @param {String} method - * @param {String} url - * @api public - */ -function Request(method, url) { - var self = this; - this._query = this._query || []; - this.method = method; - this.url = url; - this.header = {}; // preserves header name case - this._header = {}; // coerces header names to lowercase - this.on('end', function(){ - var err = null; - var res = null; + Promise.prototype.catch = function _catch(onRejection) { + return this.then(null, onRejection); + }; - try { - res = new Response(self); - } catch(e) { - err = new Error('Parser is unable to parse the response'); - err.parse = true; - err.original = e; - // issue #675: return the raw response if the response parsing fails - if (self.xhr) { - // ie9 doesn't have 'response' property - err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response; - // issue #876: return the http status code if the response parsing fails - err.status = self.xhr.status ? self.xhr.status : null; - err.statusCode = err.status; // backwards-compat only - } else { - err.rawResponse = null; - err.status = null; + /** + `finally` will be invoked regardless of the promise's fate just as native + try/catch/finally behaves + + Synchronous example: + + ```js + findAuthor() { + if (Math.random() > 0.5) { + throw new Error(); } - - return self.callback(err); + return new Author(); } - - self.emit('response', res); - - var new_err; + try { - if (!self._isResponseOK(res)) { - new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); - } - } catch(custom_err) { - new_err = custom_err; // ok() callback can throw - } - - // #1000 don't catch errors from the callback to avoid double calling it - if (new_err) { - new_err.original = err; - new_err.response = res; - new_err.status = res.status; - self.callback(new_err, res); - } else { - self.callback(null, res); + return findAuthor(); // succeed or fail + } catch(error) { + return findOtherAuther(); + } finally { + // always runs + // doesn't affect the return value } - }); -} - -/** - * Mixin `Emitter` and `RequestBase`. - */ - -Emitter(Request.prototype); -RequestBase(Request.prototype); - -/** - * Set Content-Type to `type`, mapping values from `request.types`. - * - * Examples: - * - * superagent.types.xml = 'application/xml'; - * - * request.post('/') - * .type('xml') - * .send(xmlstring) - * .end(callback); - * - * request.post('/') - * .type('application/xml') - * .send(xmlstring) - * .end(callback); - * - * @param {String} type - * @return {Request} for chaining - * @api public - */ - -Request.prototype.type = function(type){ - this.set('Content-Type', request.types[type] || type); - return this; -}; - -/** - * Set Accept to `type`, mapping values from `request.types`. - * - * Examples: - * - * superagent.types.json = 'application/json'; - * - * request.get('/agent') - * .accept('json') - * .end(callback); - * - * request.get('/agent') - * .accept('application/json') - * .end(callback); - * - * @param {String} accept - * @return {Request} for chaining - * @api public - */ - -Request.prototype.accept = function(type){ - this.set('Accept', request.types[type] || type); - return this; -}; + ``` + + Asynchronous example: + + ```js + findAuthor().catch(function(reason){ + return findOtherAuther(); + }).finally(function(){ + // author was either found, or not + }); + ``` + + @method finally + @param {Function} callback + @return {Promise} + */ -/** - * Set Authorization field value with `user` and `pass`. - * - * @param {String} user - * @param {String} [pass] optional in case of using 'bearer' as type - * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic') - * @return {Request} for chaining - * @api public - */ -Request.prototype.auth = function(user, pass, options){ - if (1 === arguments.length) pass = ''; - if (typeof pass === 'object' && pass !== null) { // pass is optional and can be replaced with options - options = pass; - pass = ''; - } - if (!options) { - options = { - type: 'function' === typeof btoa ? 'basic' : 'auto', - }; - } + Promise.prototype.finally = function _finally(callback) { + var promise = this; + var constructor = promise.constructor; - var encoder = function(string) { - if ('function' === typeof btoa) { - return btoa(string); - } - throw new Error('Cannot use basic auth, btoa is not a function'); + return promise.then(function (value) { + return constructor.resolve(callback()).then(function () { + return value; + }); + }, function (reason) { + return constructor.resolve(callback()).then(function () { + throw reason; + }); + }); }; - return this._auth(user, pass, options, encoder); -}; - -/** - * Add query-string `val`. - * - * Examples: - * - * request.get('/shoes') - * .query('size=10') - * .query({ color: 'blue' }) - * - * @param {Object|String} val - * @return {Request} for chaining - * @api public - */ - -Request.prototype.query = function(val){ - if ('string' != typeof val) val = serialize(val); - if (val) this._query.push(val); - return this; -}; - -/** - * Queue the given `file` as an attachment to the specified `field`, - * with optional `options` (or filename). - * - * ``` js - * request.post('/upload') - * .attach('content', new Blob(['hey!'], { type: "text/html"})) - * .end(callback); - * ``` - * - * @param {String} field - * @param {Blob|File} file - * @param {String|Object} options - * @return {Request} for chaining - * @api public - */ - -Request.prototype.attach = function(field, file, options){ - if (file) { - if (this._data) { - throw Error("superagent can't mix .send() and .attach()"); - } - - this._getFormData().append(field, file, options || file.name); - } - return this; -}; - -Request.prototype._getFormData = function(){ - if (!this._formData) { - this._formData = new root.FormData(); - } - return this._formData; -}; - -/** - * Invoke the callback with `err` and `res` - * and handle arity check. - * - * @param {Error} err - * @param {Response} res - * @api private - */ - -Request.prototype.callback = function(err, res){ - if (this._shouldRetry(err, res)) { - return this._retry(); - } - - var fn = this._callback; - this.clearTimeout(); - - if (err) { - if (this._maxRetries) err.retries = this._retries - 1; - this.emit('error', err); - } - - fn(err, res); -}; - -/** - * Invoke callback with x-domain error. - * - * @api private - */ - -Request.prototype.crossDomainError = function(){ - 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.'); - err.crossDomain = true; - - err.status = this.status; - err.method = this.method; - err.url = this.url; - - this.callback(err); -}; - -// This only warns, because the request is still likely to work -Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){ - console.warn("This is not supported in browser version of superagent"); - return this; -}; - -// This throws, because it can't send/receive data as expected -Request.prototype.pipe = Request.prototype.write = function(){ - throw Error("Streaming is not supported in browser version of superagent"); -}; - -/** - * Check if `obj` is a host object, - * we don't want to serialize these :) - * - * @param {Object} obj - * @return {Boolean} - * @api private - */ -Request.prototype._isHost = function _isHost(obj) { - // Native objects stringify to [object File], [object Blob], [object FormData], etc. - return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]'; -} - -/** - * Initiate request, invoking callback `fn(res)` - * with an instanceof `Response`. - * - * @param {Function} fn - * @return {Request} for chaining - * @api public - */ - -Request.prototype.end = function(fn){ - if (this._endCalled) { - console.warn("Warning: .end() was called twice. This is not supported in superagent"); - } - this._endCalled = true; - - // store callback - this._callback = fn || noop; - - // querystring - this._finalizeQueryString(); - - return this._end(); -}; - -Request.prototype._end = function() { - var self = this; - var xhr = (this.xhr = request.getXHR()); - var data = this._formData || this._data; - - this._setTimeouts(); - - // state change - xhr.onreadystatechange = function(){ - var readyState = xhr.readyState; - if (readyState >= 2 && self._responseTimeoutTimer) { - clearTimeout(self._responseTimeoutTimer); - } - if (4 != readyState) { - return; - } + return Promise; +}(); - // In IE9, reads to any property (e.g. status) off of an aborted XHR will - // result in the error "Could not complete the operation due to error c00c023f" - var status; - try { status = xhr.status } catch(e) { status = 0; } +Promise$1.prototype.then = then; +Promise$1.all = all; +Promise$1.race = race; +Promise$1.resolve = resolve$1; +Promise$1.reject = reject$1; +Promise$1._setScheduler = setScheduler; +Promise$1._setAsap = setAsap; +Promise$1._asap = asap; - if (!status) { - if (self.timedout || self._aborted) return; - return self.crossDomainError(); - } - self.emit('end'); - }; +/*global self*/ +function polyfill() { + var local = void 0; - // progress - var handleProgress = function(direction, e) { - if (e.total > 0) { - e.percent = e.loaded / e.total * 100; - } - e.direction = direction; - self.emit('progress', e); - }; - if (this.hasListeners('progress')) { + if (typeof global !== 'undefined') { + local = global; + } else if (typeof self !== 'undefined') { + local = self; + } else { try { - xhr.onprogress = handleProgress.bind(null, 'download'); - if (xhr.upload) { - xhr.upload.onprogress = handleProgress.bind(null, 'upload'); - } - } catch(e) { - // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. - // Reported here: - // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context - } - } - - // initiate request - try { - if (this.username && this.password) { - xhr.open(this.method, this.url, true, this.username, this.password); - } else { - xhr.open(this.method, this.url, true); - } - } catch (err) { - // see #1149 - return this.callback(err); - } - - // CORS - if (this._withCredentials) xhr.withCredentials = true; - - // body - if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { - // serialize stuff - var contentType = this._header['content-type']; - var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; - if (!serialize && isJSON(contentType)) { - serialize = request.serialize['application/json']; + local = Function('return this')(); + } catch (e) { + throw new Error('polyfill failed because global object is unavailable in this environment'); } - if (serialize) data = serialize(data); } - // set header fields - for (var field in this.header) { - if (null == this.header[field]) continue; - - if (this.header.hasOwnProperty(field)) - xhr.setRequestHeader(field, this.header[field]); - } - - if (this._responseType) { - xhr.responseType = this._responseType; - } - - // send stuff - this.emit('request', this); - - // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) - // We need null here if data is undefined - xhr.send(typeof data !== 'undefined' ? data : null); - return this; -}; + var P = local.Promise; -request.agent = function() { - return new Agent(); -}; + if (P) { + var promiseToString = null; + try { + promiseToString = Object.prototype.toString.call(P.resolve()); + } catch (e) { + // silently ignored + } -["GET", "POST", "OPTIONS", "PATCH", "PUT", "DELETE"].forEach(function(method) { - Agent.prototype[method.toLowerCase()] = function(url, fn) { - var req = new request.Request(method, url); - this._setDefaults(req); - if (fn) { - req.end(fn); + if (promiseToString === '[object Promise]' && !P.cast) { + return; } - return req; - }; -}); + } -Agent.prototype.del = Agent.prototype['delete']; + local.Promise = Promise$1; +} -/** - * GET `url` with optional callback `fn(res)`. - * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public - */ +// Strange compat.. +Promise$1.polyfill = polyfill; +Promise$1.Promise = Promise$1; -request.get = function(url, data, fn) { - var req = request('GET', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.query(data); - if (fn) req.end(fn); - return req; -}; +return Promise$1; -/** - * HEAD `url` with optional callback `fn(res)`. - * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public - */ +}))); -request.head = function(url, data, fn) { - var req = request('HEAD', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.query(data); - if (fn) req.end(fn); - return req; -}; -/** - * OPTIONS query to `url` with optional callback `fn(res)`. - * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public - */ -request.options = function(url, data, fn) { - var req = request('OPTIONS', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; -}; -/** - * DELETE `url` with optional `data` and callback `fn(res)`. - * - * @param {String} url - * @param {Mixed} [data] - * @param {Function} [fn] - * @return {Request} - * @api public - */ -function del(url, data, fn) { - var req = request('DELETE', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"_process":14}],11:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = (nBytes * 8) - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) } -request['del'] = del; -request['delete'] = del; +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = (nBytes * 8) - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } -/** - * PATCH `url` with optional `data` and callback `fn(res)`. - * - * @param {String} url - * @param {Mixed} [data] - * @param {Function} [fn] - * @return {Request} - * @api public - */ + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = ((value * c) - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } -request.patch = function(url, data, fn) { - var req = request('PATCH', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; -}; + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} -/** - * POST `url` with optional `data` and callback `fn(res)`. - * - * @param {String} url - * @param {Mixed} [data] - * @param {Function} [fn] - * @return {Request} - * @api public - */ + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} -request.post = function(url, data, fn) { - var req = request('POST', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; -}; + buffer[offset + i - d] |= s * 128 +} -/** - * PUT `url` with optional `data` and callback `fn(res)`. - * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public - */ +},{}],12:[function(require,module,exports){ +var toString = {}.toString; -request.put = function(url, data, fn) { - var req = request('PUT', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; }; -},{"./agent-base":9,"./is-object":11,"./request-base":12,"./response-base":13,"component-emitter":6}],11:[function(require,module,exports){ -'use strict'; +},{}],13:[function(require,module,exports){ +// the whatwg-fetch polyfill installs the fetch() function +// on the global object (window or self) +// +// Return that as the export for use in Webpack, Browserify etc. +require('whatwg-fetch'); +module.exports = self.fetch.bind(self); -/** - * Check if `obj` is an object. - * - * @param {Object} obj - * @return {Boolean} - * @api private - */ +},{"whatwg-fetch":15}],14:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; -function isObject(obj) { - return null !== obj && 'object' === typeof obj; -} +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. -module.exports = isObject; +var cachedSetTimeout; +var cachedClearTimeout; -},{}],12:[function(require,module,exports){ -'use strict'; +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } -/** - * Module of mixed-in functions shared between node and client code - */ -var isObject = require('./is-object'); -/** - * Expose `RequestBase`. - */ +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } -module.exports = RequestBase; -/** - * Initialize a new `RequestBase`. - * - * @api public - */ -function RequestBase(obj) { - if (obj) return mixin(obj); } +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; -/** - * Mixin the prototype properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in RequestBase.prototype) { - obj[key] = RequestBase.prototype[key]; - } - return obj; +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } } -/** - * Clear previous timeout. - * - * @return {Request} for chaining - * @api public - */ - -RequestBase.prototype.clearTimeout = function _clearTimeout(){ - clearTimeout(this._timer); - clearTimeout(this._responseTimeoutTimer); - delete this._timer; - delete this._responseTimeoutTimer; - return this; -}; - -/** - * Override default response body parser - * - * This function will be called to convert incoming data into request.body - * - * @param {Function} - * @api public - */ - -RequestBase.prototype.parse = function parse(fn){ - this._parser = fn; - return this; -}; +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; -/** - * Set format of binary response body. - * In browser valid formats are 'blob' and 'arraybuffer', - * which return Blob and ArrayBuffer, respectively. - * - * In Node all values result in Buffer. - * - * Examples: - * - * req.get('/') - * .responseType('blob') - * .end(callback); - * - * @param {String} val - * @return {Request} for chaining - * @api public - */ + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} -RequestBase.prototype.responseType = function(val){ - this._responseType = val; - return this; +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } }; -/** - * Override default request body serializer - * - * This function will be called to convert data set via .send or .attach into payload to send - * - * @param {Function} - * @api public - */ - -RequestBase.prototype.serialize = function serialize(fn){ - this._serializer = fn; - return this; +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); }; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; -/** - * Set timeouts. - * - * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time. - * - 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. - * - * Value of 0 or false means no timeout. - * - * @param {Number|Object} ms or {response, deadline} - * @return {Request} for chaining - * @api public - */ +function noop() {} -RequestBase.prototype.timeout = function timeout(options){ - if (!options || 'object' !== typeof options) { - this._timeout = options; - this._responseTimeout = 0; - return this; - } - - for(var option in options) { - switch(option) { - case 'deadline': - this._timeout = options.deadline; - break; - case 'response': - this._responseTimeout = options.response; - break; - default: - console.warn("Unknown timeout option", option); - } - } - return this; -}; +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; -/** - * Set number of retry attempts on error. - * - * Failed requests will be retried 'count' times if timeout or err.code >= 500. - * - * @param {Number} count - * @param {Function} [fn] - * @return {Request} for chaining - * @api public - */ +process.listeners = function (name) { return [] } -RequestBase.prototype.retry = function retry(count, fn){ - // Default to 1 if no count passed or true - if (arguments.length === 0 || count === true) count = 1; - if (count <= 0) count = 0; - this._maxRetries = count; - this._retries = 0; - this._retryCallback = fn; - return this; +process.binding = function (name) { + throw new Error('process.binding is not supported'); }; -var ERROR_CODES = [ - 'ECONNRESET', - 'ETIMEDOUT', - 'EADDRINFO', - 'ESOCKETTIMEDOUT' -]; - -/** - * Determine if a request should be retried. - * (Borrowed from segmentio/superagent-retry) - * - * @param {Error} err - * @param {Response} [res] - * @returns {Boolean} - */ -RequestBase.prototype._shouldRetry = function(err, res) { - if (!this._maxRetries || this._retries++ >= this._maxRetries) { - return false; - } - if (this._retryCallback) { - try { - var override = this._retryCallback(err, res); - if (override === true) return true; - if (override === false) return false; - // undefined falls back to defaults - } catch(e) { - console.error(e); - } - } - if (res && res.status && res.status >= 500 && res.status != 501) return true; - if (err) { - if (err.code && ~ERROR_CODES.indexOf(err.code)) return true; - // Superagent timeout - if (err.timeout && err.code == 'ECONNABORTED') return true; - if (err.crossDomain) return true; - } - return false; +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); }; +process.umask = function() { return 0; }; -/** - * Retry request - * - * @return {Request} for chaining - * @api private - */ - -RequestBase.prototype._retry = function() { - - this.clearTimeout(); +},{}],15:[function(require,module,exports){ +(function(self) { + 'use strict'; - // node - if (this.req) { - this.req = null; - this.req = this.request(); + if (self.fetch) { + return } - this._aborted = false; - this.timedout = false; - - return this._end(); -}; + var support = { + searchParams: 'URLSearchParams' in self, + iterable: 'Symbol' in self && 'iterator' in Symbol, + blob: 'FileReader' in self && 'Blob' in self && (function() { + try { + new Blob() + return true + } catch(e) { + return false + } + })(), + formData: 'FormData' in self, + arrayBuffer: 'ArrayBuffer' in self + } -/** - * Promise support - * - * @param {Function} resolve - * @param {Function} [reject] - * @return {Request} - */ + if (support.arrayBuffer) { + var viewClasses = [ + '[object Int8Array]', + '[object Uint8Array]', + '[object Uint8ClampedArray]', + '[object Int16Array]', + '[object Uint16Array]', + '[object Int32Array]', + '[object Uint32Array]', + '[object Float32Array]', + '[object Float64Array]' + ] + + var isDataView = function(obj) { + return obj && DataView.prototype.isPrototypeOf(obj) + } -RequestBase.prototype.then = function then(resolve, reject) { - if (!this._fullfilledPromise) { - var self = this; - if (this._endCalled) { - console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises"); + var isArrayBufferView = ArrayBuffer.isView || function(obj) { + return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1 } - this._fullfilledPromise = new Promise(function(innerResolve, innerReject) { - self.end(function(err, res) { - if (err) innerReject(err); - else innerResolve(res); - }); - }); } - return this._fullfilledPromise.then(resolve, reject); -}; -RequestBase.prototype['catch'] = function(cb) { - return this.then(undefined, cb); -}; + function normalizeName(name) { + if (typeof name !== 'string') { + name = String(name) + } + if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) { + throw new TypeError('Invalid character in header field name') + } + return name.toLowerCase() + } -/** - * Allow for extension - */ + function normalizeValue(value) { + if (typeof value !== 'string') { + value = String(value) + } + return value + } -RequestBase.prototype.use = function use(fn) { - fn(this); - return this; -}; + // Build a destructive iterator for the value list + function iteratorFor(items) { + var iterator = { + next: function() { + var value = items.shift() + return {done: value === undefined, value: value} + } + } -RequestBase.prototype.ok = function(cb) { - if ('function' !== typeof cb) throw Error("Callback required"); - this._okCallback = cb; - return this; -}; + if (support.iterable) { + iterator[Symbol.iterator] = function() { + return iterator + } + } -RequestBase.prototype._isResponseOK = function(res) { - if (!res) { - return false; + return iterator } - if (this._okCallback) { - return this._okCallback(res); + function Headers(headers) { + this.map = {} + + if (headers instanceof Headers) { + headers.forEach(function(value, name) { + this.append(name, value) + }, this) + } else if (Array.isArray(headers)) { + headers.forEach(function(header) { + this.append(header[0], header[1]) + }, this) + } else if (headers) { + Object.getOwnPropertyNames(headers).forEach(function(name) { + this.append(name, headers[name]) + }, this) + } } - return res.status >= 200 && res.status < 300; -}; - -/** - * Get request header `field`. - * Case-insensitive. - * - * @param {String} field - * @return {String} - * @api public - */ + Headers.prototype.append = function(name, value) { + name = normalizeName(name) + value = normalizeValue(value) + var oldValue = this.map[name] + this.map[name] = oldValue ? oldValue+','+value : value + } -RequestBase.prototype.get = function(field){ - return this._header[field.toLowerCase()]; -}; + Headers.prototype['delete'] = function(name) { + delete this.map[normalizeName(name)] + } -/** - * Get case-insensitive header `field` value. - * This is a deprecated internal API. Use `.get(field)` instead. - * - * (getHeader is no longer used internally by the superagent code base) - * - * @param {String} field - * @return {String} - * @api private - * @deprecated - */ + Headers.prototype.get = function(name) { + name = normalizeName(name) + return this.has(name) ? this.map[name] : null + } -RequestBase.prototype.getHeader = RequestBase.prototype.get; + Headers.prototype.has = function(name) { + return this.map.hasOwnProperty(normalizeName(name)) + } -/** - * Set header `field` to `val`, or multiple fields with one object. - * Case-insensitive. - * - * Examples: - * - * req.get('/') - * .set('Accept', 'application/json') - * .set('X-API-Key', 'foobar') - * .end(callback); - * - * req.get('/') - * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) - * .end(callback); - * - * @param {String|Object} field - * @param {String} val - * @return {Request} for chaining - * @api public - */ + Headers.prototype.set = function(name, value) { + this.map[normalizeName(name)] = normalizeValue(value) + } -RequestBase.prototype.set = function(field, val){ - if (isObject(field)) { - for (var key in field) { - this.set(key, field[key]); + Headers.prototype.forEach = function(callback, thisArg) { + for (var name in this.map) { + if (this.map.hasOwnProperty(name)) { + callback.call(thisArg, this.map[name], name, this) + } } - return this; } - this._header[field.toLowerCase()] = val; - this.header[field] = val; - return this; -}; -/** - * Remove header `field`. - * Case-insensitive. - * - * Example: - * - * req.get('/') - * .unset('User-Agent') - * .end(callback); - * - * @param {String} field - */ -RequestBase.prototype.unset = function(field){ - delete this._header[field.toLowerCase()]; - delete this.header[field]; - return this; -}; + Headers.prototype.keys = function() { + var items = [] + this.forEach(function(value, name) { items.push(name) }) + return iteratorFor(items) + } -/** - * Write the field `name` and `val`, or multiple fields with one object - * for "multipart/form-data" request bodies. - * - * ``` js - * request.post('/upload') - * .field('foo', 'bar') - * .end(callback); - * - * request.post('/upload') - * .field({ foo: 'bar', baz: 'qux' }) - * .end(callback); - * ``` - * - * @param {String|Object} name - * @param {String|Blob|File|Buffer|fs.ReadStream} val - * @return {Request} for chaining - * @api public - */ -RequestBase.prototype.field = function(name, val) { - // name should be either a string or an object. - if (null === name || undefined === name) { - throw new Error('.field(name, val) name can not be empty'); + Headers.prototype.values = function() { + var items = [] + this.forEach(function(value) { items.push(value) }) + return iteratorFor(items) } - if (this._data) { - console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()"); + Headers.prototype.entries = function() { + var items = [] + this.forEach(function(value, name) { items.push([name, value]) }) + return iteratorFor(items) } - if (isObject(name)) { - for (var key in name) { - this.field(key, name[key]); - } - return this; + if (support.iterable) { + Headers.prototype[Symbol.iterator] = Headers.prototype.entries } - if (Array.isArray(val)) { - for (var i in val) { - this.field(name, val[i]); + function consumed(body) { + if (body.bodyUsed) { + return Promise.reject(new TypeError('Already read')) } - return this; + body.bodyUsed = true } - // val should be defined now - if (null === val || undefined === val) { - throw new Error('.field(name, val) val can not be empty'); - } - if ('boolean' === typeof val) { - val = '' + val; + function fileReaderReady(reader) { + return new Promise(function(resolve, reject) { + reader.onload = function() { + resolve(reader.result) + } + reader.onerror = function() { + reject(reader.error) + } + }) } - this._getFormData().append(name, val); - return this; -}; - -/** - * Abort the request, and clear potential timeout. - * - * @return {Request} - * @api public - */ -RequestBase.prototype.abort = function(){ - if (this._aborted) { - return this; - } - this._aborted = true; - this.xhr && this.xhr.abort(); // browser - this.req && this.req.abort(); // node - this.clearTimeout(); - this.emit('abort'); - return this; -}; - -RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { - switch (options.type) { - case 'basic': - this.set('Authorization', 'Basic ' + base64Encoder(user + ':' + pass)); - break; - - case 'auto': - this.username = user; - this.password = pass; - break; - case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) - this.set('Authorization', 'Bearer ' + user); - break; + function readBlobAsArrayBuffer(blob) { + var reader = new FileReader() + var promise = fileReaderReady(reader) + reader.readAsArrayBuffer(blob) + return promise } - return this; -}; - -/** - * Enable transmission of cookies with x-domain requests. - * - * Note that for this to work the origin must not be - * using "Access-Control-Allow-Origin" with a wildcard, - * and also must set "Access-Control-Allow-Credentials" - * to "true". - * - * @api public - */ - -RequestBase.prototype.withCredentials = function(on) { - // This is browser-only functionality. Node side is no-op. - if (on == undefined) on = true; - this._withCredentials = on; - return this; -}; - -/** - * Set the max redirects to `n`. Does noting in browser XHR implementation. - * - * @param {Number} n - * @return {Request} for chaining - * @api public - */ -RequestBase.prototype.redirects = function(n){ - this._maxRedirects = n; - return this; -}; - -/** - * Maximum size of buffered response body, in bytes. Counts uncompressed size. - * Default 200MB. - * - * @param {Number} n - * @return {Request} for chaining - */ -RequestBase.prototype.maxResponseSize = function(n){ - if ('number' !== typeof n) { - throw TypeError("Invalid argument"); + function readBlobAsText(blob) { + var reader = new FileReader() + var promise = fileReaderReady(reader) + reader.readAsText(blob) + return promise } - this._maxResponseSize = n; - return this; -}; - -/** - * Convert to a plain javascript object (not JSON string) of scalar properties. - * Note as this method is designed to return a useful non-this value, - * it cannot be chained. - * - * @return {Object} describing method, url, and data of this request - * @api public - */ - -RequestBase.prototype.toJSON = function() { - return { - method: this.method, - url: this.url, - data: this._data, - headers: this._header, - }; -}; - -/** - * Send `data` as the request body, defaulting the `.type()` to "json" when - * an object is given. - * - * Examples: - * - * // manual json - * request.post('/user') - * .type('json') - * .send('{"name":"tj"}') - * .end(callback) - * - * // auto json - * request.post('/user') - * .send({ name: 'tj' }) - * .end(callback) - * - * // manual x-www-form-urlencoded - * request.post('/user') - * .type('form') - * .send('name=tj') - * .end(callback) - * - * // auto x-www-form-urlencoded - * request.post('/user') - * .type('form') - * .send({ name: 'tj' }) - * .end(callback) - * - * // defaults to x-www-form-urlencoded - * request.post('/user') - * .send('name=tobi') - * .send('species=ferret') - * .end(callback) - * - * @param {String|Object} data - * @return {Request} for chaining - * @api public - */ -RequestBase.prototype.send = function(data){ - var isObj = isObject(data); - var type = this._header['content-type']; + function readArrayBufferAsText(buf) { + var view = new Uint8Array(buf) + var chars = new Array(view.length) - if (this._formData) { - console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()"); - } - - if (isObj && !this._data) { - if (Array.isArray(data)) { - this._data = []; - } else if (!this._isHost(data)) { - this._data = {}; + for (var i = 0; i < view.length; i++) { + chars[i] = String.fromCharCode(view[i]) } - } else if (data && this._data && this._isHost(this._data)) { - throw Error("Can't merge these send calls"); + return chars.join('') } - // merge - if (isObj && isObject(this._data)) { - for (var key in data) { - this._data[key] = data[key]; - } - } else if ('string' == typeof data) { - // default to x-www-form-urlencoded - if (!type) this.type('form'); - type = this._header['content-type']; - if ('application/x-www-form-urlencoded' == type) { - this._data = this._data - ? this._data + '&' + data - : data; + function bufferClone(buf) { + if (buf.slice) { + return buf.slice(0) } else { - this._data = (this._data || '') + data; + var view = new Uint8Array(buf.byteLength) + view.set(new Uint8Array(buf)) + return view.buffer } - } else { - this._data = data; } - if (!isObj || this._isHost(data)) { - return this; - } + function Body() { + this.bodyUsed = false + + this._initBody = function(body) { + this._bodyInit = body + if (!body) { + this._bodyText = '' + } else if (typeof body === 'string') { + this._bodyText = body + } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { + this._bodyBlob = body + } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { + this._bodyFormData = body + } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { + this._bodyText = body.toString() + } else if (support.arrayBuffer && support.blob && isDataView(body)) { + this._bodyArrayBuffer = bufferClone(body.buffer) + // IE 10-11 can't handle a DataView body. + this._bodyInit = new Blob([this._bodyArrayBuffer]) + } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { + this._bodyArrayBuffer = bufferClone(body) + } else { + throw new Error('unsupported BodyInit type') + } - // default to json - if (!type) this.type('json'); - return this; -}; + if (!this.headers.get('content-type')) { + if (typeof body === 'string') { + this.headers.set('content-type', 'text/plain;charset=UTF-8') + } else if (this._bodyBlob && this._bodyBlob.type) { + this.headers.set('content-type', this._bodyBlob.type) + } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { + this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8') + } + } + } -/** - * Sort `querystring` by the sort function - * - * - * Examples: - * - * // default order - * request.get('/user') - * .query('name=Nick') - * .query('search=Manny') - * .sortQuery() - * .end(callback) - * - * // customized sort function - * request.get('/user') - * .query('name=Nick') - * .query('search=Manny') - * .sortQuery(function(a, b){ - * return a.length - b.length; - * }) - * .end(callback) - * - * - * @param {Function} sort - * @return {Request} for chaining - * @api public - */ + if (support.blob) { + this.blob = function() { + var rejected = consumed(this) + if (rejected) { + return rejected + } -RequestBase.prototype.sortQuery = function(sort) { - // _sort default to true but otherwise can be a function or boolean - this._sort = typeof sort === 'undefined' ? true : sort; - return this; -}; + if (this._bodyBlob) { + return Promise.resolve(this._bodyBlob) + } else if (this._bodyArrayBuffer) { + return Promise.resolve(new Blob([this._bodyArrayBuffer])) + } else if (this._bodyFormData) { + throw new Error('could not read FormData body as blob') + } else { + return Promise.resolve(new Blob([this._bodyText])) + } + } -/** - * Compose querystring to append to req.url - * - * @api private - */ -RequestBase.prototype._finalizeQueryString = function(){ - var query = this._query.join('&'); - if (query) { - this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query; - } - this._query.length = 0; // Makes the call idempotent - - if (this._sort) { - var index = this.url.indexOf('?'); - if (index >= 0) { - var queryArr = this.url.substring(index + 1).split('&'); - if ('function' === typeof this._sort) { - queryArr.sort(this._sort); - } else { - queryArr.sort(); + this.arrayBuffer = function() { + if (this._bodyArrayBuffer) { + return consumed(this) || Promise.resolve(this._bodyArrayBuffer) + } else { + return this.blob().then(readBlobAsArrayBuffer) + } } - this.url = this.url.substring(0, index) + '?' + queryArr.join('&'); } - } -}; -// For backwards compat only -RequestBase.prototype._appendQueryString = function() {console.trace("Unsupported");} + this.text = function() { + var rejected = consumed(this) + if (rejected) { + return rejected + } -/** - * Invoke callback with timeout error. - * - * @api private - */ + if (this._bodyBlob) { + return readBlobAsText(this._bodyBlob) + } else if (this._bodyArrayBuffer) { + return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)) + } else if (this._bodyFormData) { + throw new Error('could not read FormData body as text') + } else { + return Promise.resolve(this._bodyText) + } + } -RequestBase.prototype._timeoutError = function(reason, timeout, errno){ - if (this._aborted) { - return; - } - var err = new Error(reason + timeout + 'ms exceeded'); - err.timeout = timeout; - err.code = 'ECONNABORTED'; - err.errno = errno; - this.timedout = true; - this.abort(); - this.callback(err); -}; + if (support.formData) { + this.formData = function() { + return this.text().then(decode) + } + } -RequestBase.prototype._setTimeouts = function() { - var self = this; + this.json = function() { + return this.text().then(JSON.parse) + } - // deadline - if (this._timeout && !this._timer) { - this._timer = setTimeout(function(){ - self._timeoutError('Timeout of ', self._timeout, 'ETIME'); - }, this._timeout); - } - // response timeout - if (this._responseTimeout && !this._responseTimeoutTimer) { - this._responseTimeoutTimer = setTimeout(function(){ - self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT'); - }, this._responseTimeout); + return this } -}; -},{"./is-object":11}],13:[function(require,module,exports){ -'use strict'; + // HTTP methods whose capitalization should be normalized + var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'] -/** - * Module dependencies. - */ + function normalizeMethod(method) { + var upcased = method.toUpperCase() + return (methods.indexOf(upcased) > -1) ? upcased : method + } -var utils = require('./utils'); + function Request(input, options) { + options = options || {} + var body = options.body -/** - * Expose `ResponseBase`. - */ + if (input instanceof Request) { + if (input.bodyUsed) { + throw new TypeError('Already read') + } + this.url = input.url + this.credentials = input.credentials + if (!options.headers) { + this.headers = new Headers(input.headers) + } + this.method = input.method + this.mode = input.mode + if (!body && input._bodyInit != null) { + body = input._bodyInit + input.bodyUsed = true + } + } else { + this.url = String(input) + } -module.exports = ResponseBase; + this.credentials = options.credentials || this.credentials || 'omit' + if (options.headers || !this.headers) { + this.headers = new Headers(options.headers) + } + this.method = normalizeMethod(options.method || this.method || 'GET') + this.mode = options.mode || this.mode || null + this.referrer = null -/** - * Initialize a new `ResponseBase`. - * - * @api public - */ + if ((this.method === 'GET' || this.method === 'HEAD') && body) { + throw new TypeError('Body not allowed for GET or HEAD requests') + } + this._initBody(body) + } -function ResponseBase(obj) { - if (obj) return mixin(obj); -} + Request.prototype.clone = function() { + return new Request(this, { body: this._bodyInit }) + } -/** - * Mixin the prototype properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ + function decode(body) { + var form = new FormData() + body.trim().split('&').forEach(function(bytes) { + if (bytes) { + var split = bytes.split('=') + var name = split.shift().replace(/\+/g, ' ') + var value = split.join('=').replace(/\+/g, ' ') + form.append(decodeURIComponent(name), decodeURIComponent(value)) + } + }) + return form + } -function mixin(obj) { - for (var key in ResponseBase.prototype) { - obj[key] = ResponseBase.prototype[key]; + function parseHeaders(rawHeaders) { + var headers = new Headers() + // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space + // https://tools.ietf.org/html/rfc7230#section-3.2 + var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ') + preProcessedHeaders.split(/\r?\n/).forEach(function(line) { + var parts = line.split(':') + var key = parts.shift().trim() + if (key) { + var value = parts.join(':').trim() + headers.append(key, value) + } + }) + return headers } - return obj; -} -/** - * Get case-insensitive `field` value. - * - * @param {String} field - * @return {String} - * @api public - */ + Body.call(Request.prototype) -ResponseBase.prototype.get = function(field) { - return this.header[field.toLowerCase()]; -}; + function Response(bodyInit, options) { + if (!options) { + options = {} + } -/** - * Set header related properties: - * - * - `.type` the content type without params - * - * A response of "Content-Type: text/plain; charset=utf-8" - * will provide you with a `.type` of "text/plain". - * - * @param {Object} header - * @api private - */ + this.type = 'default' + this.status = options.status === undefined ? 200 : options.status + this.ok = this.status >= 200 && this.status < 300 + this.statusText = 'statusText' in options ? options.statusText : 'OK' + this.headers = new Headers(options.headers) + this.url = options.url || '' + this._initBody(bodyInit) + } -ResponseBase.prototype._setHeaderProperties = function(header){ - // TODO: moar! - // TODO: make this a util + Body.call(Response.prototype) - // content-type - var ct = header['content-type'] || ''; - this.type = utils.type(ct); + Response.prototype.clone = function() { + return new Response(this._bodyInit, { + status: this.status, + statusText: this.statusText, + headers: new Headers(this.headers), + url: this.url + }) + } - // params - var params = utils.params(ct); - for (var key in params) this[key] = params[key]; + Response.error = function() { + var response = new Response(null, {status: 0, statusText: ''}) + response.type = 'error' + return response + } - this.links = {}; + var redirectStatuses = [301, 302, 303, 307, 308] - // links - try { - if (header.link) { - this.links = utils.parseLinks(header.link); - } - } catch (err) { - // ignore + Response.redirect = function(url, status) { + if (redirectStatuses.indexOf(status) === -1) { + throw new RangeError('Invalid status code') } -}; -/** - * Set flags such as `.ok` based on `status`. - * - * For example a 2xx response will give you a `.ok` of __true__ - * whereas 5xx will be __false__ and `.error` will be __true__. The - * `.clientError` and `.serverError` are also available to be more - * specific, and `.statusType` is the class of error ranging from 1..5 - * sometimes useful for mapping respond colors etc. - * - * "sugar" properties are also defined for common cases. Currently providing: - * - * - .noContent - * - .badRequest - * - .unauthorized - * - .notAcceptable - * - .notFound - * - * @param {Number} status - * @api private - */ - -ResponseBase.prototype._setStatusProperties = function(status){ - var type = status / 100 | 0; - - // status / class - this.status = this.statusCode = status; - this.statusType = type; - - // basics - this.info = 1 == type; - this.ok = 2 == type; - this.redirect = 3 == type; - this.clientError = 4 == type; - this.serverError = 5 == type; - this.error = (4 == type || 5 == type) - ? this.toError() - : false; - - // sugar - this.created = 201 == status; - this.accepted = 202 == status; - this.noContent = 204 == status; - this.badRequest = 400 == status; - this.unauthorized = 401 == status; - this.notAcceptable = 406 == status; - this.forbidden = 403 == status; - this.notFound = 404 == status; - this.unprocessableEntity = 422 == status; -}; + return new Response(null, {status: status, headers: {location: url}}) + } -},{"./utils":14}],14:[function(require,module,exports){ -'use strict'; + self.Headers = Headers + self.Request = Request + self.Response = Response -/** - * Return the mime type for the given `str`. - * - * @param {String} str - * @return {String} - * @api private - */ + self.fetch = function(input, init) { + return new Promise(function(resolve, reject) { + var request = new Request(input, init) + var xhr = new XMLHttpRequest() -exports.type = function(str){ - return str.split(/ *; */).shift(); -}; + xhr.onload = function() { + var options = { + status: xhr.status, + statusText: xhr.statusText, + headers: parseHeaders(xhr.getAllResponseHeaders() || '') + } + options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL') + var body = 'response' in xhr ? xhr.response : xhr.responseText + resolve(new Response(body, options)) + } -/** - * Return header field parameters. - * - * @param {String} str - * @return {Object} - * @api private - */ + xhr.onerror = function() { + reject(new TypeError('Network request failed')) + } -exports.params = function(str){ - return str.split(/ *; */).reduce(function(obj, str){ - var parts = str.split(/ *= */); - var key = parts.shift(); - var val = parts.shift(); + xhr.ontimeout = function() { + reject(new TypeError('Network request failed')) + } - if (key && val) obj[key] = val; - return obj; - }, {}); -}; + xhr.open(request.method, request.url, true) -/** - * Parse Link header fields. - * - * @param {String} str - * @return {Object} - * @api private - */ + if (request.credentials === 'include') { + xhr.withCredentials = true + } else if (request.credentials === 'omit') { + xhr.withCredentials = false + } -exports.parseLinks = function(str){ - return str.split(/ *, */).reduce(function(obj, str){ - var parts = str.split(/ *; */); - var url = parts[0].slice(1, -1); - var rel = parts[1].split(/ *= */)[1].slice(1, -1); - obj[rel] = url; - return obj; - }, {}); -}; + if ('responseType' in xhr && support.blob) { + xhr.responseType = 'blob' + } -/** - * Strip content related fields from `header`. - * - * @param {Object} header - * @return {Object} header - * @api private - */ + request.headers.forEach(function(value, name) { + xhr.setRequestHeader(name, value) + }) -exports.cleanHeader = function(header, changesOrigin){ - delete header['content-type']; - delete header['content-length']; - delete header['transfer-encoding']; - delete header['host']; - // secuirty - if (changesOrigin) { - delete header['authorization']; - delete header['cookie']; - } - return header; -}; + xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit) + }) + } + self.fetch.polyfill = true +})(typeof self !== 'undefined' ? self : this); },{}]},{},[1]); diff --git a/lib/spec/core/responseHandling.d.ts b/lib/spec/core/responseHandling.d.ts index cb0ff5c3b..10f321b53 100644 --- a/lib/spec/core/responseHandling.d.ts +++ b/lib/spec/core/responseHandling.d.ts @@ -1 +1 @@ -export {}; +import 'isomorphic-fetch'; diff --git a/lib/spec/core/responseHandling.js b/lib/spec/core/responseHandling.js index dc6d2123c..b19a894d4 100644 --- a/lib/spec/core/responseHandling.js +++ b/lib/spec/core/responseHandling.js @@ -1,58 +1,49 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var ResponseHandler_1 = require("../../src/ResponseHandler"); -var assert = require("assert"); -var _200_SUPERAGENT_RES = { - ok: true, - statusCode: 200, - body: { - a: 1 - } -}; -var _500_SUPERAGENT_RES = { - ok: false, - response: { - body: { - error: { - "code": "SearchEvents", - "message": "The parameter $search is not currently supported on the Events resource.", - "innerError": { - "request-id": "b31c83fd-944c-4663-aa50-5d9ceb367e19", - "date": "2016-11-17T18:37:45" - } - } - } - }, - statusCode: 500 -}; -describe('#handleResponse()', function () { - it('passes through response to callback', function () { - ResponseHandler_1.ResponseHandler.init(null, _200_SUPERAGENT_RES, function (err, res) { - assert.equal(res, _200_SUPERAGENT_RES.body); - }); - }); - it('200 response => err is null', function () { - ResponseHandler_1.ResponseHandler.init(null, _200_SUPERAGENT_RES, function (err, res) { - assert.equal(err, null); - }); - }); -}); -describe('#ParseError()', function () { - it('500 error => res param in callback is null', function () { - ResponseHandler_1.ResponseHandler.init(null, _500_SUPERAGENT_RES, function (err, res) { - assert.equal(res, null); - }); - }); - it('extracts code and request-id from the JSON body of 500 errors', function () { - ResponseHandler_1.ResponseHandler.init(null, _500_SUPERAGENT_RES, function (err, res) { - assert.equal(err.code, _500_SUPERAGENT_RES.response.body.error.code); - assert.equal(err.requestId, _500_SUPERAGENT_RES.response.body.error.innerError["request-id"]); - }); - }); - it('parses a 404 superagent error', function () { - var rawErr = JSON.parse('{"original":null,"response":{"req":{"method":"GET","url":"https://graph.microsoft.com/v1.0/users/4470c514-8ac5-4f2d-8116-870d2c41bdf6/photo/$value","headers":{"authorization":"Bearer abc","cache-control":"no-cache","sdkversion":"graph-js-0.2.0"}},"xhr":{},"text":null,"statusText":"Not Found","statusCode":404,"status":404,"statusType":4,"info":false,"ok":false,"clientError":true,"serverError":false,"error":{"status":404,"method":"GET","url":"https://graph.microsoft.com/v1.0/users/4470c514-8ac5-4f2d-8116-870d2c41bdf6/photo/$value"},"accepted":false,"noContent":false,"badRequest":false,"unauthorized":false,"notAcceptable":false,"notFound":true,"forbidden":false,"headers":{"client-request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2","content-type":"text/plain","cache-control":"private","request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2"},"header":{"client-request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2","content-type":"text/plain","cache-control":"private","request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2"},"type":"text/plain","body":null},"status":404}'); - var graphErr = ResponseHandler_1.ResponseHandler.ParseError(rawErr); - assert.equal(graphErr.statusCode, 404); - }); -}); +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +require("isomorphic-fetch"); +var ResponseHandler_1 = require("../../src/ResponseHandler"); +var assert = require("assert"); +var _200_RES_BODY = { a: 1 }; +var _200_RES_INIT = { status: 200 }; +var _200_RES = new Response(_200_RES_BODY, _200_RES_INIT); +var _500_RES_BODY = { + error: { + "code": "SearchEvents", + "message": "The parameter $search is not currently supported on the Events resource.", + "innerError": { + "request-id": "b31c83fd-944c-4663-aa50-5d9ceb367e19", + "date": "2016-11-17T18:37:45" + } + } +}; +var _500_RES_INIT = { status: 500 }; +var _500_RES = new Response(_500_RES_BODY, _500_RES_INIT); +describe('#handleResponse()', function () { + it('passes through response to callback', function () { + ResponseHandler_1.ResponseHandler.init(_200_RES, null, _200_RES_BODY, function (err, res) { + assert.equal(res, _200_RES.body); + }); + }); + it('200 response => err is null', function () { + ResponseHandler_1.ResponseHandler.init(_200_RES, null, _200_RES_BODY, function (err, res) { + assert.equal(err, null); + }); + }); +}); +describe('#ParseResponse()', function () { + it('extracts code and request-id from the JSON body of 500 errors', function () { + ResponseHandler_1.ResponseHandler.init(_500_RES, null, _500_RES_BODY, function (err, res) { + assert.equal(err.code, _500_RES_BODY.error.code); + assert.equal(err.requestId, _500_RES_BODY.error.innerError["request-id"]); + }); + }); +}); +describe('#ParseError()', function () { + it('res param in callback is null', function () { + ResponseHandler_1.ResponseHandler.init(null, null, null, function (err, res) { + assert.equal(res, null); + assert.equal(err.statusCode, -1); + }); + }); +}); //# sourceMappingURL=responseHandling.js.map \ No newline at end of file diff --git a/lib/spec/core/responseHandling.js.map b/lib/spec/core/responseHandling.js.map index 1b4365897..2fc4ec5e8 100644 --- a/lib/spec/core/responseHandling.js.map +++ b/lib/spec/core/responseHandling.js.map @@ -1 +1 @@ -{"version":3,"file":"responseHandling.js","sourceRoot":"","sources":["../../../spec/core/responseHandling.ts"],"names":[],"mappings":";;AAAA,6DAAyD;AAIzD,+BAAiC;AAEjC,IAAM,mBAAmB,GAAG;IAC1B,EAAE,EAAE,IAAI;IACR,UAAU,EAAE,GAAG;IACf,IAAI,EAAE;QACJ,CAAC,EAAE,CAAC;KACL;CACF,CAAC;AAEF,IAAM,mBAAmB,GAAG;IACxB,EAAE,EAAE,KAAK;IACT,QAAQ,EAAE;QACN,IAAI,EAAE;YACF,KAAK,EAAE;gBACH,MAAM,EAAE,cAAc;gBACtB,SAAS,EAAE,0EAA0E;gBACrF,YAAY,EAAE;oBACV,YAAY,EAAE,sCAAsC;oBACpD,MAAM,EAAE,qBAAqB;iBAChC;aACJ;SACJ;KACJ;IACD,UAAU,EAAE,GAAG;CAClB,CAAC;AAGF,QAAQ,CAAC,mBAAmB,EAAE;IAC1B,EAAE,CAAC,qCAAqC,EAAE;QACtC,iCAAe,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,EAAE,UAAC,GAAc,EAAE,GAAG;YAChE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE;QAC9B,iCAAe,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,EAAE,UAAC,GAAc,EAAE,GAAG;YAChE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,eAAe,EAAE;IACtB,EAAE,CAAC,4CAA4C,EAAE;QAC7C,iCAAe,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,EAAE,UAAC,GAAc,EAAE,GAAG;YAChE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE;QAChE,iCAAe,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,EAAE,UAAC,GAAc,EAAE,GAAG;YAChE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;QAClG,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAGH,EAAE,CAAC,+BAA+B,EAAE;QAChC,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,4iCAA4iC,CAAC,CAAC;QAEtkC,IAAI,QAAQ,GAAG,iCAAe,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAElD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAE3C,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"responseHandling.js","sourceRoot":"","sources":["../../../spec/core/responseHandling.ts"],"names":[],"mappings":";;AAAA,4BAA0B;AAC1B,6DAAyD;AAKzD,+BAAiC;AAEjC,IAAM,aAAa,GAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACpC,IAAM,aAAa,GAAiB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACpD,IAAM,QAAQ,GACV,IAAI,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE/C,IAAM,aAAa,GAAQ;IACvB,KAAK,EAAE;QACH,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,0EAA0E;QACrF,YAAY,EAAE;YACV,YAAY,EAAE,sCAAsC;YACpD,MAAM,EAAE,qBAAqB;SAChC;KACJ;CACJ,CAAC;AAEF,IAAM,aAAa,GAAiB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACpD,IAAM,QAAQ,GACV,IAAI,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE/C,QAAQ,CAAC,mBAAmB,EAAE;IAC1B,EAAE,CAAC,qCAAqC,EAAE;QACtC,iCAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,UAAC,GAAc,EAAE,GAAG;YACpE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE;QAC9B,iCAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,UAAC,GAAc,EAAE,GAAG;YACpE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE;IACzB,EAAE,CAAC,+DAA+D,EAAE;QAChE,iCAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,UAAC,GAAc,EAAE,GAAG;YACpE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE;IACtB,EAAE,CAAC,+BAA+B,EAAE;QAChC,iCAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAC,GAAc,EAAE,GAAG;YACvD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/lib/spec/core/urlGeneration.d.ts b/lib/spec/core/urlGeneration.d.ts index cb0ff5c3b..509db1866 100644 --- a/lib/spec/core/urlGeneration.d.ts +++ b/lib/spec/core/urlGeneration.d.ts @@ -1 +1 @@ -export {}; +export {}; diff --git a/lib/spec/core/urlGeneration.js b/lib/spec/core/urlGeneration.js index 74809c06d..222bdd208 100644 --- a/lib/spec/core/urlGeneration.js +++ b/lib/spec/core/urlGeneration.js @@ -1,83 +1,83 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var assert = require("assert"); -var index_1 = require("../../src/index"); -var client = index_1.Client.init(); -var cases = []; -cases.push({ - url: "https://graph.microsoft.com/v1.0/me?$select=displayName", - request: client.api("/me") - .select("displayName") -}); -cases.push({ - url: "https://graph.microsoft.com/v1.0/me?$select=displayName", - request: client.api("/me") - .select(["displayName"]) -}); -cases.push({ - url: "https://graph.microsoft.com/v1.0/me?$select=displayName,jobTitle", - request: client.api("me") - .select(["displayName", "jobTitle"]) -}); -cases.push({ - url: "https://graph.microsoft.com/v1.0/me?$select=displayName,jobTitle", - request: client.api("/me") - .select(["displayName"]) - .select("jobTitle") -}); -cases.push({ - url: "https://graph.microsoft.com/beta/me?$select=displayName,jobTitle", - request: client.api("/me") - .version("beta") - .select(["displayName"]) - .select("jobTitle") -}); -cases.push({ - url: "https://graph.microsoft.com/beta/me?$select=displayName,jobTitle", - request: client.api("/me") - .version("beta") - .select(["displayName"]) - .select("jobTitle") -}); -cases.push({ - url: "https://graph.microsoft.com/beta/me/people?$select=displayName,title&$count=true", - request: client.api("/me/people") - .version("beta") - .select(["displayName"]) - .select("title") - .count(true) -}); -cases.push({ - url: "https://graph.microsoft.com/beta/me/people?$select=displayName,title&$count=true&$search=senior", - request: client.api("/me/people") - .version("beta") - .select(['displayName', 'title']) - .count(true) - .query({ "$search": "senior" }) -}); -cases.push({ - url: "https://graph.microsoft.com/beta/me/people?$select=displayName,title&$count=true&$search=senior", - request: client.api("/me/people") - .version("beta") - .select(['displayName', 'title']) - .count(true) - .query("$search=senior") -}); -cases.push({ - url: "https://graph.microsoft.com/v1.0/me/drive/root?$expand=children($select=name),permissions", - request: client.api("me/drive/root") - .expand("children($select=name)") - .expand("permissions") -}); -describe('#buildFullUrl()', function () { - var _loop_1 = function (i) { - var testCase = cases[i]; - it('should correctly build ' + testCase.url, function () { - assert.equal(testCase.url, testCase.request.buildFullUrl()); - }); - }; - for (var i = 0; i < cases.length; i++) { - _loop_1(i); - } -}); +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var assert = require("assert"); +var index_1 = require("../../src/index"); +var client = index_1.Client.init(); +var cases = []; +cases.push({ + url: "https://graph.microsoft.com/v1.0/me?$select=displayName", + request: client.api("/me") + .select("displayName") +}); +cases.push({ + url: "https://graph.microsoft.com/v1.0/me?$select=displayName", + request: client.api("/me") + .select(["displayName"]) +}); +cases.push({ + url: "https://graph.microsoft.com/v1.0/me?$select=displayName,jobTitle", + request: client.api("me") + .select(["displayName", "jobTitle"]) +}); +cases.push({ + url: "https://graph.microsoft.com/v1.0/me?$select=displayName,jobTitle", + request: client.api("/me") + .select(["displayName"]) + .select("jobTitle") +}); +cases.push({ + url: "https://graph.microsoft.com/beta/me?$select=displayName,jobTitle", + request: client.api("/me") + .version("beta") + .select(["displayName"]) + .select("jobTitle") +}); +cases.push({ + url: "https://graph.microsoft.com/beta/me?$select=displayName,jobTitle", + request: client.api("/me") + .version("beta") + .select(["displayName"]) + .select("jobTitle") +}); +cases.push({ + url: "https://graph.microsoft.com/beta/me/people?$select=displayName,title&$count=true", + request: client.api("/me/people") + .version("beta") + .select(["displayName"]) + .select("title") + .count(true) +}); +cases.push({ + url: "https://graph.microsoft.com/beta/me/people?$select=displayName,title&$count=true&$search=senior", + request: client.api("/me/people") + .version("beta") + .select(['displayName', 'title']) + .count(true) + .query({ "$search": "senior" }) +}); +cases.push({ + url: "https://graph.microsoft.com/beta/me/people?$select=displayName,title&$count=true&$search=senior", + request: client.api("/me/people") + .version("beta") + .select(['displayName', 'title']) + .count(true) + .query("$search=senior") +}); +cases.push({ + url: "https://graph.microsoft.com/v1.0/me/drive/root?$expand=children($select=name),permissions", + request: client.api("me/drive/root") + .expand("children($select=name)") + .expand("permissions") +}); +describe('#buildFullUrl()', function () { + var _loop_1 = function (i) { + var testCase = cases[i]; + it('should correctly build ' + testCase.url, function () { + assert.equal(testCase.url, testCase.request.buildFullUrl()); + }); + }; + for (var i = 0; i < cases.length; i++) { + _loop_1(i); + } +}); //# sourceMappingURL=urlGeneration.js.map \ No newline at end of file diff --git a/lib/spec/core/urlParsing.d.ts b/lib/spec/core/urlParsing.d.ts index cb0ff5c3b..509db1866 100644 --- a/lib/spec/core/urlParsing.d.ts +++ b/lib/spec/core/urlParsing.d.ts @@ -1 +1 @@ -export {}; +export {}; diff --git a/lib/spec/core/urlParsing.js b/lib/spec/core/urlParsing.js index 71d2ea990..421a8b867 100644 --- a/lib/spec/core/urlParsing.js +++ b/lib/spec/core/urlParsing.js @@ -1,33 +1,33 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var assert = require("assert"); -var index_1 = require("../../src/index"); -var client = index_1.Client.init(); -var testCases = { - "/me": "https://graph.microsoft.com/v1.0/me", - "/me/": "https://graph.microsoft.com/v1.0/me/", - "me": "https://graph.microsoft.com/v1.0/me", - "me/events": "https://graph.microsoft.com/v1.0/me/events", - "/me/events": "https://graph.microsoft.com/v1.0/me/events", - "https://graph.microsoft.com/v1.0/me/events": "https://graph.microsoft.com/v1.0/me/events", - "https://graph.microsoft.com/beta/me/events?$filter=startswith(subject, 'update')": "https://graph.microsoft.com/beta/me/events?$filter=startswith(subject, 'update')", - "me/events?$filter=startswith(subject, 'update')": "https://graph.microsoft.com/v1.0/me/events?$filter=startswith(subject, 'update')", - "/me?a=b": "https://graph.microsoft.com/v1.0/me?a=b", - "/me?$filter=b&c=d": "https://graph.microsoft.com/v1.0/me?$filter=b&c=d", - "me?$filter=b&c=d": "https://graph.microsoft.com/v1.0/me?$filter=b&c=d", - "me?$select=displayName": "https://graph.microsoft.com/v1.0/me?$select=displayName", - "me?select=displayName": "https://graph.microsoft.com/v1.0/me?select=displayName", - "https://graph.microsoft.com/beta/me?select=displayName": "https://graph.microsoft.com/beta/me?select=displayName" -}; -describe('#parsePath()', function () { - var _loop_1 = function (path) { - it('should correctly parse ' + path, function () { - var request = client.api(path); - assert.equal(request.buildFullUrl(), testCases[path]); - }); - }; - for (var path in testCases) { - _loop_1(path); - } -}); +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var assert = require("assert"); +var index_1 = require("../../src/index"); +var client = index_1.Client.init(); +var testCases = { + "/me": "https://graph.microsoft.com/v1.0/me", + "/me/": "https://graph.microsoft.com/v1.0/me/", + "me": "https://graph.microsoft.com/v1.0/me", + "me/events": "https://graph.microsoft.com/v1.0/me/events", + "/me/events": "https://graph.microsoft.com/v1.0/me/events", + "https://graph.microsoft.com/v1.0/me/events": "https://graph.microsoft.com/v1.0/me/events", + "https://graph.microsoft.com/beta/me/events?$filter=startswith(subject, 'update')": "https://graph.microsoft.com/beta/me/events?$filter=startswith(subject, 'update')", + "me/events?$filter=startswith(subject, 'update')": "https://graph.microsoft.com/v1.0/me/events?$filter=startswith(subject, 'update')", + "/me?a=b": "https://graph.microsoft.com/v1.0/me?a=b", + "/me?$filter=b&c=d": "https://graph.microsoft.com/v1.0/me?$filter=b&c=d", + "me?$filter=b&c=d": "https://graph.microsoft.com/v1.0/me?$filter=b&c=d", + "me?$select=displayName": "https://graph.microsoft.com/v1.0/me?$select=displayName", + "me?select=displayName": "https://graph.microsoft.com/v1.0/me?select=displayName", + "https://graph.microsoft.com/beta/me?select=displayName": "https://graph.microsoft.com/beta/me?select=displayName" +}; +describe('#parsePath()', function () { + var _loop_1 = function (path) { + it('should correctly parse ' + path, function () { + var request = client.api(path); + assert.equal(request.buildFullUrl(), testCases[path]); + }); + }; + for (var path in testCases) { + _loop_1(path); + } +}); //# sourceMappingURL=urlParsing.js.map \ No newline at end of file diff --git a/lib/src/GraphHelper.d.ts b/lib/src/GraphHelper.d.ts new file mode 100644 index 000000000..529130cbb --- /dev/null +++ b/lib/src/GraphHelper.d.ts @@ -0,0 +1,3 @@ +export declare class GraphHelper { + static serializeContent(content: any): any; +} diff --git a/lib/src/GraphHelper.js b/lib/src/GraphHelper.js new file mode 100644 index 000000000..858034b9b --- /dev/null +++ b/lib/src/GraphHelper.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var GraphHelper = (function () { + function GraphHelper() { + } + GraphHelper.serializeContent = function (content) { + var className = content.constructor.name; + if (className === 'Buffer' + || className === 'Blob' + || className === 'File' + || className === 'FormData' + || typeof content === 'string') { + return content; + } + if (className === 'ArrayBuffer') { + content = Buffer.from(content); + } + else if (className === 'Int8Array' + || className === 'Int16Array' + || className === 'Int32Array' + || className === 'Uint8Array' + || className === 'Uint16Array' + || className === 'Uint32Array' + || className === 'Uint8ClampedArray' + || className === 'Float32Array' + || className === 'Float64Array' + || className === 'DataView') { + content = Buffer.from(content.buffer); + } + else { + try { + content = JSON.stringify(content); + } + catch (error) { + console.log(error); + throw new Error('Invalid JSON content'); + } + } + return content; + }; + return GraphHelper; +}()); +exports.GraphHelper = GraphHelper; +//# sourceMappingURL=GraphHelper.js.map \ No newline at end of file diff --git a/lib/src/GraphHelper.js.map b/lib/src/GraphHelper.js.map new file mode 100644 index 000000000..15712a755 --- /dev/null +++ b/lib/src/GraphHelper.js.map @@ -0,0 +1 @@ +{"version":3,"file":"GraphHelper.js","sourceRoot":"","sources":["../../src/GraphHelper.ts"],"names":[],"mappings":";;AAAA;IAAA;IA+CA,CAAC;IAlCe,4BAAgB,GAA9B,UAA+B,OAAY;QACvC,IAAI,SAAS,GAAW,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;QAEjD,IAAI,SAAS,KAAK,QAAQ;eACnB,SAAS,KAAK,MAAM;eACpB,SAAS,KAAK,MAAM;eACpB,SAAS,KAAK,UAAU;eACxB,OAAO,OAAO,KAAK,QAAQ,EAAE;YAChC,OAAO,OAAO,CAAC;SAClB;QAED,IAAI,SAAS,KAAK,aAAa,EAAE;YAC7B,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SAClC;aAAM,IAAI,SAAS,KAAK,WAAW;eAC7B,SAAS,KAAK,YAAY;eAC1B,SAAS,KAAK,YAAY;eAC1B,SAAS,KAAK,YAAY;eAC1B,SAAS,KAAK,aAAa;eAC3B,SAAS,KAAK,aAAa;eAC3B,SAAS,KAAK,mBAAmB;eACjC,SAAS,KAAK,cAAc;eAC5B,SAAS,KAAK,cAAc;eAC5B,SAAS,KAAK,UAAU,EAAE;YAC7B,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SACzC;aAAM;YACH,IAAI;gBACA,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;aACrC;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;aAC3C;SACJ;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IACH,kBAAC;AAAD,CAAC,AA/CD,IA+CC;AA/CY,kCAAW"} \ No newline at end of file diff --git a/lib/src/GraphRequest.d.ts b/lib/src/GraphRequest.d.ts index 2abeeb479..5a679ee4c 100644 --- a/lib/src/GraphRequest.d.ts +++ b/lib/src/GraphRequest.d.ts @@ -1,47 +1,49 @@ -import { Promise } from 'es6-promise'; -import { Options, URLComponents, GraphRequestCallback } from "./common"; -export declare class GraphRequest { - config: Options; - urlComponents: URLComponents; - _headers: { - [key: string]: string | number; - }; - _responseType: string; - constructor(config: Options, path: string); - header(headerKey: string, headerValue: string): this; - headers(headers: { - [key: string]: string | number; - }): this; - parsePath(rawPath: string): void; - private urlJoin(urlSegments); - buildFullUrl(): string; - version(v: string): GraphRequest; - select(properties: string | string[]): GraphRequest; - expand(properties: string | string[]): GraphRequest; - orderby(properties: string | string[]): GraphRequest; - filter(filterStr: string): GraphRequest; - top(n: number): GraphRequest; - skip(n: number): GraphRequest; - skipToken(token: string): GraphRequest; - count(count: boolean): GraphRequest; - responseType(responseType: string): GraphRequest; - private addCsvQueryParamater(propertyName, propertyValue, additionalProperties); - delete(callback?: GraphRequestCallback): Promise; - patch(content: any, callback?: GraphRequestCallback): Promise; - post(content: any, callback?: GraphRequestCallback): Promise; - put(content: any, callback?: GraphRequestCallback): Promise; - create(content: any, callback?: GraphRequestCallback): Promise; - update(content: any, callback?: GraphRequestCallback): Promise; - del(callback?: GraphRequestCallback): Promise; - get(callback?: GraphRequestCallback): Promise; - private routeResponseToPromise(requestBuilder); - private routeResponseToCallback(requestBuilder, callback); - private sendRequestAndRouteResponse(requestBuilder, callback?); - getStream(callback: GraphRequestCallback): void; - putStream(stream: any, callback: Function): void; - private configureRequest(requestBuilder, accessToken); - query(queryDictionaryOrString: string | { - [key: string]: string | number; - }): GraphRequest; - private createQueryString(); -} +import { Promise } from 'es6-promise'; +import 'isomorphic-fetch'; +import { Options, URLComponents, GraphRequestCallback } from "./common"; +export declare class GraphRequest { + config: Options; + urlComponents: URLComponents; + _headers: { + [key: string]: string | number; + }; + _responseType: string; + constructor(config: Options, path: string); + header(headerKey: string, headerValue: string): this; + headers(headers: { + [key: string]: string | number; + }): this; + parsePath(rawPath: string): void; + private urlJoin(urlSegments); + buildFullUrl(): string; + version(v: string): GraphRequest; + select(properties: string | string[]): GraphRequest; + expand(properties: string | string[]): GraphRequest; + orderby(properties: string | string[]): GraphRequest; + filter(filterStr: string): GraphRequest; + top(n: number): GraphRequest; + skip(n: number): GraphRequest; + skipToken(token: string): GraphRequest; + count(count: boolean): GraphRequest; + responseType(responseType: string): GraphRequest; + private addCsvQueryParamater(propertyName, propertyValue, additionalProperties); + delete(callback?: GraphRequestCallback): Promise; + patch(content: any, callback?: GraphRequestCallback): Promise; + post(content: any, callback?: GraphRequestCallback): Promise; + put(content: any, callback?: GraphRequestCallback): Promise; + create(content: any, callback?: GraphRequestCallback): Promise; + update(content: any, callback?: GraphRequestCallback): Promise; + del(callback?: GraphRequestCallback): Promise; + get(callback?: GraphRequestCallback): Promise; + private routeResponseToPromise(request); + private routeResponseToCallback(request, callback); + private sendRequestAndRouteResponse(request, callback?); + getStream(callback: GraphRequestCallback): void; + putStream(stream: any, callback: Function): void; + private configureRequest(request, accessToken); + query(queryDictionaryOrString: string | { + [key: string]: string | number; + }): GraphRequest; + private createQueryString(); + private convertResponseType(response); +} diff --git a/lib/src/GraphRequest.js b/lib/src/GraphRequest.js index c1bc73803..a00c94ec6 100644 --- a/lib/src/GraphRequest.js +++ b/lib/src/GraphRequest.js @@ -1,280 +1,317 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var request = require("superagent"); -var es6_promise_1 = require("es6-promise"); -var common_1 = require("./common"); -var ResponseHandler_1 = require("./ResponseHandler"); -var GraphRequest = (function () { - function GraphRequest(config, path) { - this.config = config; - this._headers = {}; - this.urlComponents = { - host: this.config.baseUrl, - version: this.config.defaultVersion, - oDataQueryParams: {}, - otherURLQueryParams: {} - }; - this.parsePath(path); - } - GraphRequest.prototype.header = function (headerKey, headerValue) { - this._headers[headerKey] = headerValue; - return this; - }; - GraphRequest.prototype.headers = function (headers) { - for (var key in headers) { - this._headers[key] = headers[key]; - } - return this; - }; - GraphRequest.prototype.parsePath = function (rawPath) { - if (rawPath.indexOf("https://") != -1) { - rawPath = rawPath.replace("https://", ""); - var endOfHostStrPos = rawPath.indexOf("/"); - this.urlComponents.host = "https://" + rawPath.substring(0, endOfHostStrPos); - rawPath = rawPath.substring(endOfHostStrPos + 1, rawPath.length); - var endOfVersionStrPos = rawPath.indexOf("/"); - this.urlComponents.version = rawPath.substring(0, endOfVersionStrPos); - rawPath = rawPath.substring(endOfVersionStrPos + 1, rawPath.length); - } - if (rawPath.charAt(0) == "/") { - rawPath = rawPath.substr(1); - } - var queryStrPos = rawPath.indexOf("?"); - if (queryStrPos == -1) { - this.urlComponents.path = rawPath; - } - else { - this.urlComponents.path = rawPath.substr(0, queryStrPos); - var queryParams = rawPath.substring(queryStrPos + 1, rawPath.length).split("&"); - for (var _i = 0, queryParams_1 = queryParams; _i < queryParams_1.length; _i++) { - var queryParam = queryParams_1[_i]; - var queryParams_2 = queryParam.split("="); - var key = queryParams_2[0]; - var value = queryParams_2[1]; - if (common_1.oDataQueryNames.indexOf(key)) { - this.urlComponents.oDataQueryParams[key] = value; - } - else { - this.urlComponents.otherURLQueryParams[key] = value; - } - } - } - }; - GraphRequest.prototype.urlJoin = function (urlSegments) { - var tr = function (s) { return s.replace(/\/+$/, ''); }; - var tl = function (s) { return s.replace(/^\/+/, ''); }; - var joiner = function (pre, cur) { return [tr(pre), tl(cur)].join('/'); }; - var parts = Array.prototype.slice.call(urlSegments); - return parts.reduce(joiner); - }; - GraphRequest.prototype.buildFullUrl = function () { - var url = this.urlJoin([this.urlComponents.host, - this.urlComponents.version, - this.urlComponents.path]) - + this.createQueryString(); - if (this.config.debugLogging) { - console.log(url); - } - return url; - }; - GraphRequest.prototype.version = function (v) { - this.urlComponents.version = v; - return this; - }; - GraphRequest.prototype.select = function (properties) { - this.addCsvQueryParamater("$select", properties, arguments); - return this; - }; - GraphRequest.prototype.expand = function (properties) { - this.addCsvQueryParamater("$expand", properties, arguments); - return this; - }; - GraphRequest.prototype.orderby = function (properties) { - this.addCsvQueryParamater("$orderby", properties, arguments); - return this; - }; - GraphRequest.prototype.filter = function (filterStr) { - this.urlComponents.oDataQueryParams["$filter"] = filterStr; - return this; - }; - GraphRequest.prototype.top = function (n) { - this.urlComponents.oDataQueryParams["$top"] = n; - return this; - }; - GraphRequest.prototype.skip = function (n) { - this.urlComponents.oDataQueryParams["$skip"] = n; - return this; - }; - GraphRequest.prototype.skipToken = function (token) { - this.urlComponents.oDataQueryParams["$skipToken"] = token; - return this; - }; - GraphRequest.prototype.count = function (count) { - this.urlComponents.oDataQueryParams["$count"] = count.toString(); - return this; - }; - GraphRequest.prototype.responseType = function (responseType) { - this._responseType = responseType; - return this; - }; - GraphRequest.prototype.addCsvQueryParamater = function (propertyName, propertyValue, additionalProperties) { - this.urlComponents.oDataQueryParams[propertyName] = this.urlComponents.oDataQueryParams[propertyName] ? this.urlComponents.oDataQueryParams[propertyName] + "," : ""; - var allValues = []; - if (typeof propertyValue === "string") { - allValues.push(propertyValue); - } - else { - allValues = allValues.concat(propertyValue); - } - if (additionalProperties.length > 1 && typeof propertyValue === "string") { - allValues = Array.prototype.slice.call(additionalProperties); - } - this.urlComponents.oDataQueryParams[propertyName] += allValues.join(","); - }; - GraphRequest.prototype.delete = function (callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request.del(url), callback); - }; - GraphRequest.prototype.patch = function (content, callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .patch(url) - .send(content), callback); - }; - GraphRequest.prototype.post = function (content, callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .post(url) - .send(content), callback); - }; - GraphRequest.prototype.put = function (content, callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .put(url) - .type('application/octet-stream') - .send(content), callback); - }; - GraphRequest.prototype.create = function (content, callback) { - return this.post(content, callback); - }; - GraphRequest.prototype.update = function (content, callback) { - return this.patch(content, callback); - }; - GraphRequest.prototype.del = function (callback) { - return this.delete(callback); - }; - GraphRequest.prototype.get = function (callback) { - var url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request - .get(url), callback); - }; - GraphRequest.prototype.routeResponseToPromise = function (requestBuilder) { - var _this = this; - return new es6_promise_1.Promise(function (resolve, reject) { - _this.routeResponseToCallback(requestBuilder, function (err, body) { - if (err != null) { - reject(err); - } - else { - resolve(body); - } - }); - }); - }; - GraphRequest.prototype.routeResponseToCallback = function (requestBuilder, callback) { - var _this = this; - this.config.authProvider(function (err, accessToken) { - if (err == null && accessToken != null) { - var request_1 = _this.configureRequest(requestBuilder, accessToken); - request_1.end(function (err, res) { - ResponseHandler_1.ResponseHandler.init(err, res, callback); - }); - } - else { - callback(err, null, null); - } - }); - }; - GraphRequest.prototype.sendRequestAndRouteResponse = function (requestBuilder, callback) { - if (callback == null && typeof es6_promise_1.Promise !== "undefined") { - return this.routeResponseToPromise(requestBuilder); - } - else { - this.routeResponseToCallback(requestBuilder, callback || function () { }); - } - }; - GraphRequest.prototype.getStream = function (callback) { - var _this = this; - this.config.authProvider(function (err, accessToken) { - if (err === null && accessToken !== null) { - var url = _this.buildFullUrl(); - callback(null, _this.configureRequest(request.get(url), accessToken)); - } - else { - callback(err, null); - } - }); - }; - GraphRequest.prototype.putStream = function (stream, callback) { - var _this = this; - this.config.authProvider(function (err, accessToken) { - if (err === null && accessToken !== null) { - var url = _this.buildFullUrl(); - var req = _this.configureRequest(request.put(url), accessToken); - req.type('application/octet-stream'); - stream - .pipe(req) - .on('error', function (err) { - callback(err, null); - }) - .on('end', function () { - callback(null); - }); - } - }); - }; - GraphRequest.prototype.configureRequest = function (requestBuilder, accessToken) { - var request = requestBuilder - .set('Authorization', 'Bearer ' + accessToken) - .set(this._headers) - .set('SdkVersion', "graph-js-" + common_1.PACKAGE_VERSION); - if (this._responseType !== undefined) { - request.responseType(this._responseType); - } - return request; - }; - GraphRequest.prototype.query = function (queryDictionaryOrString) { - if (typeof queryDictionaryOrString === "string") { - var queryStr = queryDictionaryOrString; - var queryKey = queryStr.split("=")[0]; - var queryValue = queryStr.split("=")[1]; - this.urlComponents.otherURLQueryParams[queryKey] = queryValue; - } - else { - for (var key in queryDictionaryOrString) { - this.urlComponents.otherURLQueryParams[key] = queryDictionaryOrString[key]; - } - } - return this; - }; - GraphRequest.prototype.createQueryString = function () { - var q = []; - if (Object.keys(this.urlComponents.oDataQueryParams).length != 0) { - for (var property in this.urlComponents.oDataQueryParams) { - q.push(property + "=" + this.urlComponents.oDataQueryParams[property]); - } - } - if (Object.keys(this.urlComponents.otherURLQueryParams).length != 0) { - for (var property in this.urlComponents.otherURLQueryParams) { - q.push(property + "=" + this.urlComponents.otherURLQueryParams[property]); - } - } - if (q.length > 0) { - return "?" + q.join("&"); - } - return ""; - }; - return GraphRequest; -}()); -exports.GraphRequest = GraphRequest; +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var es6_promise_1 = require("es6-promise"); +require("isomorphic-fetch"); +var common_1 = require("./common"); +var ResponseHandler_1 = require("./ResponseHandler"); +var RequestMethod_1 = require("./RequestMethod"); +var GraphHelper_1 = require("./GraphHelper"); +var GraphRequest = (function () { + function GraphRequest(config, path) { + this.config = config; + this._headers = {}; + this.urlComponents = { + host: this.config.baseUrl, + version: this.config.defaultVersion, + oDataQueryParams: {}, + otherURLQueryParams: {} + }; + this.parsePath(path); + } + GraphRequest.prototype.header = function (headerKey, headerValue) { + this._headers[headerKey] = headerValue; + return this; + }; + GraphRequest.prototype.headers = function (headers) { + for (var key in headers) { + this._headers[key] = headers[key]; + } + return this; + }; + GraphRequest.prototype.parsePath = function (rawPath) { + if (rawPath.indexOf("https://") != -1) { + rawPath = rawPath.replace("https://", ""); + var endOfHostStrPos = rawPath.indexOf("/"); + this.urlComponents.host = "https://" + rawPath.substring(0, endOfHostStrPos); + rawPath = rawPath.substring(endOfHostStrPos + 1, rawPath.length); + var endOfVersionStrPos = rawPath.indexOf("/"); + this.urlComponents.version = rawPath.substring(0, endOfVersionStrPos); + rawPath = rawPath.substring(endOfVersionStrPos + 1, rawPath.length); + } + if (rawPath.charAt(0) == "/") { + rawPath = rawPath.substr(1); + } + var queryStrPos = rawPath.indexOf("?"); + if (queryStrPos == -1) { + this.urlComponents.path = rawPath; + } + else { + this.urlComponents.path = rawPath.substr(0, queryStrPos); + var queryParams = rawPath.substring(queryStrPos + 1, rawPath.length).split("&"); + for (var _i = 0, queryParams_1 = queryParams; _i < queryParams_1.length; _i++) { + var queryParam = queryParams_1[_i]; + var queryParams_2 = queryParam.split("="); + var key = queryParams_2[0]; + var value = queryParams_2[1]; + if (common_1.oDataQueryNames.indexOf(key)) { + this.urlComponents.oDataQueryParams[key] = value; + } + else { + this.urlComponents.otherURLQueryParams[key] = value; + } + } + } + }; + GraphRequest.prototype.urlJoin = function (urlSegments) { + var tr = function (s) { return s.replace(/\/+$/, ''); }; + var tl = function (s) { return s.replace(/^\/+/, ''); }; + var joiner = function (pre, cur) { return [tr(pre), tl(cur)].join('/'); }; + var parts = Array.prototype.slice.call(urlSegments); + return parts.reduce(joiner); + }; + GraphRequest.prototype.buildFullUrl = function () { + var url = this.urlJoin([this.urlComponents.host, + this.urlComponents.version, + this.urlComponents.path]) + + this.createQueryString(); + if (this.config.debugLogging) { + console.log(url); + } + return url; + }; + GraphRequest.prototype.version = function (v) { + this.urlComponents.version = v; + return this; + }; + GraphRequest.prototype.select = function (properties) { + this.addCsvQueryParamater("$select", properties, arguments); + return this; + }; + GraphRequest.prototype.expand = function (properties) { + this.addCsvQueryParamater("$expand", properties, arguments); + return this; + }; + GraphRequest.prototype.orderby = function (properties) { + this.addCsvQueryParamater("$orderby", properties, arguments); + return this; + }; + GraphRequest.prototype.filter = function (filterStr) { + this.urlComponents.oDataQueryParams["$filter"] = filterStr; + return this; + }; + GraphRequest.prototype.top = function (n) { + this.urlComponents.oDataQueryParams["$top"] = n; + return this; + }; + GraphRequest.prototype.skip = function (n) { + this.urlComponents.oDataQueryParams["$skip"] = n; + return this; + }; + GraphRequest.prototype.skipToken = function (token) { + this.urlComponents.oDataQueryParams["$skipToken"] = token; + return this; + }; + GraphRequest.prototype.count = function (count) { + this.urlComponents.oDataQueryParams["$count"] = count.toString(); + return this; + }; + GraphRequest.prototype.responseType = function (responseType) { + this._responseType = responseType; + return this; + }; + GraphRequest.prototype.addCsvQueryParamater = function (propertyName, propertyValue, additionalProperties) { + this.urlComponents.oDataQueryParams[propertyName] = this.urlComponents.oDataQueryParams[propertyName] ? this.urlComponents.oDataQueryParams[propertyName] + "," : ""; + var allValues = []; + if (typeof propertyValue === "string") { + allValues.push(propertyValue); + } + else { + allValues = allValues.concat(propertyValue); + } + if (additionalProperties.length > 1 && typeof propertyValue === "string") { + allValues = Array.prototype.slice.call(additionalProperties); + } + this.urlComponents.oDataQueryParams[propertyName] += allValues.join(","); + }; + GraphRequest.prototype.delete = function (callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { method: RequestMethod_1.RequestMethod.DELETE, headers: new Headers() }), callback); + }; + GraphRequest.prototype.patch = function (content, callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { + method: RequestMethod_1.RequestMethod.PATCH, + body: GraphHelper_1.GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/json' }) + }), callback); + }; + GraphRequest.prototype.post = function (content, callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { + method: RequestMethod_1.RequestMethod.POST, + body: GraphHelper_1.GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/json' }) + }), callback); + }; + GraphRequest.prototype.put = function (content, callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { + method: RequestMethod_1.RequestMethod.PUT, + body: GraphHelper_1.GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/octet-stream' }) + }), callback); + }; + GraphRequest.prototype.create = function (content, callback) { + return this.post(content, callback); + }; + GraphRequest.prototype.update = function (content, callback) { + return this.patch(content, callback); + }; + GraphRequest.prototype.del = function (callback) { + return this.delete(callback); + }; + GraphRequest.prototype.get = function (callback) { + var url = this.buildFullUrl(); + return this.sendRequestAndRouteResponse(new Request(url, { method: RequestMethod_1.RequestMethod.GET, headers: new Headers() }), callback); + }; + GraphRequest.prototype.routeResponseToPromise = function (request) { + var _this = this; + return new es6_promise_1.Promise(function (resolve, reject) { + _this.routeResponseToCallback(request, function (err, body) { + if (err != null) { + reject(err); + } + else { + resolve(body); + } + }); + }); + }; + GraphRequest.prototype.routeResponseToCallback = function (request, callback) { + var _this = this; + this.config.authProvider(function (err, accessToken) { + if (err == null && accessToken != null) { + fetch(_this.configureRequest(request, accessToken)).then(function (response) { + _this.convertResponseType(response).then(function (responseValue) { + ResponseHandler_1.ResponseHandler.init(response, undefined, responseValue, callback); + }).catch(function (error) { + ResponseHandler_1.ResponseHandler.init(response, error, undefined, callback); + }); + }).catch(function (error) { + ResponseHandler_1.ResponseHandler.init(undefined, error, undefined, callback); + }); + } + else { + callback(err, null, null); + } + }); + }; + GraphRequest.prototype.sendRequestAndRouteResponse = function (request, callback) { + if (callback == null && typeof es6_promise_1.Promise !== "undefined") { + return this.routeResponseToPromise(request); + } + else { + this.routeResponseToCallback(request, callback || function () { }); + } + }; + GraphRequest.prototype.getStream = function (callback) { + var _this = this; + this.config.authProvider(function (err, accessToken) { + if (err === null && accessToken !== null) { + var url = _this.buildFullUrl(); + callback(null, _this.configureRequest(new Request(url, { method: RequestMethod_1.RequestMethod.GET, headers: new Headers() }), accessToken)); + } + else { + callback(err, null); + } + }); + }; + GraphRequest.prototype.putStream = function (stream, callback) { + var _this = this; + this.config.authProvider(function (err, accessToken) { + if (err === null && accessToken !== null) { + var url = _this.buildFullUrl(); + var req = _this.configureRequest(new Request(url, { + method: RequestMethod_1.RequestMethod.PUT, + headers: new Headers({ 'Content-Type': 'application/octet-stream' }) + }), accessToken); + stream + .pipe(req) + .on('error', function (err) { + callback(err, null); + }) + .on('end', function () { + callback(null); + }); + } + }); + }; + GraphRequest.prototype.configureRequest = function (request, accessToken) { + var _this = this; + request.headers.append('Authorization', 'Bearer ' + accessToken); + request.headers.append('SdkVersion', "graph-js-" + common_1.PACKAGE_VERSION); + Object.keys(this._headers).forEach(function (key) { return request.headers.set(key, _this._headers[key]); }); + return request; + }; + GraphRequest.prototype.query = function (queryDictionaryOrString) { + if (typeof queryDictionaryOrString === "string") { + var queryStr = queryDictionaryOrString; + var queryKey = queryStr.split("=")[0]; + var queryValue = queryStr.split("=")[1]; + this.urlComponents.otherURLQueryParams[queryKey] = queryValue; + } + else { + for (var key in queryDictionaryOrString) { + this.urlComponents.otherURLQueryParams[key] = queryDictionaryOrString[key]; + } + } + return this; + }; + GraphRequest.prototype.createQueryString = function () { + var q = []; + if (Object.keys(this.urlComponents.oDataQueryParams).length != 0) { + for (var property in this.urlComponents.oDataQueryParams) { + q.push(property + "=" + this.urlComponents.oDataQueryParams[property]); + } + } + if (Object.keys(this.urlComponents.otherURLQueryParams).length != 0) { + for (var property in this.urlComponents.otherURLQueryParams) { + q.push(property + "=" + this.urlComponents.otherURLQueryParams[property]); + } + } + if (q.length > 0) { + return "?" + q.join("&"); + } + return ""; + }; + GraphRequest.prototype.convertResponseType = function (response) { + var responseValue; + if (!this._responseType) { + this._responseType = ''; + } + switch (this._responseType.toLowerCase()) { + case "arraybuffer": + responseValue = response.arrayBuffer(); + break; + case "blob": + responseValue = response.blob(); + break; + case "document": + responseValue = response.json(); + break; + case "json": + responseValue = response.json(); + break; + case "text": + responseValue = response.text(); + break; + default: + responseValue = response.json(); + break; + } + return responseValue; + }; + return GraphRequest; +}()); +exports.GraphRequest = GraphRequest; //# sourceMappingURL=GraphRequest.js.map \ No newline at end of file diff --git a/lib/src/GraphRequest.js.map b/lib/src/GraphRequest.js.map index bc7527508..f27301306 100644 --- a/lib/src/GraphRequest.js.map +++ b/lib/src/GraphRequest.js.map @@ -1 +1 @@ -{"version":3,"file":"GraphRequest.js","sourceRoot":"","sources":["../../src/GraphRequest.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"GraphRequest.js","sourceRoot":"","sources":["../../src/GraphRequest.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/lib/src/RequestMethod.d.ts b/lib/src/RequestMethod.d.ts new file mode 100644 index 000000000..5ee4498c0 --- /dev/null +++ b/lib/src/RequestMethod.d.ts @@ -0,0 +1,7 @@ +export declare enum RequestMethod { + GET = "GET", + PATCH = "PATCH", + POST = "POST", + PUT = "PUT", + DELETE = "DELETE", +} diff --git a/lib/src/RequestMethod.js b/lib/src/RequestMethod.js new file mode 100644 index 000000000..f27862469 --- /dev/null +++ b/lib/src/RequestMethod.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var RequestMethod; +(function (RequestMethod) { + RequestMethod["GET"] = "GET"; + RequestMethod["PATCH"] = "PATCH"; + RequestMethod["POST"] = "POST"; + RequestMethod["PUT"] = "PUT"; + RequestMethod["DELETE"] = "DELETE"; +})(RequestMethod = exports.RequestMethod || (exports.RequestMethod = {})); +//# sourceMappingURL=RequestMethod.js.map \ No newline at end of file diff --git a/lib/src/RequestMethod.js.map b/lib/src/RequestMethod.js.map new file mode 100644 index 000000000..7f25da0bc --- /dev/null +++ b/lib/src/RequestMethod.js.map @@ -0,0 +1 @@ +{"version":3,"file":"RequestMethod.js","sourceRoot":"","sources":["../../src/RequestMethod.ts"],"names":[],"mappings":";;AAAA,IAAY,aAMX;AAND,WAAY,aAAa;IACvB,4BAAW,CAAA;IACX,gCAAe,CAAA;IACf,8BAAa,CAAA;IACb,4BAAW,CAAA;IACX,kCAAiB,CAAA;AACnB,CAAC,EANW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAMxB"} \ No newline at end of file diff --git a/lib/src/ResponseHandler.d.ts b/lib/src/ResponseHandler.d.ts index 991dc7481..190007a56 100644 --- a/lib/src/ResponseHandler.d.ts +++ b/lib/src/ResponseHandler.d.ts @@ -1,5 +1,8 @@ -import { GraphRequestCallback, GraphError } from "./common"; -export declare class ResponseHandler { - static init(err: any, res: any, callback: GraphRequestCallback): void; - static ParseError(rawErr: any): GraphError; -} +import { GraphRequestCallback, GraphError } from "./common"; +export declare class ResponseHandler { + static init(res: any, err: any, resContents: any, callback: GraphRequestCallback): void; + static ParseError(rawErr: Error): GraphError; + static defaultGraphError(statusCode: number): GraphError; + static buildGraphErrorFromErrorObject(errObj: Error): GraphError; + static buildGraphErrorFromResponseObject(errObj: any, statusCode: number): GraphError; +} diff --git a/lib/src/ResponseHandler.js b/lib/src/ResponseHandler.js index 0d680db73..e91d2e762 100644 --- a/lib/src/ResponseHandler.js +++ b/lib/src/ResponseHandler.js @@ -1,57 +1,56 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var ResponseHandler = (function () { - function ResponseHandler() { - } - ResponseHandler.init = function (err, res, callback) { - if (res && res.ok) { - callback(null, res.body, res); - } - else { - if (err == null && res.error !== null) - callback(ResponseHandler.ParseError(res), null, res); - else - callback(ResponseHandler.ParseError(err), null, res); - } - }; - ResponseHandler.ParseError = function (rawErr) { - var errObj; - if (!('rawResponse' in rawErr)) { - if (rawErr.response !== undefined && rawErr.response.body !== null && 'error' in rawErr.response.body) { - errObj = rawErr.response.body.error; - } - } - else { - errObj = JSON.parse(rawErr.rawResponse.replace(/^\uFEFF/, '')).error; - } - var statusCode; - if (rawErr.response !== undefined && rawErr.response.status !== undefined) { - statusCode = rawErr.response.status; - } - else { - statusCode = rawErr.statusCode; - } - if (errObj === undefined) { - return { - statusCode: statusCode, - code: null, - message: null, - requestId: null, - date: new Date(), - body: null - }; - } - var err = { - statusCode: statusCode, - code: errObj.code, - message: errObj.message, - requestId: errObj.innerError["request-id"], - date: new Date(errObj.innerError.date), - body: errObj - }; - return err; - }; - return ResponseHandler; -}()); -exports.ResponseHandler = ResponseHandler; +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ResponseHandler = (function () { + function ResponseHandler() { + } + ResponseHandler.init = function (res, err, resContents, callback) { + if (res && res.ok) { + callback(null, resContents, res); + } + else { + if (err == null && res != null) + if (resContents != null && resContents.error != null) + callback(ResponseHandler.buildGraphErrorFromResponseObject(resContents.error, res.status), null, res); + else + callback(ResponseHandler.defaultGraphError(res.status), null, res); + else + callback(ResponseHandler.ParseError(err), null, res); + } + }; + ResponseHandler.ParseError = function (rawErr) { + if (!rawErr) { + return ResponseHandler.defaultGraphError(-1); + } + return ResponseHandler.buildGraphErrorFromErrorObject(rawErr); + }; + ResponseHandler.defaultGraphError = function (statusCode) { + return { + statusCode: statusCode, + code: null, + message: null, + requestId: null, + date: new Date(), + body: null + }; + }; + ResponseHandler.buildGraphErrorFromErrorObject = function (errObj) { + var error = ResponseHandler.defaultGraphError(-1); + error.body = errObj.toString(); + error.message = errObj.message; + error.date = new Date(); + return error; + }; + ResponseHandler.buildGraphErrorFromResponseObject = function (errObj, statusCode) { + return { + statusCode: statusCode, + code: errObj.code, + message: errObj.message, + requestId: errObj.innerError["request-id"], + date: new Date(errObj.innerError.date), + body: errObj + }; + }; + return ResponseHandler; +}()); +exports.ResponseHandler = ResponseHandler; //# sourceMappingURL=ResponseHandler.js.map \ No newline at end of file diff --git a/lib/src/ResponseHandler.js.map b/lib/src/ResponseHandler.js.map index 51ce967c7..c11888177 100644 --- a/lib/src/ResponseHandler.js.map +++ b/lib/src/ResponseHandler.js.map @@ -1 +1 @@ -{"version":3,"file":"ResponseHandler.js","sourceRoot":"","sources":["../../src/ResponseHandler.ts"],"names":[],"mappings":";;AAGA;IAAA;IAsEA,CAAC;IArEQ,oBAAI,GAAX,UAAY,GAAG,EAAE,GAAG,EAAE,QAA6B;QAC/C,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE;YACf,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;SAChC;aAAM;YACH,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI;gBACjC,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;;gBAErD,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;SAC3D;IACL,CAAC;IAgBQ,0BAAU,GAAjB,UAAkB,MAAM;QACpB,IAAI,MAAM,CAAC;QAEX,IAAI,CAAC,CAAC,aAAa,IAAI,MAAM,CAAC,EAAE;YAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;gBACnG,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;aACvC;SACJ;aAAM;YAGH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;SACxE;QAGD,IAAI,UAAiB,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE;YACvE,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;SACvC;aAAM;YACH,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;SAClC;QAGD,IAAI,MAAM,KAAK,SAAS,EAAE;YACtB,OAAO;gBACH,UAAU,YAAA;gBACV,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI;gBACf,IAAI,EAAE,IAAI,IAAI,EAAE;gBAChB,IAAI,EAAE,IAAI;aACb,CAAA;SACJ;QAED,IAAI,GAAG,GAAc;YACjB,UAAU,YAAA;YACV,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;YAC1C,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;YACtC,IAAI,EAAE,MAAM;SACf,CAAC;QAEF,OAAO,GAAG,CAAC;IACf,CAAC;IACL,sBAAC;AAAD,CAAC,AAtED,IAsEC;AAtEY,0CAAe"} \ No newline at end of file +{"version":3,"file":"ResponseHandler.js","sourceRoot":"","sources":["../../src/ResponseHandler.ts"],"names":[],"mappings":";;AAGA;IAAA;IAiEA,CAAC;IAhEU,oBAAI,GAAX,UAAY,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,QAA6B;QAC5D,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE;YACf,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,CAAA;SACnC;aAAM;YACH,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI;gBAC1B,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,CAAC,KAAK,IAAI,IAAI;oBAChD,QAAQ,CAAC,eAAe,CAAC,iCAAiC,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;;oBAEtG,QAAQ,CAAC,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;;gBAEtE,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;SAC3D;IACL,CAAC;IAeM,0BAAU,GAAjB,UAAkB,MAAa;QAE3B,IAAI,CAAC,MAAM,EAAE;YACT,OAAO,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;SAChD;QACD,OAAO,eAAe,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAClE,CAAC;IAEM,iCAAiB,GAAxB,UAAyB,UAAkB;QACvC,OAAO;YACH,UAAU,YAAA;YACV,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,IAAI,IAAI,EAAE;YAChB,IAAI,EAAE,IAAI;SACb,CAAA;IACL,CAAC;IAEM,8CAA8B,GAArC,UAAsC,MAAa;QAC/C,IAAM,KAAK,GAAe,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC/B,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,KAAK,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,iDAAiC,GAAxC,UAAyC,MAAW,EAAE,UAAkB;QACpE,OAAO;YACH,UAAU,YAAA;YACV,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;YAC1C,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;YACtC,IAAI,EAAE,MAAM;SACf,CAAC;IACN,CAAC;IACL,sBAAC;AAAD,CAAC,AAjED,IAiEC;AAjEY,0CAAe"} \ No newline at end of file diff --git a/lib/src/common.d.ts b/lib/src/common.d.ts index 99e492bf6..13d494c7b 100644 --- a/lib/src/common.d.ts +++ b/lib/src/common.d.ts @@ -1,35 +1,35 @@ -export declare let oDataQueryNames: string[]; -export declare const DEFAULT_VERSION = "v1.0"; -export declare const GRAPH_BASE_URL = "https://graph.microsoft.com/"; -export declare const PACKAGE_VERSION = "1.0.0"; -export interface AuthProviderCallback { - (error: any, accessToken: string): void; -} -export interface Options { - debugLogging?: boolean; - defaultVersion?: string; - authProvider?: (done: AuthProviderCallback) => void; - baseUrl?: string; -} -export interface URLComponents { - host: string; - version: string; - path?: string; - oDataQueryParams: { - [key: string]: string | number; - }; - otherURLQueryParams: { - [key: string]: string | number; - }; -} -export interface GraphRequestCallback { - (error: GraphError, response: any, rawResponse?: any): void; -} -export interface GraphError { - statusCode: number; - code: string; - message: string; - requestId: string; - date: Date; - body: string; -} +export declare let oDataQueryNames: string[]; +export declare const DEFAULT_VERSION = "v1.0"; +export declare const GRAPH_BASE_URL = "https://graph.microsoft.com/"; +export declare const PACKAGE_VERSION = "1.0.0"; +export interface AuthProviderCallback { + (error: any, accessToken: string): void; +} +export interface Options { + debugLogging?: boolean; + defaultVersion?: string; + authProvider?: (done: AuthProviderCallback) => void; + baseUrl?: string; +} +export interface URLComponents { + host: string; + version: string; + path?: string; + oDataQueryParams: { + [key: string]: string | number; + }; + otherURLQueryParams: { + [key: string]: string | number; + }; +} +export interface GraphRequestCallback { + (error: GraphError, response: any, rawResponse?: any): void; +} +export interface GraphError { + statusCode: number; + code: string; + message: string; + requestId: string; + date: Date; + body: string; +} diff --git a/lib/src/common.js b/lib/src/common.js index 45667260d..49949500a 100644 --- a/lib/src/common.js +++ b/lib/src/common.js @@ -1,8 +1,8 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.oDataQueryNames = ["select", "expand", "orderby", "filter", "top", "skip", "skipToken", "count"]; -exports.DEFAULT_VERSION = "v1.0"; -exports.GRAPH_BASE_URL = "https://graph.microsoft.com/"; -exports.PACKAGE_VERSION = "1.0.0"; -exports.oDataQueryNames = exports.oDataQueryNames.concat(exports.oDataQueryNames.map(function (s) { return "$" + s; })); +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.oDataQueryNames = ["select", "expand", "orderby", "filter", "top", "skip", "skipToken", "count"]; +exports.DEFAULT_VERSION = "v1.0"; +exports.GRAPH_BASE_URL = "https://graph.microsoft.com/"; +exports.PACKAGE_VERSION = "1.0.0"; +exports.oDataQueryNames = exports.oDataQueryNames.concat(exports.oDataQueryNames.map(function (s) { return "$" + s; })); //# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/lib/src/index.d.ts b/lib/src/index.d.ts index 260d4c764..e3ad2bc0c 100644 --- a/lib/src/index.d.ts +++ b/lib/src/index.d.ts @@ -1,10 +1,10 @@ -import { Options } from "./common"; -import { GraphRequest } from "./GraphRequest"; -export declare class Client { - config: Options; - static init(clientOptions?: Options): Client; - api(path: string): GraphRequest; -} -export * from "./GraphRequest"; -export * from "./common"; -export * from "./ResponseHandler"; +import { Options } from "./common"; +import { GraphRequest } from "./GraphRequest"; +export declare class Client { + config: Options; + static init(clientOptions?: Options): Client; + api(path: string): GraphRequest; +} +export * from "./GraphRequest"; +export * from "./common"; +export * from "./ResponseHandler"; diff --git a/lib/src/index.js b/lib/src/index.js index 044f8e7b1..4510e33e5 100644 --- a/lib/src/index.js +++ b/lib/src/index.js @@ -1,32 +1,32 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -Object.defineProperty(exports, "__esModule", { value: true }); -var common_1 = require("./common"); -var GraphRequest_1 = require("./GraphRequest"); -var Client = (function () { - function Client() { - this.config = { - debugLogging: false, - defaultVersion: common_1.DEFAULT_VERSION, - baseUrl: common_1.GRAPH_BASE_URL - }; - } - Client.init = function (clientOptions) { - var graphClient = new Client(); - for (var key in clientOptions) { - graphClient.config[key] = clientOptions[key]; - } - return graphClient; - }; - Client.prototype.api = function (path) { - return new GraphRequest_1.GraphRequest(this.config, path); - }; - return Client; -}()); -exports.Client = Client; -__export(require("./GraphRequest")); -__export(require("./common")); -__export(require("./ResponseHandler")); +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("./common"); +var GraphRequest_1 = require("./GraphRequest"); +var Client = (function () { + function Client() { + this.config = { + debugLogging: false, + defaultVersion: common_1.DEFAULT_VERSION, + baseUrl: common_1.GRAPH_BASE_URL + }; + } + Client.init = function (clientOptions) { + var graphClient = new Client(); + for (var key in clientOptions) { + graphClient.config[key] = clientOptions[key]; + } + return graphClient; + }; + Client.prototype.api = function (path) { + return new GraphRequest_1.GraphRequest(this.config, path); + }; + return Client; +}()); +exports.Client = Client; +__export(require("./GraphRequest")); +__export(require("./common")); +__export(require("./ResponseHandler")); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/lib/src/index.js.map b/lib/src/index.js.map index 1bdb82dea..2acdab94d 100644 --- a/lib/src/index.js.map +++ b/lib/src/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;AAEA,mCAAiE;AACjE,+CAA2C;AAE3C;IAAA;QAEI,WAAM,GAAW;YACb,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,wBAAe;YAC/B,OAAO,EAAE,uBAAc;SAC1B,CAAC;IAiBN,CAAC;IAfU,WAAI,GAAX,UAAY,aAAsB;QAC9B,IAAI,WAAW,GAAG,IAAI,MAAM,EAAE,CAAC;QAC/B,KAAK,IAAI,GAAG,IAAI,aAAa,EAAE;YAC3B,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;SAChD;QACD,OAAO,WAAW,CAAC;IACvB,CAAC;IAKD,oBAAG,GAAH,UAAI,IAAW;QACX,OAAO,IAAI,2BAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAEL,aAAC;AAAD,CAAC,AAvBD,IAuBC;AAvBY,wBAAM;AAyBnB,oCAA+B;AAC/B,8BAAyB;AACzB,uCAAkC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;AAAA,mCAAiE;AACjE,+CAA2C;AAE3C;IAAA;QAEI,WAAM,GAAW;YACb,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,wBAAe;YAC/B,OAAO,EAAE,uBAAc;SAC1B,CAAC;IAiBN,CAAC;IAfU,WAAI,GAAX,UAAY,aAAsB;QAC9B,IAAI,WAAW,GAAG,IAAI,MAAM,EAAE,CAAC;QAC/B,KAAK,IAAI,GAAG,IAAI,aAAa,EAAE;YAC3B,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;SAChD;QACD,OAAO,WAAW,CAAC;IACvB,CAAC;IAKD,oBAAG,GAAH,UAAI,IAAW;QACX,OAAO,IAAI,2BAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAEL,aAAC;AAAD,CAAC,AAvBD,IAuBC;AAvBY,wBAAM;AAyBnB,oCAA+B;AAC/B,8BAAyB;AACzB,uCAAkC"} \ No newline at end of file diff --git a/package.json b/package.json index d70cb74ca..42fbe6349 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ ], "types": "./lib/src/index.d.ts", "devDependencies": { - "@types/superagent": "^2.0.36", "@types/mocha": "^2.2.34", + "@types/node": "^9.4.0", "browserify": "^13.1.0", "mocha": "^3.2.0", "typescript": "^2.2.1" @@ -22,11 +22,11 @@ "test:types": "tsc --p spec/types && mocha spec/types" }, "dependencies": { - "superagent": "^3.5.2", - "es6-promise": "^4.1.0" + "es6-promise": "^4.1.0", + "isomorphic-fetch": "^2.2.1" }, "repository": { "type": "git", "url": "https://github.com/microsoftgraph/msgraph-sdk-javascript.git" } -} \ No newline at end of file +} diff --git a/sample.png b/sample.png new file mode 100644 index 000000000..4d2b65104 Binary files /dev/null and b/sample.png differ diff --git a/samples/node/node-sample.js b/samples/node/node-sample.js index 52684a516..b756b16ae 100644 --- a/samples/node/node-sample.js +++ b/samples/node/node-sample.js @@ -15,6 +15,8 @@ const client = MicrosoftGraph.init({ } }); +/* + // Get the name of the authenticated user with callbacks client .api('/me') @@ -27,7 +29,8 @@ client console.log(res.displayName); }); -/* + + // Get the name of the authenticated user with promises client .api('/me') @@ -39,11 +42,14 @@ client console.log(err); }); + */ + // Update the authenticated users birthday. client .api('/me') + .header("content-type", "application/json") .update( - {"birthday": "1908-12-22T00:00:00Z"}, + { "birthday": "1908-12-22T00:00:00Z" }, (err, res) => { if (err) { console.log(err); @@ -54,6 +60,11 @@ client ); + + +/* + + // GET /users client .api('/users') @@ -74,12 +85,13 @@ client .select("displayName") .get((err, res) => { if (err) { - console.log(err) + console. + console.log("%c" + err, 'color: #bada55') return; } - const topContacts = res.value.map((u) => {return u.displayName}); + const topContacts = res.value.map((u) => { return u.displayName }); console.log("Your top contacts are", topContacts.join(", ")); - }); + }); // Use promises instead of callbacks @@ -92,7 +104,7 @@ client console.log(res.displayName); }) .catch(console.error); - + // Find my top 5 contacts on the beta endpoint // .select() can be called multiple times client @@ -115,7 +127,7 @@ const mail = { subject: "MicrosoftGraph JavaScript SDK Samples", toRecipients: [{ emailAddress: { - address: "example@example.com" + address: "mmainer@microsoft.com" } }], body: { @@ -127,7 +139,7 @@ const mail = { client .api('/users/me/sendMail') .post( - {message: mail}, + { message: mail }, (err, res) => { if (err) console.log(err); @@ -145,30 +157,33 @@ client return; } var upcomingEventNames = [] - for (var i=0; i { - if (err) { - console.log(err) - return; - } - console.log(res.displayName) - }) -} +// let userIds = [secrets.userId1, +// secrets.userId2]; + +// for (let i = 0; i < userIds.length; i++) { +// let fetchUser = client +// .api(`/me/people/${userIds[i]}`) +// .version('beta') +// .select('displayName') +// .get((err, res) => { +// if (err) { +// console.log(err) +// return; +// } +// console.log(res.displayName) +// }) +// } + +/* // Find my top 5 contacts client @@ -201,8 +216,8 @@ client .api('/me') .select("displayName") .header('foo1', 'bar1') - .headers({'foo2': 'bar2'}) //.headers() for object, .header() for 2 params - .headers({'foo3': 'bar3', 'foo4': 'bar4'}) + .headers({ 'foo2': 'bar2' }) //.headers() for object, .header() for 2 params + .headers({ 'foo3': 'bar3', 'foo4': 'bar4' }) .get((err, res) => { if (err) { console.log(err) @@ -221,6 +236,9 @@ client console.log(res) }) +*/ + +/* // Download a file from OneDrive let fs = require('fs'); // requires filesystem module diff --git a/spec/core/responseHandling.ts b/spec/core/responseHandling.ts index bb5e31f92..815089505 100644 --- a/spec/core/responseHandling.ts +++ b/spec/core/responseHandling.ts @@ -1,72 +1,59 @@ +import 'isomorphic-fetch'; import {ResponseHandler} from "../../src/ResponseHandler" import {GraphError} from '../../src/common' + import * as mocha from 'mocha' import * as assert from 'assert'; -const _200_SUPERAGENT_RES = { - ok: true, - statusCode: 200, - body: { - a: 1 - } -}; - -const _500_SUPERAGENT_RES = { - ok: false, - response: { - body: { - error: { - "code": "SearchEvents", - "message": "The parameter $search is not currently supported on the Events resource.", - "innerError": { - "request-id": "b31c83fd-944c-4663-aa50-5d9ceb367e19", - "date": "2016-11-17T18:37:45" - } - } +const _200_RES_BODY: any = { a: 1 }; +const _200_RES_INIT: ResponseInit = { status: 200 }; +const _200_RES: Response = + new Response(_200_RES_BODY, _200_RES_INIT); + +const _500_RES_BODY: any = { + error: { + "code": "SearchEvents", + "message": "The parameter $search is not currently supported on the Events resource.", + "innerError": { + "request-id": "b31c83fd-944c-4663-aa50-5d9ceb367e19", + "date": "2016-11-17T18:37:45" } - }, - statusCode: 500 + } }; +const _500_RES_INIT: ResponseInit = { status: 500 }; +const _500_RES: Response = + new Response(_500_RES_BODY, _500_RES_INIT); describe('#handleResponse()', function() { it('passes through response to callback', function() { - ResponseHandler.init(null, _200_SUPERAGENT_RES, (err:GraphError, res) => { - assert.equal(res, _200_SUPERAGENT_RES.body); + ResponseHandler.init(_200_RES, null, _200_RES_BODY, (err:GraphError, res) => { + assert.equal(res, _200_RES.body); }); }); it('200 response => err is null', function() { - ResponseHandler.init(null, _200_SUPERAGENT_RES, (err:GraphError, res) => { + ResponseHandler.init(_200_RES, null, _200_RES_BODY, (err:GraphError, res) => { assert.equal(err, null); }); }); }); - - -describe('#ParseError()', function() { - it('500 error => res param in callback is null', function() { - ResponseHandler.init(null, _500_SUPERAGENT_RES, (err:GraphError, res) => { - assert.equal(res, null); +describe('#ParseResponse()', function() { + it('extracts code and request-id from the JSON body of 500 errors', function() { + ResponseHandler.init(_500_RES, null, _500_RES_BODY, (err:GraphError, res) => { + assert.equal(err.code, _500_RES_BODY.error.code); + assert.equal(err.requestId, _500_RES_BODY.error.innerError["request-id"]); }); }); +}); - it('extracts code and request-id from the JSON body of 500 errors', function() { - ResponseHandler.init(null, _500_SUPERAGENT_RES, (err:GraphError, res) => { - assert.equal(err.code, _500_SUPERAGENT_RES.response.body.error.code); - assert.equal(err.requestId, _500_SUPERAGENT_RES.response.body.error.innerError["request-id"]); +describe('#ParseError()', function() { + it('res param in callback is null', function() { + ResponseHandler.init(null, null, null, (err:GraphError, res) => { + assert.equal(res, null); + assert.equal(err.statusCode, -1); }); }); - - - it('parses a 404 superagent error', function() { - let rawErr = JSON.parse('{"original":null,"response":{"req":{"method":"GET","url":"https://graph.microsoft.com/v1.0/users/4470c514-8ac5-4f2d-8116-870d2c41bdf6/photo/$value","headers":{"authorization":"Bearer abc","cache-control":"no-cache","sdkversion":"graph-js-0.2.0"}},"xhr":{},"text":null,"statusText":"Not Found","statusCode":404,"status":404,"statusType":4,"info":false,"ok":false,"clientError":true,"serverError":false,"error":{"status":404,"method":"GET","url":"https://graph.microsoft.com/v1.0/users/4470c514-8ac5-4f2d-8116-870d2c41bdf6/photo/$value"},"accepted":false,"noContent":false,"badRequest":false,"unauthorized":false,"notAcceptable":false,"notFound":true,"forbidden":false,"headers":{"client-request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2","content-type":"text/plain","cache-control":"private","request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2"},"header":{"client-request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2","content-type":"text/plain","cache-control":"private","request-id":"3726fdf7-8ae6-47c0-9f6a-5847982738d2"},"type":"text/plain","body":null},"status":404}'); - - let graphErr = ResponseHandler.ParseError(rawErr); - - assert.equal(graphErr.statusCode, 404); - - }) }); \ No newline at end of file diff --git a/spec/types/miscellaneous.ts b/spec/types/miscellaneous.ts new file mode 100644 index 000000000..30d4e41da --- /dev/null +++ b/spec/types/miscellaneous.ts @@ -0,0 +1,193 @@ +/* + Tests in this file tries to cover functionality in Graph API, it may not contain exhaustive end points. Functionality + includes OData features, GET on complexType, GET on entity, POST an entity, POST an action etc.. + + Please make sure the following before running the test: + 1. For the tests to run, make sure that all the app permissions are there. + Visit https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference for further details + 2. It is also a requirement to add access token in secrets.js. + + Please follow the following steps to run the tests: + 1. cd into spec/types directory. + 2. npm install + 3. npm run test:types +*/ + +import { assert } from 'chai' +import { getClient, randomString } from "./test-helper" + + +declare const describe, it; + +describe('Fetch messages', function() { + this.timeout(10*1000); + /* + Following test assumes that number of messages exceed the default number for @odata.nextLink + to exist + */ + it('Fetch the messages', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/messages").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res['@odata.context']); + assert.isDefined(res['@odata.nextLink']); + assert.isDefined(res['value']); + done(); + }); + }); + + /* + Following test assumes that number of messages exceed the default number for @odata.nextLink to + exist + */ + it('Fetch the messages with $top', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/messages?$top=5").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res['@odata.context']); + assert.isDefined(res['@odata.nextLink']); + assert.isDefined(res['value']); + assert.isTrue(res.value.length == 5); + done(); + }); + }); + + /* + Following test assumes that number of messages exceed the default number for @odata.nextLink to exist + */ + it('Fetch the messages with $select', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/messages?$select=createdDateTime").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res['@odata.context']); + assert.isDefined(res['@odata.nextLink']); + assert.isDefined(res['value']); + assert.isDefined(res.value[0]['createdDateTime']); + done(); + }); + }); +}); + +describe('GET/PATCH mailBoxSettings', function() { + this.timeout(10*1000); + it('GET mailBoxSettings', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/mailboxSettings").get((err, res) => { + assert.isDefined(res['@odata.context']); + assert.isDefined(res['archiveFolder']); + assert.isDefined(res['timeZone']); + assert.isDefined(res['automaticRepliesSetting']); + assert.isDefined(res['language']); + assert.isDefined(res['workingHours']); + done(); + }); + }); + + it('PATCH mailBoxSettings', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/mailboxSettings").patch({"timeZone": "India Standard Time"}, (err, res) => { + assert.isDefined(res['@odata.context']); + assert.isDefined(res['timeZone']); + assert.isTrue(res['timeZone'] == 'India Standard Time'); + done(); + }); + }); +}); + +describe('Fetch inbox folder', function() { + this.timeout(10*1000); + it('GET me/mailfolders/inbox', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/mailfolders/inbox").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res['@odata.context']); + assert.isDefined(res['id']); + assert.isDefined(res['displayName']); + assert.isDefined(res['parentFolderId']); + assert.isDefined(res['childFolderCount']); + assert.isDefined(res['unreadItemCount']); + assert.isDefined(res['totalItemCount']); + done(); + }); + }); +}); + +describe('Fetch users and groups', function() { + this.timeout(10*1000); + it('GET users/{id}', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/users").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res); + assert.isDefined(res['value']); + const id = res['value'][0]['id']; + return getClient().api("https://graph.microsoft.com/v1.0/users/" + id).get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res); + assert.isTrue(res['id'] == id); + done(); + }); + }); + }); + + /* + Following test assumes that a group has been made in the tenant. + */ + it('GET groups/{id}', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/groups").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res); + const id = res['value'][0]['id']; + return getClient().api("https://graph.microsoft.com/v1.0/groups/" + id).get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res); + assert.isTrue(res['id'] == id); + done(); + }); + }); + }); +}); + +describe('Test for actions and functions', function() { + this.timeout(10*1000); + it('GET me/findrooms', function(done) { + return getClient().api("https://graph.microsoft.com/beta/me/findRooms").get((err, res) => { + assert.isTrue(err === null); + assert.isDefined(res['@odata.context']); + assert.isDefined(res['value']); + done(); + }); + }); + + it('POST me/getMailTips', function(done) { + return getClient().api("https://graph.microsoft.com/beta/me/getMailTips").post({ + "EmailAddresses": [ + "danas@contoso.onmicrosoft.com", + "fannyd@contoso.onmicrosoft.com" + ], + "MailTipsOptions": "automaticReplies, mailboxFullStatus" + }, (err, res) => { + assert.isTrue(err === null); + assert.isDefined(res['@odata.context']); + assert.isDefined(res['value']); + assert.isUndefined(res['error']); + done(); + }); + }); +}); + +describe('Test for GET and PUT binary data', function() { + this.timeout(10*1000); + it('PUT me/photo', function(done) { + const fs = require("fs"); + var nb = fs.readFileSync('sample.png'); + return getClient().api("https://graph.microsoft.com/v1.0/me/photo/$value").put(nb, (err, res) => { + assert.isTrue(err === null); + done(); + }); + }); + + it('GET me/photo', function(done) { + return getClient().api("https://graph.microsoft.com/v1.0/me/photo/$value").get((err, res) => { + assert.isTrue(err === null); + done(); + }); + }); +}); + + + + diff --git a/src/GraphHelper.ts b/src/GraphHelper.ts new file mode 100644 index 000000000..b8fbf313b --- /dev/null +++ b/src/GraphHelper.ts @@ -0,0 +1,48 @@ +export class GraphHelper { + + /* + This conversion is required due to the following reasons: + 1. Body parameter of Request method of isomorphic-fetch only accepts Blob, ArrayBuffer, FormData, TypedArrays, string. + 2. Node.js platform does not suppport Blob, FormData. Javascript File object inherits from Blob so it is also + not supported in node. Therefore content of type Blob, File, FormData will only come from browsers. + 3. Parallel to Javascript's arrayBuffer, node provides Buffer interface. Node's Buffer is able to send the arbitary + binary data to the server successfully for both Browser and Node platform. Whereas sending binary data via + ArrayBuffer or TypedArrays was only possible using Browser. To support both Node and Browser, `serializeContent` + converts TypedArrays or ArrayBuffer to `Node Buffer`. + 4. If the data received is in JSON format, `serializeContent` converts the JSON to string. + */ + public static serializeContent(content: any): any { + let className: string = content.constructor.name; + + if (className === 'Buffer' + || className === 'Blob' + || className === 'File' + || className === 'FormData' + || typeof content === 'string') { + return content; + } + + if (className === 'ArrayBuffer') { + content = Buffer.from(content); + } else if (className === 'Int8Array' + || className === 'Int16Array' + || className === 'Int32Array' + || className === 'Uint8Array' + || className === 'Uint16Array' + || className === 'Uint32Array' + || className === 'Uint8ClampedArray' + || className === 'Float32Array' + || className === 'Float64Array' + || className === 'DataView') { + content = Buffer.from(content.buffer); + } else { + try { + content = JSON.stringify(content); + } catch (error) { + console.log(error); + throw new Error('Invalid JSON content'); + } + } + return content; + } +} \ No newline at end of file diff --git a/src/GraphRequest.ts b/src/GraphRequest.ts index adb984430..e03c47ead 100644 --- a/src/GraphRequest.ts +++ b/src/GraphRequest.ts @@ -1,18 +1,19 @@ -import * as request from 'superagent'; import { Promise } from 'es6-promise' - +import 'isomorphic-fetch'; import { Options, URLComponents, GraphError, oDataQueryNames, GraphRequestCallback, PACKAGE_VERSION } from "./common" import { ResponseHandler } from "./ResponseHandler" +import { RequestMethod } from './RequestMethod'; +import { GraphHelper } from './GraphHelper'; export class GraphRequest { config: Options; urlComponents: URLComponents; - _headers:{ [key: string] : string|number; } // other headers to pass through to superagent + _headers: { [key: string]: string | number; } // other headers to pass through to superagent _responseType: string; - constructor(config: Options, path:string) { + constructor(config: Options, path: string) { this.config = config; this._headers = {}; @@ -26,23 +27,23 @@ export class GraphRequest { this.parsePath(path); } - public header(headerKey:string, headerValue:string) { + public header(headerKey: string, headerValue: string) { this._headers[headerKey] = headerValue; return this; } - public headers(headers:{ [key: string] : string|number }) { + public headers(headers: { [key: string]: string | number }) { for (let key in headers) { this._headers[key] = headers[key]; } return this; } - public parsePath(rawPath:string) { + public parsePath(rawPath: string) { // break rawPath into this.urlComponents // strip out the base url if they passed it in - if (rawPath.indexOf("https://")!= -1) { + if (rawPath.indexOf("https://") != -1) { rawPath = rawPath.replace("https://", ""); // find where the host ends @@ -58,12 +59,12 @@ export class GraphRequest { // strip version from rawPath rawPath = rawPath.substring(endOfVersionStrPos + 1, rawPath.length); } - + // strip out any leading "/" if (rawPath.charAt(0) == "/") { rawPath = rawPath.substr(1); } - + let queryStrPos = rawPath.indexOf("?"); // let afterPath = if (queryStrPos == -1) { @@ -71,7 +72,7 @@ export class GraphRequest { this.urlComponents.path = rawPath; } else { this.urlComponents.path = rawPath.substr(0, queryStrPos); - + // capture query string into // this.urlComponents.oDataQueryParams // and @@ -87,14 +88,14 @@ export class GraphRequest { if (oDataQueryNames.indexOf(key)) { this.urlComponents.oDataQueryParams[key] = value; } else { - this.urlComponents.otherURLQueryParams[key] = value; + this.urlComponents.otherURLQueryParams[key] = value; } } } } - - private urlJoin(urlSegments:string[]):String { + + private urlJoin(urlSegments: string[]): String { const tr = (s) => s.replace(/\/+$/, ''); const tl = (s) => s.replace(/^\/+/, ''); const joiner = (pre, cur) => [tr(pre), tl(cur)].join('/'); @@ -103,11 +104,11 @@ export class GraphRequest { return parts.reduce(joiner); } - public buildFullUrl():string { + public buildFullUrl(): string { let url = this.urlJoin([this.urlComponents.host, - this.urlComponents.version, - this.urlComponents.path]) - + this.createQueryString(); + this.urlComponents.version, + this.urlComponents.path]) + + this.createQueryString(); if (this.config.debugLogging) { console.log(url) @@ -116,7 +117,7 @@ export class GraphRequest { return url; } - version(v:string):GraphRequest { + version(v: string): GraphRequest { this.urlComponents.version = v; return this; } @@ -127,58 +128,58 @@ export class GraphRequest { * and .select("displayName", "birthday") * */ - select(properties:string|string[]):GraphRequest { + select(properties: string | string[]): GraphRequest { this.addCsvQueryParamater("$select", properties, arguments); return this; } - expand(properties:string|string[]):GraphRequest { + expand(properties: string | string[]): GraphRequest { this.addCsvQueryParamater("$expand", properties, arguments); return this; } - orderby(properties:string|string[]):GraphRequest { + orderby(properties: string | string[]): GraphRequest { this.addCsvQueryParamater("$orderby", properties, arguments); return this; } - - filter(filterStr:string):GraphRequest { + + filter(filterStr: string): GraphRequest { this.urlComponents.oDataQueryParams["$filter"] = filterStr; return this; } - top(n:number):GraphRequest { + top(n: number): GraphRequest { this.urlComponents.oDataQueryParams["$top"] = n; return this; } - skip(n:number):GraphRequest { + skip(n: number): GraphRequest { this.urlComponents.oDataQueryParams["$skip"] = n; return this; } - skipToken(token:string):GraphRequest { + skipToken(token: string): GraphRequest { this.urlComponents.oDataQueryParams["$skipToken"] = token; return this; } - count(count:boolean):GraphRequest { + count(count: boolean): GraphRequest { this.urlComponents.oDataQueryParams["$count"] = count.toString(); return this; } - - responseType(responseType:string):GraphRequest { + + responseType(responseType: string): GraphRequest { this._responseType = responseType; return this; } // helper for $select, $expand and $orderby (must be comma separated) - private addCsvQueryParamater(propertyName:string, propertyValue:string|string[], additionalProperties:IArguments) { + private addCsvQueryParamater(propertyName: string, propertyValue: string | string[], additionalProperties: IArguments) { // if there are already $propertyName value there, append a "," this.urlComponents.oDataQueryParams[propertyName] = this.urlComponents.oDataQueryParams[propertyName] ? this.urlComponents.oDataQueryParams[propertyName] + "," : ""; - let allValues:string[] = []; + let allValues: string[] = []; if (typeof propertyValue === "string") { allValues.push(propertyValue); @@ -195,72 +196,84 @@ export class GraphRequest { } - delete(callback?:GraphRequestCallback):Promise { + delete(callback?: GraphRequestCallback): Promise { let url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse(request.del(url), callback) + return this.sendRequestAndRouteResponse( + new Request(url, { method: RequestMethod.DELETE, headers: new Headers() }), + callback + ); } - patch(content:any, callback?:GraphRequestCallback):Promise { + patch(content: any, callback?: GraphRequestCallback): Promise { let url = this.buildFullUrl(); - return this.sendRequestAndRouteResponse( - request - .patch(url) - .send(content), + new Request( + url, + { + method: RequestMethod.PATCH, + body: GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/json' }) + }), callback ); } - post(content:any, callback?:GraphRequestCallback):Promise { + post(content: any, callback?: GraphRequestCallback): Promise { let url = this.buildFullUrl(); return this.sendRequestAndRouteResponse( - request - .post(url) - .send(content), - callback + new Request( + url, + { + method: RequestMethod.POST, + body: GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/json' }) + }), + callback ); } - put(content:any, callback?:GraphRequestCallback):Promise { + put(content: any, callback?: GraphRequestCallback): Promise { let url = this.buildFullUrl(); return this.sendRequestAndRouteResponse( - request - .put(url) - .type('application/octet-stream') - .send(content), - callback + new Request( + url, + { + method: RequestMethod.PUT, + body: GraphHelper.serializeContent(content), + headers: new Headers({ 'Content-Type': 'application/octet-stream' }) + }), + callback ); } // request aliases // alias for post - create(content:any, callback?:GraphRequestCallback):Promise { + create(content: any, callback?: GraphRequestCallback): Promise { return this.post(content, callback); } // alias for patch - update(content:any, callback?:GraphRequestCallback):Promise { + update(content: any, callback?: GraphRequestCallback): Promise { return this.patch(content, callback); } - del(callback?:GraphRequestCallback):Promise { + del(callback?: GraphRequestCallback): Promise { return this.delete(callback); } - get(callback?:GraphRequestCallback):Promise { + get(callback?: GraphRequestCallback): Promise { let url = this.buildFullUrl(); return this.sendRequestAndRouteResponse( - request - .get(url), - callback + new Request(url, { method: RequestMethod.GET, headers: new Headers() }), + callback ); } // Given the built SuperAgentRequest, get an auth token from the authProvider, make the request and return a promise - private routeResponseToPromise(requestBuilder:request.SuperAgentRequest) { + private routeResponseToPromise(request: Request) { return new Promise((resolve, reject) => { - this.routeResponseToCallback(requestBuilder, (err, body) => { + this.routeResponseToCallback(request, (err, body) => { if (err != null) { reject(err); } else { @@ -271,12 +284,17 @@ export class GraphRequest { } // Given the built SuperAgentRequest, get an auth token from the authProvider, make the request and invoke the callback - private routeResponseToCallback(requestBuilder:request.SuperAgentRequest, callback: GraphRequestCallback) { + private routeResponseToCallback(request: Request, callback: GraphRequestCallback) { this.config.authProvider((err, accessToken) => { if (err == null && accessToken != null) { - let request = this.configureRequest(requestBuilder, accessToken); - request.end((err, res) => { - ResponseHandler.init(err, res, callback) + fetch(this.configureRequest(request, accessToken)).then((response) => { + this.convertResponseType(response).then((responseValue) => { + ResponseHandler.init(response, undefined, responseValue, callback); + }).catch((error) => { + ResponseHandler.init(response, error, undefined, callback) + }); + }).catch((error) => { + ResponseHandler.init(undefined, error, undefined, callback) }); } else { callback(err, null, null); @@ -288,62 +306,65 @@ export class GraphRequest { * Help method that's called from the final actions( .get(), .post(), etc.) that after making the request either invokes * routeResponseToCallback() or routeResponseToPromise() */ - private sendRequestAndRouteResponse(requestBuilder:request.SuperAgentRequest, callback?:GraphRequestCallback):Promise { + private sendRequestAndRouteResponse(request: Request, callback?: GraphRequestCallback): Promise { // return a promise when Promises are supported and no callback was provided if (callback == null && typeof Promise !== "undefined") { - return this.routeResponseToPromise(requestBuilder); + return this.routeResponseToPromise(request); } else { - this.routeResponseToCallback(requestBuilder, callback || function(){}); + this.routeResponseToCallback(request, callback || function () { }); } } - getStream(callback:GraphRequestCallback) { + getStream(callback: GraphRequestCallback) { this.config.authProvider((err, accessToken) => { if (err === null && accessToken !== null) { let url = this.buildFullUrl(); - callback(null, this.configureRequest(request.get(url), accessToken)); + callback(null, this.configureRequest( + new Request(url, { method: RequestMethod.GET, headers: new Headers() }), + accessToken)); } else { callback(err, null); } }); } - putStream(stream:any, callback:Function) { + putStream(stream: any, callback: Function) { this.config.authProvider((err, accessToken) => { if (err === null && accessToken !== null) { let url = this.buildFullUrl(); - let req:request.Request = this.configureRequest(request.put(url), accessToken); - req.type('application/octet-stream'); + let req: Request = this.configureRequest( + new Request( + url, + { + method: RequestMethod.PUT, + headers: new Headers({ 'Content-Type': 'application/octet-stream' }) + }), + accessToken + ); stream .pipe(req) - .on('error', function(err) { + .on('error', function (err) { callback(err, null) }) - .on('end', function() { + .on('end', function () { callback(null) }); } }); } - private configureRequest(requestBuilder:request.SuperAgentRequest, accessToken:string):request.SuperAgentRequest { - let request = requestBuilder - .set('Authorization', 'Bearer ' + accessToken) - .set(this._headers) - .set('SdkVersion', "graph-js-" + PACKAGE_VERSION) - - if (this._responseType !== undefined) { - request.responseType(this._responseType); - } + private configureRequest(request: Request, accessToken: string): Request { + request.headers.append('Authorization', 'Bearer ' + accessToken); + request.headers.append('SdkVersion', "graph-js-" + PACKAGE_VERSION); + Object.keys(this._headers).forEach((key) => request.headers.set(key, this._headers[key] as string)); return request; } // append query strings to the url, accepts either a string like $select=displayName or a dictionary {"$select": "displayName"} - query(queryDictionaryOrString:string|{ [key: string] : string|number; }):GraphRequest { + query(queryDictionaryOrString: string | { [key: string]: string | number; }): GraphRequest { if (typeof queryDictionaryOrString === "string") { // is string let queryStr = queryDictionaryOrString; - //split .query("$select=displayName") into key and balue let queryKey = queryStr.split("=")[0]; let queryValue = queryStr.split("=")[1]; @@ -355,19 +376,19 @@ export class GraphRequest { } return this; } - + // ex: ?$select=displayName&$filter=startsWith(displayName, 'A') // does not include starting ? - private createQueryString():string { + private createQueryString(): string { // need to combine first this.urlComponents.oDataQueryParams and this.urlComponents.otherURLQueryParams - let q:string[] = []; + let q: string[] = []; if (Object.keys(this.urlComponents.oDataQueryParams).length != 0) { for (let property in this.urlComponents.oDataQueryParams) { q.push(property + "=" + this.urlComponents.oDataQueryParams[property]); } } - + if (Object.keys(this.urlComponents.otherURLQueryParams).length != 0) { for (let property in this.urlComponents.otherURLQueryParams) { q.push(property + "=" + this.urlComponents.otherURLQueryParams[property]); @@ -378,6 +399,35 @@ export class GraphRequest { return "?" + q.join("&"); } - return ""; + return ""; + } + + private convertResponseType(response: Response): Promise { + let responseValue: any; + if (!this._responseType) { + this._responseType = ''; + } + switch (this._responseType.toLowerCase()) { + case "arraybuffer": + responseValue = response.arrayBuffer(); + break; + case "blob": + responseValue = response.blob(); + break; + case "document": + // XMLHTTPRequest only :( + responseValue = response.json(); + break; + case "json": + responseValue = response.json(); + break; + case "text": + responseValue = response.text(); + break; + default: + responseValue = response.json(); + break; + } + return responseValue; } } \ No newline at end of file diff --git a/src/RequestMethod.ts b/src/RequestMethod.ts new file mode 100644 index 000000000..6209bb3ec --- /dev/null +++ b/src/RequestMethod.ts @@ -0,0 +1,7 @@ +export enum RequestMethod { + GET = 'GET', + PATCH = 'PATCH', + POST = 'POST', + PUT = 'PUT', + DELETE = 'DELETE' +} \ No newline at end of file diff --git a/src/ResponseHandler.ts b/src/ResponseHandler.ts index f7a129be9..0d1a351e9 100644 --- a/src/ResponseHandler.ts +++ b/src/ResponseHandler.ts @@ -2,17 +2,19 @@ import {GraphRequest} from "./GraphRequest" import {GraphRequestCallback, GraphError} from "./common" export class ResponseHandler { - static init(err, res, callback:GraphRequestCallback):void { - if (res && res.ok) { // 2xx - callback(null, res.body, res) - } else { // not OK response - if (err == null && res.error !== null) // if error was passed to body - callback(ResponseHandler.ParseError(res), null, res); - else // pass back error as first param - callback(ResponseHandler.ParseError(err), null, res) - } - } - + static init(res, err, resContents, callback:GraphRequestCallback):void { + if (res && res.ok) { // 2xx + callback(null, resContents, res) + } else { // not OK response + if (err == null && res != null) + if (resContents != null && resContents.error != null) // if error was passed to body + callback(ResponseHandler.buildGraphErrorFromResponseObject(resContents.error, res.status), null, res); + else + callback(ResponseHandler.defaultGraphError(res.status), null, res) + else // pass back error as first param + callback(ResponseHandler.ParseError(err), null, res) + } + } /* Example error for https://graph.microsoft.com/v1.0/me/events?$top=3&$search=foo @@ -27,40 +29,35 @@ export class ResponseHandler { } } */ - static ParseError(rawErr):GraphError { - let errObj; // path to object containing innerError (see above schema) - - if (!('rawResponse' in rawErr)) { // if superagent correctly parsed the JSON - if (rawErr.response !== undefined && rawErr.response.body !== null && 'error' in rawErr.response.body) { // some 404s don't return an error object - errObj = rawErr.response.body.error; - } - } else { - // if there was an error parsing the JSON - // possibly because of http://stackoverflow.com/a/38749510/2517012 - errObj = JSON.parse(rawErr.rawResponse.replace(/^\uFEFF/, '')).error; + static ParseError(rawErr: Error):GraphError { + // if we couldn't find an error obj to parse, just return an object with a status code and date + if (!rawErr) { + return ResponseHandler.defaultGraphError(-1); } + return ResponseHandler.buildGraphErrorFromErrorObject(rawErr); + } - // parse out statusCode - let statusCode:number; - if (rawErr.response !== undefined && rawErr.response.status !== undefined) { - statusCode = rawErr.response.status; - } else { - statusCode = rawErr.statusCode; - } - - // if we couldn't find an error obj to parse, just return an object with a status code and date - if (errObj === undefined) { - return { - statusCode, - code: null, - message: null, - requestId: null, - date: new Date(), - body: null - } + static defaultGraphError(statusCode: number):GraphError { + return { + statusCode, + code: null, + message: null, + requestId: null, + date: new Date(), + body: null } + } - let err:GraphError = { + static buildGraphErrorFromErrorObject(errObj: Error):GraphError { + const error: GraphError = ResponseHandler.defaultGraphError(-1); + error.body = errObj.toString(); + error.message = errObj.message; + error.date = new Date(); + return error; + } + + static buildGraphErrorFromResponseObject(errObj: any, statusCode: number):GraphError { + return { statusCode, code: errObj.code, message: errObj.message, @@ -68,7 +65,5 @@ export class ResponseHandler { date: new Date(errObj.innerError.date), body: errObj }; - - return err; } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 57ee11a69..40f3c4a00 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,3 @@ -import * as request from 'superagent'; - import {Options, DEFAULT_VERSION, GRAPH_BASE_URL} from "./common" import {GraphRequest} from "./GraphRequest"