UNPKG

mach

Version:
1,932 lines (1,560 loc) 101 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define(factory); else if(typeof exports === 'object') exports["mach"] = factory(); else root["mach"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var EXTENSIONS = []; /*! * mach - HTTP for JavaScript * https://github.com/mjackson/mach */ var mach = module.exports = { version: __webpack_require__(1), Connection: __webpack_require__(2), Header: __webpack_require__(3), Location: __webpack_require__(4), Message: __webpack_require__(5), extend: function extend() { var extension; for (var i = 0, len = arguments.length; i < len; ++i) { extension = arguments[i]; if (EXTENSIONS.indexOf(extension) === -1) { EXTENSIONS.push(extension); extension(mach); } } } }; mach.extend(__webpack_require__(6)); /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * The current version of mach. */ module.exports = "1.3.5"; /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /* jshint -W058 */ var d = __webpack_require__(18); var isBinary = __webpack_require__(20).isBinary; var decodeBase64 = __webpack_require__(7); var encodeBase64 = __webpack_require__(8); var stringifyQuery = __webpack_require__(9); var Promise = __webpack_require__(10); var Location = __webpack_require__(4); var Message = __webpack_require__(5); function locationPropertyAlias(name) { return d.gs(function () { return this.location[name]; }, function (value) { this.location[name] = value; }); } function defaultErrorHandler(error) { if (typeof console !== "undefined" && console.error) { console.error(error && error.stack || error); } else { throw error; // Don't silently swallow errors! } } function defaultCloseHandler() {} function defaultApp(conn) { conn.status = 404; conn.response.contentType = "text/plain"; conn.response.content = "Not found: " + conn.method + " " + conn.path; } /** * An HTTP connection that acts as the asynchronous primitive for * the duration of the request/response cycle. * * Important features are: * * - request A Message representing the request being made. In * a server environment, this is an "incoming" message * that was probably generated by a web browser or some * other consumer. In a client environment, this is an * "outgoing" message that we send to a remote server. * - response A Message representing the response to the request. * In a server environment, this is an "outgoing" message * that will be sent back to the client. In a client * environment, this is the response that was received * from the remote server. * - method The HTTP method that the request uses * - location The URL of the request. In a server environment, this * is derived from the URL path used in the request as * well as a combination of the Host, X-Forwarded-* and * other relevant headers. * - version The version of HTTP used in the request * - status The HTTP status code of the response * - statusText The HTTP status text that corresponds to the status * - responseText This is a special property that contains the entire * content of the response. It is present by default when * making client requests for convenience, but may also be * disabled when you need to stream the response. * * Options may be any of the following: * * - content The request content, defaults to "" * - headers The request headers, defaults to {} * - method The request HTTP method, defaults to "GET" * - location/url The request Location or URL * - params The request params * - onError A function that is called when there is an error * - onClose A function that is called when the request closes * * The options may also be a URL string to specify the URL. */ function Connection(options) { options = options || {}; var location; if (typeof options === "string") { location = options; // options may be a URL string. } else if (options.location || options.url) { location = options.location || options.url; } else if (typeof window === "object") { location = window.location.href; } this.location = location; this.version = options.version || "1.1"; this.method = options.method; this.onError = (options.onError || defaultErrorHandler).bind(this); this.onClose = (options.onClose || defaultCloseHandler).bind(this); this.request = new Message(options.content, options.headers); this.response = new Message(); // Params may be given as an object. if (options.params) { if (this.method === "GET" || this.method === "HEAD") { this.query = options.params; } else { this.request.contentType = "application/x-www-form-urlencoded"; this.request.content = stringifyQuery(options.params); } } this.withCredentials = options.withCredentials || false; this.remoteHost = options.remoteHost || null; this.remoteUser = options.remoteUser || null; this.basename = ""; this.responseText = null; this.status = 200; } Object.defineProperties(Connection.prototype, { /** * The method used in the request. */ method: d.gs(function () { return this._method; }, function (value) { this._method = typeof value === "string" ? value.toUpperCase() : "GET"; }), /** * The Location of the request. */ location: d.gs(function () { return this._location; }, function (value) { this._location = value instanceof Location ? value : new Location(value); }), href: locationPropertyAlias("href"), protocol: locationPropertyAlias("protocol"), host: locationPropertyAlias("host"), hostname: locationPropertyAlias("hostname"), port: locationPropertyAlias("port"), search: locationPropertyAlias("search"), queryString: locationPropertyAlias("queryString"), query: locationPropertyAlias("query"), /** * True if the request uses SSL, false otherwise. */ isSSL: d.gs(function () { return this.protocol === "https:"; }), /** * The username:password used in the request, an empty string * if no auth was provided. */ auth: d.gs(function () { var header = this.request.headers.Authorization; if (header) { var parts = header.split(" ", 2); var scheme = parts[0]; if (scheme.toLowerCase() === "basic") return decodeBase64(parts[1]); return header; } return this.location.auth; }, function (value) { var headers = this.request.headers; if (value && typeof value === "string") { headers.Authorization = "Basic " + encodeBase64(value); } else { delete headers.Authorization; } }), /** * The portion of the original URL path that is still relevant * for request processing. */ pathname: d.gs(function () { return this.location.pathname.replace(this.basename, "") || "/"; }, function (value) { this.location.pathname = this.basename + value; }), /** * The URL path with query string. */ path: d.gs(function () { return this.pathname + this.search; }, function (value) { this.location.path = this.basename + value; }), /** * Calls the given `app` with this connection as the only argument. * as the first argument and returns a promise for a Response. */ call: d(function (app) { app = app || defaultApp; var conn = this; try { return Promise.resolve(app(conn)).then(function (value) { if (value == null) return; if (typeof value === "number") { conn.status = value; } else if (typeof value === "string" || isBinary(value) || typeof value.pipe === "function") { conn.response.content = value; } else { if (value.headers != null) conn.response.headers = value.headers; if (value.content != null) conn.response.content = value.content; if (value.status != null) conn.status = value.status; } }); } catch (error) { return Promise.reject(error); } }) }); module.exports = Connection; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var normalizeHeaderName = __webpack_require__(11); var Header = (function () { function Header(name, value) { _classCallCheck(this, Header); this.name = name; this.value = value; } _prototypeProperties(Header, null, { name: { get: function () { return this._name; }, set: function (value) { this._name = normalizeHeaderName(value); }, configurable: true }, toString: { value: function toString() { return this.name + ": " + this.value; }, writable: true, configurable: true } }); return Header; })(); module.exports = Header; /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var d = __webpack_require__(18); var mergeQuery = __webpack_require__(12); var stringifyQuery = __webpack_require__(9); var parseQuery = __webpack_require__(13); var parseURL = __webpack_require__(16); /** * Standard ports for HTTP protocols. */ var STANDARD_PORTS = { "http:": "80", "https:": "443" }; function propertyAlias(propertyName, defaultValue) { return d.gs(function () { return this.properties[propertyName] || (defaultValue == null ? null : defaultValue); }, function (value) { this.properties[propertyName] = value; }); } // Order is important here. Later properties take priority. var PROPERTY_NAMES = ["protocol", "auth", "hostname", "port", "host", "pathname", "search", "queryString", "query", "path"]; function setProperties(location, properties) { var propertyName; for (var i = 0, len = PROPERTY_NAMES.length; i < len; ++i) { propertyName = PROPERTY_NAMES[i]; if (properties.hasOwnProperty(propertyName) && propertyName in location) location[propertyName] = properties[propertyName]; } } /** * A URL location, analogous to window.location. * * Options may be any of the following: * * - protocol * - auth * - hostname * - port * - host (overrides hostname and port) * - pathname * - search * - queryString (overrides search) * - query (overrides queryString/search) * - path (overrides pathname and query/queryString/search) * * Alternatively, options may be a URL string. */ function Location(options) { this.properties = {}; if (typeof options === "string") { this.href = options; } else if (options) { setProperties(this, options); } } Object.defineProperties(Location.prototype, { /** * Creates and returns a new Location with the path and query of * the given location appended. */ concat: d(function (location) { if (!(location instanceof Location)) location = new Location(location); var pathname = this.pathname; var extraPathname = location.pathname; if (extraPathname !== "/") pathname = pathname.replace(/\/*$/, "/") + extraPathname.replace(/^\/*/, ""); var query = mergeQuery(this.query, location.query); return new Location({ protocol: location.protocol || this.protocol, auth: location.auth || this.auth, hostname: location.hostname || this.hostname, port: location.port || this.port, pathname: pathname, query: query }); }), /** * The full URL. */ href: d.gs(function () { var auth = this.auth; var host = this.host; var path = this.path; return host ? this.protocol + "//" + (auth ? auth + "@" : "") + host + path : path; }, function (value) { var parsed = parseURL(value); setProperties(this, { protocol: parsed.protocol, auth: parsed.auth, hostname: parsed.hostname, port: parsed.port, pathname: parsed.pathname, search: parsed.search }); }), /** * The portion of the URL that denotes the protocol, including the * trailing colon (e.g. "http:" or "https:"). */ protocol: propertyAlias("protocol"), /** * The username:password used in the URL, if any. */ auth: propertyAlias("auth", ""), /** * The full name of the host, including the port number when using * a non-standard port. */ host: d.gs(function () { var protocol = this.protocol; var host = this.hostname; var port = this.port; if (port != null && port !== STANDARD_PORTS[protocol]) host += ":" + port; return host; }, function (value) { var index; if (typeof value === "string" && (index = value.indexOf(":")) !== -1) { this.hostname = value.substring(0, index); this.port = value.substring(index + 1); } else { this.hostname = value; this.port = null; } }), /** * The name of the host without the port. */ hostname: propertyAlias("hostname"), /** * The port number as a string. */ port: d.gs(function () { return this.properties.port || (this.protocol ? STANDARD_PORTS[this.protocol] : null); }, function (value) { this.properties.port = value ? String(value) : null; }), /** * The URL path without the query string. */ pathname: propertyAlias("pathname", "/"), /** * The URL path with query string. */ path: d.gs(function () { return this.pathname + this.search; }, function (value) { var index; if (typeof value === "string" && (index = value.indexOf("?")) !== -1) { this.pathname = value.substring(0, index); this.search = value.substring(index); } else { this.pathname = value; this.search = null; } }), /** * The query string, including the preceeding ?. */ search: propertyAlias("search", ""), /** * The query string of the URL, without the preceeding ?. */ queryString: d.gs(function () { return this.search.substring(1); }, function (value) { this.search = value && "?" + value; }), /** * An object of data in the query string. */ query: d.gs(function () { return parseQuery(this.queryString); }, function (value) { this.queryString = stringifyQuery(value); }), toJSON: d(function () { return this.href; }), toString: d(function () { return this.href; }) }); module.exports = Location; /***/ }, /* 5 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var bodec = __webpack_require__(20); var d = __webpack_require__(18); var Stream = __webpack_require__(19); var bufferStream = __webpack_require__(14); var normalizeHeaderName = __webpack_require__(11); var parseCookie = __webpack_require__(15); var parseQuery = __webpack_require__(13); /** * The default content to use for new messages. */ var DEFAULT_CONTENT = bodec.fromString(""); /** * The default maximum length (in bytes) to use in Message#parseContent. */ var DEFAULT_MAX_CONTENT_LENGTH = Math.pow(2, 20); // 1M var HEADERS_LINE_SEPARATOR = /\r?\n/; var HEADER_SEPARATOR = ": "; function defaultParser(message, maxLength) { return message.stringifyContent(maxLength); } /** * An HTTP message. */ function Message(content, headers) { this.headers = headers; this.content = content; } Object.defineProperties(Message, { PARSERS: d({ enumerable: true, value: { "application/json": function (message, maxLength) { return message.stringifyContent(maxLength).then(JSON.parse); }, "application/x-www-form-urlencoded": function (message, maxLength) { return message.stringifyContent(maxLength).then(parseQuery); } } }) }); Object.defineProperties(Message.prototype, { /** * The headers of this message as { headerName, value }. */ headers: d.gs(function () { return this._headers; }, function (value) { this._headers = {}; if (typeof value === "string") { value.split(HEADERS_LINE_SEPARATOR).forEach(function (line) { var index = line.indexOf(HEADER_SEPARATOR); if (index === -1) { this.addHeader(line, true); } else { this.addHeader(line.substring(0, index), line.substring(index + HEADER_SEPARATOR.length)); } }, this); } else if (value != null) { for (var headerName in value) if (value.hasOwnProperty(headerName)) this.addHeader(headerName, value[headerName]); } }), /** * Returns the value of the header with the given name. */ getHeader: d(function (headerName) { return this.headers[normalizeHeaderName(headerName)]; }), /** * Sets the value of the header with the given name. */ setHeader: d(function (headerName, value) { this.headers[normalizeHeaderName(headerName)] = value; }), /** * Adds the value to the header with the given name. */ addHeader: d(function (headerName, value) { headerName = normalizeHeaderName(headerName); var headers = this.headers; if (headerName in headers) { if (Array.isArray(headers[headerName])) { headers[headerName].push(value); } else { headers[headerName] = [headers[headerName], value]; } } else { headers[headerName] = value; } }), /** * An object containing cookies in this message, keyed by name. */ cookies: d.gs(function () { if (!this._cookies) { var header = this.headers.Cookie; if (header) { var cookies = parseCookie(header); // From RFC 2109: // If multiple cookies satisfy the criteria above, they are ordered in // the Cookie header such that those with more specific Path attributes // precede those with less specific. Ordering with respect to other // attributes (e.g., Domain) is unspecified. for (var cookieName in cookies) if (Array.isArray(cookies[cookieName])) cookies[cookieName] = cookies[cookieName][0] || ""; this._cookies = cookies; } else { this._cookies = {}; } } return this._cookies; }), /** * Gets/sets the value of the Content-Type header. */ contentType: d.gs(function () { return this.headers["Content-Type"]; }, function (value) { this.headers["Content-Type"] = value; }), /** * The media type (type/subtype) portion of the Content-Type header without any * media type parameters. e.g. when Content-Type is "text/plain;charset=utf-8", * the mediaType is "text/plain". * * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7 */ mediaType: d.gs(function () { var contentType = this.contentType, match; return contentType && (match = contentType.match(/^([^;,]+)/)) ? match[1].toLowerCase() : null; }, function (value) { this.contentType = value + (this.charset ? ";charset=" + this.charset : ""); }), /** * Returns the character set used to encode the content of this message. e.g. * when Content-Type is "text/plain;charset=utf-8", charset is "utf-8". * * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.4 */ charset: d.gs(function () { var contentType = this.contentType, match; return contentType && (match = contentType.match(/\bcharset=([\w-]+)/)) ? match[1] : null; }, function (value) { this.contentType = this.mediaType + (value ? ";charset=" + value : ""); }), /** * The content of this message as a binary stream. */ content: d.gs(function () { return this._content; }, function (value) { if (value == null) value = DEFAULT_CONTENT; if (value instanceof Stream) { this._content = value; value.pause(); } else { this._content = new Stream(value); } delete this._bufferedContent; }), /** * True if the content of this message is buffered, false otherwise. */ isBuffered: d.gs(function () { return this._bufferedContent != null; }), /** * Returns a binary representation of the content of this message up to * the given length. This is useful in applications that need to access the * entire message body at once, instead of as a stream. * * Note: 0 is a valid value for maxLength. It means "no limit". */ bufferContent: d(function (maxLength) { if (this._bufferedContent == null) this._bufferedContent = bufferStream(this.content, maxLength); return this._bufferedContent; }), /** * Returns the content of this message up to the given length as a string * with the given encoding. * * Note: 0 is a valid value for maxLength. It means "no limit". */ stringifyContent: d(function (maxLength, encoding) { encoding = encoding || this.charset; return this.bufferContent(maxLength).then(function (chunk) { return bodec.toString(chunk, encoding); }); }), /** * Returns a promise for an object of data contained in the content body. * * The maxLength argument specifies the maximum length (in bytes) that the * parser will accept. If the content stream exceeds the maximum length, the * promise is rejected with a MaxLengthExceededError. The appropriate response * to send to the client in this case is 413 Request Entity Too Large, but * many HTTP clients including most web browsers may not understand it. * * Note: 0 is a valid value for maxLength. It means "no limit". */ parseContent: d(function (maxLength) { if (this._parsedContent) return this._parsedContent; if (typeof maxLength !== "number") maxLength = DEFAULT_MAX_CONTENT_LENGTH; var parser = Message.PARSERS[this.mediaType] || defaultParser; this._parsedContent = parser(this, maxLength); return this._parsedContent; }) }); module.exports = Message; /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * The default extension for browser environments. */ module.exports = function (mach) { mach.extend(__webpack_require__(17)); }; /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(20).decodeBase64; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(20).encodeBase64; /***/ }, /* 9 */ /***/ function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(25).stringify; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var Promise = __webpack_require__(28); if (false) require("when/monitor")(Promise); module.exports = Promise; /***/ }, /* 11 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var IrregularHeaderNames = __webpack_require__(21); /** * Normalizes HTTP header names according to RFC 2616. */ function normalizeHeaderName(headerName) { headerName = headerName.toLowerCase(); if (headerName in IrregularHeaderNames) { return IrregularHeaderNames[headerName]; }return headerName.replace(/(^|-)([a-z])/g, function (match, dash, letter) { return dash + letter.toUpperCase(); }); } module.exports = normalizeHeaderName; /***/ }, /* 12 */ /***/ function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(26).merge; /***/ }, /* 13 */ /***/ function(module, exports, __webpack_require__) { "use strict"; module.exports = __webpack_require__(25).parse; /***/ }, /* 14 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var bodec = __webpack_require__(20); var Promise = __webpack_require__(10); var MaxLengthExceededError = __webpack_require__(22); /** * Returns a promise for a buffer of all content in the given stream up to * the given maximum length. */ function bufferStream(stream, maxLength) { maxLength = maxLength || Infinity; if (!stream.readable) throw new Error("Cannot buffer stream that is not readable"); return new Promise(function (resolve, reject) { var chunks = []; var length = 0; stream.on("error", reject); stream.on("data", function (chunk) { length += chunk.length; if (length > maxLength) { reject(new MaxLengthExceededError(maxLength)); } else { chunks.push(chunk); } }); stream.on("end", function () { resolve(bodec.join(chunks)); }); if (typeof stream.resume === "function") stream.resume(); }); } module.exports = bufferStream; /***/ }, /* 15 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var parseQuery = __webpack_require__(13); function parseCookie(cookie) { return parseQuery(cookie, { delimiter: /[;,] */ }); } module.exports = parseCookie; /***/ }, /* 16 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var ORIGIN_MATCHER = /^(https?:)\/\/(?:([^@]+)@)?([^/:]+)(?::(\d+))?/; function parseURL(url) { var origin = ORIGIN_MATCHER.exec(url) || {}; var anchor = document.createElement("a"); anchor.href = url; return { protocol: origin[1] || null, auth: origin[2] || null, hostname: origin[3] || null, port: origin[4] || null, pathname: anchor.pathname, search: anchor.search, hash: anchor.hash }; } module.exports = parseURL; /***/ }, /* 17 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var objectAssign = __webpack_require__(29); var sendRequest = __webpack_require__(27); var Location = __webpack_require__(4); function defaultApp(conn) { return sendRequest(conn, conn.location); } module.exports = function (mach) { mach.call = __webpack_require__(24); ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT", "TRACE"].forEach(function (method) { var property = method.toLowerCase(); mach[property] = function (app, options, modifier) { if (typeof app !== "function") { modifier = options; if (typeof app === "string") { // get(url, modifier) options = { url: app }; } else if (app instanceof Location) { // get(location, modifier) options = { location: app }; } else { // get(options, modifier) options = objectAssign({}, app || {}); } app = defaultApp; } else if (typeof options === "string") { // get(app, url, modifier) options = { url: options }; } else if (options instanceof Location) { // get(app, location, modifier) options = { location: options }; } else if (typeof options !== "object") { // get(app, modifier) modifier = options; options = {}; } else { // get(app, options, modifier) options = objectAssign({}, options || {}); } options.method = method; return mach.call(app, options, modifier); }; }); }; /***/ }, /* 18 */ /***/ function(module, exports, __webpack_require__) { var objectAssign = __webpack_require__(29); function describeProperty(descriptor) { if (typeof descriptor === 'function') descriptor = { value: descriptor }; // Use ES5 defaults. var defaults = { configurable: true, enumerable: false }; if (descriptor.get == null && descriptor.set == null) defaults.writable = true; return objectAssign(defaults, descriptor); } describeProperty.gs = function (get, set) { var descriptor = { get: get }; if (typeof set === 'function') descriptor.set = set; return describeProperty(descriptor); }; module.exports = describeProperty; /***/ }, /* 19 */ /***/ function(module, exports, __webpack_require__) { /* jshint -W084 */ /*! * BufferedStream - A robust stream implementation for node.js and the browser * https://github.com/mjackson/bufferedstream */ var bodec = __webpack_require__(20); var d = __webpack_require__(18); var EventEmitter = __webpack_require__(30).EventEmitter; /** * The default maximum buffer size. */ var DEFAULT_MAX_SIZE = Math.pow(2, 16); // 64k var BaseClass, async; if (typeof window === 'object') { BaseClass = EventEmitter; async = window.setTimeout; } else { BaseClass = __webpack_require__(23).Stream; async = process.nextTick; } function trackSource(dest) { dest.on('pipe', function (source) { if (dest._source) throw new Error('BufferedStream is already piped'); dest._source = source; function cleanup() { dest._source = null; source.removeListener('error', cleanup); source.removeListener('end', cleanup); } source.on('error', cleanup); source.on('end', cleanup); }); } function flushSoon(stream) { if (stream._flushing) return; stream._flushing = true; async(function tryToFlush() { if (stream.paused) { stream._flushing = false; return; } flush(stream); if (stream.empty) { stream._flushing = false; } else { async(tryToFlush); } }); } function flush(stream) { if (!stream._chunks) return; var chunk; while (chunk = stream._chunks.shift()) { stream.size -= chunk.length; if (stream.encoding) { stream.emit('data', bodec.toString(chunk, stream.encoding)); } else { stream.emit('data', chunk); } // If the stream was paused in a data event handler, break. if (stream.paused) break; } if (stream.ended) { if (!stream.paused) { stream._chunks = null; stream.emit('end'); } } else if (stream._wasFull && !stream.full) { stream._wasFull = false; stream.emit('drain'); } } /** * A robust stream implementation for node.js and the browser based on the * initial version of the stream API in Node.js. * * The maxSize determines the number of bytes the buffer can hold before it is * considered "full". Defaults to 64k. * * The source and sourceEncoding arguments may be used to easily wrap this * stream around another, or a simple string. If the source is another stream, * it is piped to this stream. If it's a string or binary data, it is used as * the entire contents of the stream. * * NOTE: The maxSize is a soft limit that is only used to determine when calls * to write will return false, indicating to streams that are writing to this * stream that they should pause. In any case, calls to write will still append * to the buffer so that no data is lost. */ function BufferedStream(maxSize, source, sourceEncoding) { if (!(this instanceof BufferedStream)) return new BufferedStream(maxSize, source, sourceEncoding); BaseClass.call(this); if (typeof maxSize !== 'number') { sourceEncoding = source; source = maxSize; maxSize = DEFAULT_MAX_SIZE; } // Public interface. this.maxSize = maxSize; this.size = 0; this.encoding = null; this.paused = true; this.ended = false; this.readable = true; this.writable = true; this._chunks = []; this._flushing = false; this._wasFull = false; this._source = null; trackSource(this); if (source != null) { if (typeof source.pipe === 'function') { if (typeof source.resume === 'function') source.resume(); // Triggers "old mode" in node v2 streams. source.pipe(this); } else { this.end(source, sourceEncoding); } } } BufferedStream.prototype = Object.create(BaseClass.prototype, { constructor: d(BufferedStream), /** * A read-only property that is true if this stream has no data to emit. */ empty: d.gs(function () { return this._chunks == null || this._chunks.length === 0; }), /** * A read-only property that is true if this stream's buffer is full. */ full: d.gs(function () { return this.maxSize < this.size; }), /** * A read-only property that is true if this stream is currently receiving * data from another stream via pipe(). */ piped: d.gs(function () { return this._source != null; }), /** * Sets this stream's encoding. If an encoding is set, this stream will emit * strings using that encoding. Otherwise, it emits binary objects. * * Valid encodings are "hex", "base64", "utf8", and "utf-8". */ setEncoding: d(function (encoding) { this.encoding = encoding; }), /** * Prevents this stream from emitting data events until resume is called. * Note: This does not prevent writes to this stream. */ pause: d(function () { this.paused = true; }), /** * Resumes emitting data events. */ resume: d(function () { if (this.paused) flushSoon(this); this.paused = false; }), /** * Pipes all data in this stream through to the given destination stream. * By default the destination stream is ended when this one ends. Set the * "end" option to `false` to disable this behavior. * * This function was copied out of node's lib/stream.js and modified for * use in other JavaScript environments. */ pipe: d(function (dest, options) { var source = this; function ondata(chunk) { if (dest.writable && false === dest.write(chunk)) source.pause(); } source.on('data', ondata); function ondrain() { if (source.readable) source.resume(); } dest.on('drain', ondrain); var didOnEnd = false; function onend() { if (didOnEnd) return; didOnEnd = true; dest.end(); } // If the 'end' option is not supplied, dest.end() will be called when // source gets the 'end' or 'close' events. Only dest.end() once. if (!dest._isStdio && (!options || options.end !== false)) source.on('end', onend); // don't leave dangling pipes when there are errors. function onerror(error) { cleanup(); if (EventEmitter.listenerCount(this, 'error') === 0) throw error; // Unhandled stream error in pipe. } source.on('error', onerror); dest.on('error', onerror); // remove all the event listeners that were added. function cleanup() { source.removeListener('data', ondata); dest.removeListener('drain', ondrain); source.removeListener('end', onend); source.removeListener('error', onerror); dest.removeListener('error', onerror); source.removeListener('end', cleanup); } source.on('end', cleanup); dest.on('close', cleanup); dest.emit('pipe', source); // Mimic the behavior of node v2 streams where pipe() resumes the flow. // This lets us avoid having to do stream.resume() all over the place. source.resume(); // Allow for unix-like usage: A.pipe(B).pipe(C) return dest; }), /** * Writes the given chunk of data to this stream. Returns false if this * stream is full and should not be written to further until drained, true * otherwise. */ write: d(function (chunk) { if (!this.writable) throw new Error('BufferedStream is not writable'); if (this.ended) throw new Error('BufferedStream is already ended'); if (typeof chunk === 'string') chunk = bodec.fromString(chunk, arguments[1]); if (!bodec.isBinary(chunk)) throw new Error('BufferedStream only accepts binary data'); this._chunks.push(chunk); this.size += chunk.length; flushSoon(this); if (this.full) { this._wasFull = true; return false; } return true; }), /** * Writes the given chunk to this stream and queues the end event to be * called as soon as soon as the stream is empty. Calling write() after * end() is an error. */ end: d(function (chunk) { if (this.ended) throw new Error('BufferedStream is already ended'); if (chunk != null) this.write(chunk, arguments[1]); this.ended = true; // Trigger the flush cycle one last time to emit // any data that was written before end was called. flushSoon(this); }) }); module.exports = BufferedStream; /***/ }, /* 20 */ /***/ function(module, exports, __webpack_require__) { "use strict"; // This file must be served with UTF-8 encoding for the utf8 codec to work. module.exports = { Binary: Uint8Array, // Utility functions isBinary: isBinary, create: create, join: join, // Binary input and output copy: copy, slice: slice, // String input and output toRaw: toRaw, fromRaw: fromRaw, toUnicode: toUnicode, fromUnicode: fromUnicode, toHex: toHex, fromHex: fromHex, toBase64: toBase64, fromBase64: fromBase64, toString: toString, fromString: fromString, // Array input and output toArray: toArray, fromArray: fromArray, // Raw <-> Hex-encoded codec decodeHex: decodeHex, encodeHex: encodeHex, decodeBase64: decodeBase64, encodeBase64: encodeBase64, // Unicode <-> Utf8-encoded-raw codec encodeUtf8: encodeUtf8, decodeUtf8: decodeUtf8, // Hex <-> Nibble codec nibbleToCode: nibbleToCode, codeToNibble: codeToNibble }; function isBinary(value) { return value && typeof value === "object" && value instanceof Uint8Array || value.constructor.name === "Uint8Array"; } function create(length) { return new Uint8Array(length); } function join(chunks) { var length = chunks.length; var total = 0; for (var i = 0; i < length; i++) { total += chunks[i].length; } var binary = create(total); var offset = 0; for (i = 0; i < length; i++) { var chunk = chunks[i]; copy(chunk, binary, offset); offset += chunk.length; } return binary; } function slice(binary, start, end) { if (end === undefined) { end = binary.length; if (start === undefined) start = 0; } return binary.subarray(start, end); } function copy(source, binary, offset) { var length = source.length; if (offset === undefined) { offset = 0; if (binary === undefined) binary = create(length); } for (var i = 0; i < length; i++) { binary[i + offset] = source[i]; } return binary; } // Like slice, but encode as a hex string function toHex(binary, start, end) { var hex = ""; if (end === undefined) { end = binary.length; if (start === undefined) start = 0; } for (var i = start; i < end; i++) { var byte = binary[i]; hex += String.fromCharCode(nibbleToCode(byte >> 4)) + String.fromCharCode(nibbleToCode(byte & 0xf)); } return hex; } // Like copy, but decode from a hex string function fromHex(hex, binary, offset) { var length = hex.length / 2; if (offset === undefined) { offset = 0; if (binary === undefined) binary = create(length); } var j = 0; for (var i = 0; i < length; i++) { binary[offset + i] = (codeToNibble(hex.charCodeAt(j++)) << 4) | codeToNibble(hex.charCodeAt(j++)); } return binary; } function toBase64(binary, start, end) { return btoa(toRaw(binary, start, end)); } function fromBase64(base64, binary, offset) { return fromRaw(atob(base64), binary, offset); } function nibbleToCode(nibble) { nibble |= 0; return (nibble + (nibble < 10 ? 0x30 : 0x57))|0; } function codeToNibble(code) { code |= 0; return (code - ((code & 0x40) ? 0x57 : 0x30))|0; } function toUnicode(binary, start, end) { return decodeUtf8(toRaw(binary, start, end)); } function fromUnicode(unicode, binary, offset) { return fromRaw(encodeUtf8(unicode), binary, offset); } function decodeHex(hex) { var j = 0, l = hex.length; var raw = ""; while (j < l) { raw += String.fromCharCode( (codeToNibble(hex.charCodeAt(j++)) << 4) | codeToNibble(hex.charCodeAt(j++)) ); } return raw; } function encodeHex(raw) { var hex = ""; var length = raw.length; for (var i = 0; i < length; i++) { var byte = raw.charCodeAt(i); hex += String.fromCharCode(nibbleToCode(byte >> 4)) + String.fromCharCode(nibbleToCode(byte & 0xf)); } return hex; } function decodeBase64(base64) { return atob(base64); } function encodeBase64(raw) { return btoa(raw); } function decodeUtf8(utf8) { return decodeURIComponent(window.escape(utf8)); } function encodeUtf8(unicode) { return window.unescape(encodeURIComponent(unicode)); } function toRaw(binary, start, end) { var raw = ""; if (end === undefined) { end = binary.length; if (start === undefined) start = 0; } for (var i = start; i < end; i++) { raw += String.fromCharCode(binary[i]); } return raw; } function fromRaw(raw, binary, offset) { var length = raw.length; if (offset === undefined) { offset = 0; if (binary === undefined) binary = create(length); } for (var i = 0; i < length; i++) { binary[offset + i] = raw.charCodeAt(i); } return binary; } function toArray(binary, start, end) { if (end === undefined) { end = binary.length; if (start === undefined) start = 0; } var length = end - start; var array = new Array(length); for (var i = 0; i < length; i++) { array[i] = binary[i + start]; } return array; } function fromArray(array, binary, offset) { var length = array.length; if (offset === undefined) { offset = 0; if (binary === undefined) binary = create(length); } for (var i = 0; i < length; i++) { binary[offset + i] = array[i]; } return binary; } var toStringCoders = { base64: toBase64, hex: toHex, utf8: toUnicode, 'utf-8': toUnicode }; function toString(binary, encoding) { return ((encoding && toStringCoders[encoding]) || toStringCoders.utf8)(binary); } var fromStringCoders = { base64: fromBase64, hex: fromHex, utf8: fromUnicode, 'utf-8': fromUnicode }; function fromString(string, encoding) { return ((encoding && fromStringCoders[encoding]) || fromStringCoders.utf8)(string); } /***/ }, /* 21 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * A map of HTTP header names with irregular case. */ module.exports = ["Content-ID", "Content-MD5", "DNT", "ETag", "P3P", "TE", "WWW-Authenticate", "X-ATT-DeviceId", "X-UA-Compatible", "X-WebKit-CSP", "X-XSS-Protection"].reduce(function (map, headerName) { map[headerName.toLowerCase()] = headerName; return map; }, {}); /***/ }, /* 22 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var d = __webpack_require__(18); /** * An error indicating that some maximum length has been exceeded. */ function MaxLengthExceededError(maxLength) { Error.call(this); Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; this.message = "Maximum length exceeded"; this.maxLength = maxLength; } MaxLengthExceededError.prototype = Object.create(Error.prototype, { constructor: d(MaxLengthExceededError) }); module.exports = MaxLengthExceededError; /***/ }, /* 23 */ /***/ function(module, exports, __webpack_require__) { /* (ignored) */ /***/ }, /* 24 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var Connection = __webpack_require__(2); var Promise = __webpack_require__(10); /** * Creates a new Connection using the given options and sends * the request to the given app. Returns a promise for the connection * object when the response is received. * * Options may be any of the Connection options, plus the following: * * - binary By default the response content is buffered and stored * in the responseText property of the connection. Set this * option true to disable this behavior. * - maxLength The maximum length of the response content to accept. * This option has no effect when "binary" is true. By * default there is no maximum length. * - encoding The encoding to use to decode the response body. This * option has no effect when "binary" is true. By default * the encoding is whatever was specified in the Content-Type * header of the response. * * If a modifier function is provided, it will have a chance to modify * the Connection object immediately before the request is made. */ function callApp(app, options, modifier) { options = options || {}; var c = new Connection(options); return Promise.resolve(modifier ? modifier(c) : c).then(function (conn) { if (conn == null || !(conn instanceof Connection)) conn = c; return conn.call(app).then(function () { if (options.binary) return conn; return conn.response.stringifyContent(options.maxLength, options.encoding).then(function (content) { conn.responseText = content; return conn; }); }); }); } module.exports = callApp; /***/ }, /* 25 */ /***/ function(module, exports, __webpack_require__) { module.exports = __webpack_require__(32); /***/ }, /* 26 */ /***/ function(module, exports, __webpack_require__) { // Load modules // Declare internals var internals = {}; exports.arrayToObject = function (source) { var obj = {}; for (var i = 0, il = source.length; i < il; ++i) { if (typeof source[i] !== 'undefined') { obj[i] = source[i]; } } return obj; }; exports.merge = function (target, source) { if (!source) { return target; } if (typeof source !== 'object') { if (Array.isArray(target)) { target.push(source); } else { target[source] = true; } return target; } if (typeof target !== 'object') { target = [target].concat(source); return target; } if (Array.isArray(target) && !Array.isArray(source)) { target = exports.arrayToObject(target); } var keys = Object.keys(source); for (var k = 0, kl = keys.length; k < kl; ++k) { var key = keys[k]; var value = source[key]; if (!target[key]) { target[key] = value; } else { target[key] = exports.merge(target[key], value); } } return target; }; exports.decode = function (str) { try { return decodeURIComponent(str.replace(/\+/g, ' ')); } catch (e) { return str; } }; exports.compact = function (obj, refs) { if (typeof obj !== 'object' || obj === null) { return obj; } refs = refs || []; var lookup = refs.indexOf(obj); if (lookup !== -1) { return refs[lookup]; } refs.push(obj); if (Array.isArray(obj)) { var compacted = []; for (var i = 0, il = obj.length; i < il; ++i) { if (typeof obj[i] !== 'undefined') { comp