Skip to content

Instantly share code, notes, and snippets.

@justrhysism
Last active February 14, 2019 08:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justrhysism/7ad1279eb4e839c97f403861a94c0d3c to your computer and use it in GitHub Desktop.
Save justrhysism/7ad1279eb4e839c97f403861a94c0d3c to your computer and use it in GitHub Desktop.
Pretender v3.0.0 (Browser Ready)
var Pretender = (function () {
'use strict';
// This is just a placeholder for the build step
var createObject = Object.create;
function createMap() {
var map = createObject(null);
map["__"] = undefined;
delete map["__"];
return map;
}
var Target = function Target(path, matcher, delegate) {
this.path = path;
this.matcher = matcher;
this.delegate = delegate;
};
Target.prototype.to = function to (target, callback) {
var delegate = this.delegate;
if (delegate && delegate.willAddRoute) {
target = delegate.willAddRoute(this.matcher.target, target);
}
this.matcher.add(this.path, target);
if (callback) {
if (callback.length === 0) {
throw new Error("You must have an argument in the function passed to `to`");
}
this.matcher.addChild(this.path, target, callback, this.delegate);
}
};
var Matcher = function Matcher(target) {
this.routes = createMap();
this.children = createMap();
this.target = target;
};
Matcher.prototype.add = function add (path, target) {
this.routes[path] = target;
};
Matcher.prototype.addChild = function addChild (path, target, callback, delegate) {
var matcher = new Matcher(target);
this.children[path] = matcher;
var match = generateMatch(path, matcher, delegate);
if (delegate && delegate.contextEntered) {
delegate.contextEntered(target, match);
}
callback(match);
};
function generateMatch(startingPath, matcher, delegate) {
function match(path, callback) {
var fullPath = startingPath + path;
if (callback) {
callback(generateMatch(fullPath, matcher, delegate));
}
else {
return new Target(fullPath, matcher, delegate);
}
}
return match;
}
function addRoute(routeArray, path, handler) {
var len = 0;
for (var i = 0; i < routeArray.length; i++) {
len += routeArray[i].path.length;
}
path = path.substr(len);
var route = { path: path, handler: handler };
routeArray.push(route);
}
function eachRoute(baseRoute, matcher, callback, binding) {
var routes = matcher.routes;
var paths = Object.keys(routes);
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
var routeArray = baseRoute.slice();
addRoute(routeArray, path, routes[path]);
var nested = matcher.children[path];
if (nested) {
eachRoute(routeArray, nested, callback, binding);
}
else {
callback.call(binding, routeArray);
}
}
}
var map = function (callback, addRouteCallback) {
var matcher = new Matcher();
callback(generateMatch("", matcher, this.delegate));
eachRoute([], matcher, function (routes) {
if (addRouteCallback) {
addRouteCallback(this, routes);
}
else {
this.add(routes);
}
}, this);
};
// Normalizes percent-encoded values in `path` to upper-case and decodes percent-encoded
// values that are not reserved (i.e., unicode characters, emoji, etc). The reserved
// chars are "/" and "%".
// Safe to call multiple times on the same path.
// Normalizes percent-encoded values in `path` to upper-case and decodes percent-encoded
function normalizePath(path) {
return path.split("/")
.map(normalizeSegment)
.join("/");
}
// We want to ensure the characters "%" and "/" remain in percent-encoded
// form when normalizing paths, so replace them with their encoded form after
// decoding the rest of the path
var SEGMENT_RESERVED_CHARS = /%|\//g;
function normalizeSegment(segment) {
if (segment.length < 3 || segment.indexOf("%") === -1)
{ return segment; }
return decodeURIComponent(segment).replace(SEGMENT_RESERVED_CHARS, encodeURIComponent);
}
// We do not want to encode these characters when generating dynamic path segments
// See https://tools.ietf.org/html/rfc3986#section-3.3
// sub-delims: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
// others allowed by RFC 3986: ":", "@"
//
// First encode the entire path segment, then decode any of the encoded special chars.
//
// The chars "!", "'", "(", ")", "*" do not get changed by `encodeURIComponent`,
// so the possible encoded chars are:
// ['%24', '%26', '%2B', '%2C', '%3B', '%3D', '%3A', '%40'].
var PATH_SEGMENT_ENCODINGS = /%(?:2(?:4|6|B|C)|3(?:B|D|A)|40)/g;
function encodePathSegment(str) {
return encodeURIComponent(str).replace(PATH_SEGMENT_ENCODINGS, decodeURIComponent);
}
var escapeRegex = /(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\)/g;
var isArray = Array.isArray;
var hasOwnProperty = Object.prototype.hasOwnProperty;
function getParam(params, key) {
if (typeof params !== "object" || params === null) {
throw new Error("You must pass an object as the second argument to `generate`.");
}
if (!hasOwnProperty.call(params, key)) {
throw new Error("You must provide param `" + key + "` to `generate`.");
}
var value = params[key];
var str = typeof value === "string" ? value : "" + value;
if (str.length === 0) {
throw new Error("You must provide a param `" + key + "`.");
}
return str;
}
var eachChar = [];
eachChar[0 /* Static */] = function (segment, currentState) {
var state = currentState;
var value = segment.value;
for (var i = 0; i < value.length; i++) {
var ch = value.charCodeAt(i);
state = state.put(ch, false, false);
}
return state;
};
eachChar[1 /* Dynamic */] = function (_, currentState) {
return currentState.put(47 /* SLASH */, true, true);
};
eachChar[2 /* Star */] = function (_, currentState) {
return currentState.put(-1 /* ANY */, false, true);
};
eachChar[4 /* Epsilon */] = function (_, currentState) {
return currentState;
};
var regex = [];
regex[0 /* Static */] = function (segment) {
return segment.value.replace(escapeRegex, "\\$1");
};
regex[1 /* Dynamic */] = function () {
return "([^/]+)";
};
regex[2 /* Star */] = function () {
return "(.+)";
};
regex[4 /* Epsilon */] = function () {
return "";
};
var generate = [];
generate[0 /* Static */] = function (segment) {
return segment.value;
};
generate[1 /* Dynamic */] = function (segment, params) {
var value = getParam(params, segment.value);
if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) {
return encodePathSegment(value);
}
else {
return value;
}
};
generate[2 /* Star */] = function (segment, params) {
return getParam(params, segment.value);
};
generate[4 /* Epsilon */] = function () {
return "";
};
var EmptyObject = Object.freeze({});
var EmptyArray = Object.freeze([]);
// The `names` will be populated with the paramter name for each dynamic/star
// segment. `shouldDecodes` will be populated with a boolean for each dyanamic/star
// segment, indicating whether it should be decoded during recognition.
function parse(segments, route, types) {
// normalize route as not starting with a "/". Recognition will
// also normalize.
if (route.length > 0 && route.charCodeAt(0) === 47 /* SLASH */) {
route = route.substr(1);
}
var parts = route.split("/");
var names = undefined;
var shouldDecodes = undefined;
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
var flags = 0;
var type = 0;
if (part === "") {
type = 4 /* Epsilon */;
}
else if (part.charCodeAt(0) === 58 /* COLON */) {
type = 1 /* Dynamic */;
}
else if (part.charCodeAt(0) === 42 /* STAR */) {
type = 2 /* Star */;
}
else {
type = 0 /* Static */;
}
flags = 2 << type;
if (flags & 12 /* Named */) {
part = part.slice(1);
names = names || [];
names.push(part);
shouldDecodes = shouldDecodes || [];
shouldDecodes.push((flags & 4 /* Decoded */) !== 0);
}
if (flags & 14 /* Counted */) {
types[type]++;
}
segments.push({
type: type,
value: normalizeSegment(part)
});
}
return {
names: names || EmptyArray,
shouldDecodes: shouldDecodes || EmptyArray,
};
}
function isEqualCharSpec(spec, char, negate) {
return spec.char === char && spec.negate === negate;
}
// A State has a character specification and (`charSpec`) and a list of possible
// subsequent states (`nextStates`).
//
// If a State is an accepting state, it will also have several additional
// properties:
//
// * `regex`: A regular expression that is used to extract parameters from paths
// that reached this accepting state.
// * `handlers`: Information on how to convert the list of captures into calls
// to registered handlers with the specified parameters
// * `types`: How many static, dynamic or star segments in this route. Used to
// decide which route to use if multiple registered routes match a path.
//
// Currently, State is implemented naively by looping over `nextStates` and
// comparing a character specification against a character. A more efficient
// implementation would use a hash of keys pointing at one or more next states.
var State = function State(states, id, char, negate, repeat) {
this.states = states;
this.id = id;
this.char = char;
this.negate = negate;
this.nextStates = repeat ? id : null;
this.pattern = "";
this._regex = undefined;
this.handlers = undefined;
this.types = undefined;
};
State.prototype.regex = function regex$1 () {
if (!this._regex) {
this._regex = new RegExp(this.pattern);
}
return this._regex;
};
State.prototype.get = function get (char, negate) {
var this$1 = this;
var nextStates = this.nextStates;
if (nextStates === null)
{ return; }
if (isArray(nextStates)) {
for (var i = 0; i < nextStates.length; i++) {
var child = this$1.states[nextStates[i]];
if (isEqualCharSpec(child, char, negate)) {
return child;
}
}
}
else {
var child$1 = this.states[nextStates];
if (isEqualCharSpec(child$1, char, negate)) {
return child$1;
}
}
};
State.prototype.put = function put (char, negate, repeat) {
var state;
// If the character specification already exists in a child of the current
// state, just return that state.
if (state = this.get(char, negate)) {
return state;
}
// Make a new state for the character spec
var states = this.states;
state = new State(states, states.length, char, negate, repeat);
states[states.length] = state;
// Insert the new state as a child of the current state
if (this.nextStates == null) {
this.nextStates = state.id;
}
else if (isArray(this.nextStates)) {
this.nextStates.push(state.id);
}
else {
this.nextStates = [this.nextStates, state.id];
}
// Return the new state
return state;
};
// Find a list of child states matching the next character
State.prototype.match = function match (ch) {
var this$1 = this;
var nextStates = this.nextStates;
if (!nextStates)
{ return []; }
var returned = [];
if (isArray(nextStates)) {
for (var i = 0; i < nextStates.length; i++) {
var child = this$1.states[nextStates[i]];
if (isMatch(child, ch)) {
returned.push(child);
}
}
}
else {
var child$1 = this.states[nextStates];
if (isMatch(child$1, ch)) {
returned.push(child$1);
}
}
return returned;
};
function isMatch(spec, char) {
return spec.negate ? spec.char !== char && spec.char !== -1 /* ANY */ : spec.char === char || spec.char === -1 /* ANY */;
}
// This is a somewhat naive strategy, but should work in a lot of cases
// A better strategy would properly resolve /posts/:id/new and /posts/edit/:id.
//
// This strategy generally prefers more static and less dynamic matching.
// Specifically, it
//
// * prefers fewer stars to more, then
// * prefers using stars for less of the match to more, then
// * prefers fewer dynamic segments to more, then
// * prefers more static segments to more
function sortSolutions(states) {
return states.sort(function (a, b) {
var ref = a.types || [0, 0, 0];
var astatics = ref[0];
var adynamics = ref[1];
var astars = ref[2];
var ref$1 = b.types || [0, 0, 0];
var bstatics = ref$1[0];
var bdynamics = ref$1[1];
var bstars = ref$1[2];
if (astars !== bstars) {
return astars - bstars;
}
if (astars) {
if (astatics !== bstatics) {
return bstatics - astatics;
}
if (adynamics !== bdynamics) {
return bdynamics - adynamics;
}
}
if (adynamics !== bdynamics) {
return adynamics - bdynamics;
}
if (astatics !== bstatics) {
return bstatics - astatics;
}
return 0;
});
}
function recognizeChar(states, ch) {
var nextStates = [];
for (var i = 0, l = states.length; i < l; i++) {
var state = states[i];
nextStates = nextStates.concat(state.match(ch));
}
return nextStates;
}
var RecognizeResults = function RecognizeResults(queryParams) {
this.length = 0;
this.queryParams = queryParams || {};
};
RecognizeResults.prototype.splice = Array.prototype.splice;
RecognizeResults.prototype.slice = Array.prototype.slice;
RecognizeResults.prototype.push = Array.prototype.push;
function findHandler(state, originalPath, queryParams) {
var handlers = state.handlers;
var regex = state.regex();
if (!regex || !handlers)
{ throw new Error("state not initialized"); }
var captures = originalPath.match(regex);
var currentCapture = 1;
var result = new RecognizeResults(queryParams);
result.length = handlers.length;
for (var i = 0; i < handlers.length; i++) {
var handler = handlers[i];
var names = handler.names;
var shouldDecodes = handler.shouldDecodes;
var params = EmptyObject;
var isDynamic = false;
if (names !== EmptyArray && shouldDecodes !== EmptyArray) {
for (var j = 0; j < names.length; j++) {
isDynamic = true;
var name = names[j];
var capture = captures && captures[currentCapture++];
if (params === EmptyObject) {
params = {};
}
if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS && shouldDecodes[j]) {
params[name] = capture && decodeURIComponent(capture);
}
else {
params[name] = capture;
}
}
}
result[i] = {
handler: handler.handler,
params: params,
isDynamic: isDynamic
};
}
return result;
}
function decodeQueryParamPart(part) {
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
part = part.replace(/\+/gm, "%20");
var result;
try {
result = decodeURIComponent(part);
}
catch (error) {
result = "";
}
return result;
}
var RouteRecognizer = function RouteRecognizer() {
this.names = createMap();
var states = [];
var state = new State(states, 0, -1 /* ANY */, true, false);
states[0] = state;
this.states = states;
this.rootState = state;
};
RouteRecognizer.prototype.add = function add (routes, options) {
var currentState = this.rootState;
var pattern = "^";
var types = [0, 0, 0];
var handlers = new Array(routes.length);
var allSegments = [];
var isEmpty = true;
var j = 0;
for (var i = 0; i < routes.length; i++) {
var route = routes[i];
var ref = parse(allSegments, route.path, types);
var names = ref.names;
var shouldDecodes = ref.shouldDecodes;
// preserve j so it points to the start of newly added segments
for (; j < allSegments.length; j++) {
var segment = allSegments[j];
if (segment.type === 4 /* Epsilon */) {
continue;
}
isEmpty = false;
// Add a "/" for the new segment
currentState = currentState.put(47 /* SLASH */, false, false);
pattern += "/";
// Add a representation of the segment to the NFA and regex
currentState = eachChar[segment.type](segment, currentState);
pattern += regex[segment.type](segment);
}
handlers[i] = {
handler: route.handler,
names: names,
shouldDecodes: shouldDecodes
};
}
if (isEmpty) {
currentState = currentState.put(47 /* SLASH */, false, false);
pattern += "/";
}
currentState.handlers = handlers;
currentState.pattern = pattern + "$";
currentState.types = types;
var name;
if (typeof options === "object" && options !== null && options.as) {
name = options.as;
}
if (name) {
// if (this.names[name]) {
// throw new Error("You may not add a duplicate route named `" + name + "`.");
// }
this.names[name] = {
segments: allSegments,
handlers: handlers
};
}
};
RouteRecognizer.prototype.handlersFor = function handlersFor (name) {
var route = this.names[name];
if (!route) {
throw new Error("There is no route named " + name);
}
var result = new Array(route.handlers.length);
for (var i = 0; i < route.handlers.length; i++) {
var handler = route.handlers[i];
result[i] = handler;
}
return result;
};
RouteRecognizer.prototype.hasRoute = function hasRoute (name) {
return !!this.names[name];
};
RouteRecognizer.prototype.generate = function generate$1 (name, params) {
var route = this.names[name];
var output = "";
if (!route) {
throw new Error("There is no route named " + name);
}
var segments = route.segments;
for (var i = 0; i < segments.length; i++) {
var segment = segments[i];
if (segment.type === 4 /* Epsilon */) {
continue;
}
output += "/";
output += generate[segment.type](segment, params);
}
if (output.charAt(0) !== "/") {
output = "/" + output;
}
if (params && params.queryParams) {
output += this.generateQueryString(params.queryParams);
}
return output;
};
RouteRecognizer.prototype.generateQueryString = function generateQueryString (params) {
var pairs = [];
var keys = Object.keys(params);
keys.sort();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = params[key];
if (value == null) {
continue;
}
var pair = encodeURIComponent(key);
if (isArray(value)) {
for (var j = 0; j < value.length; j++) {
var arrayPair = key + "[]" + "=" + encodeURIComponent(value[j]);
pairs.push(arrayPair);
}
}
else {
pair += "=" + encodeURIComponent(value);
pairs.push(pair);
}
}
if (pairs.length === 0) {
return "";
}
return "?" + pairs.join("&");
};
RouteRecognizer.prototype.parseQueryString = function parseQueryString (queryString) {
var pairs = queryString.split("&");
var queryParams = {};
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("="), key = decodeQueryParamPart(pair[0]), keyLength = key.length, isArray = false, value = (void 0);
if (pair.length === 1) {
value = "true";
}
else {
// Handle arrays
if (keyLength > 2 && key.slice(keyLength - 2) === "[]") {
isArray = true;
key = key.slice(0, keyLength - 2);
if (!queryParams[key]) {
queryParams[key] = [];
}
}
value = pair[1] ? decodeQueryParamPart(pair[1]) : "";
}
if (isArray) {
queryParams[key].push(value);
}
else {
queryParams[key] = value;
}
}
return queryParams;
};
RouteRecognizer.prototype.recognize = function recognize (path) {
var results;
var states = [this.rootState];
var queryParams = {};
var isSlashDropped = false;
var hashStart = path.indexOf("#");
if (hashStart !== -1) {
path = path.substr(0, hashStart);
}
var queryStart = path.indexOf("?");
if (queryStart !== -1) {
var queryString = path.substr(queryStart + 1, path.length);
path = path.substr(0, queryStart);
queryParams = this.parseQueryString(queryString);
}
if (path.charAt(0) !== "/") {
path = "/" + path;
}
var originalPath = path;
if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) {
path = normalizePath(path);
}
else {
path = decodeURI(path);
originalPath = decodeURI(originalPath);
}
var pathLen = path.length;
if (pathLen > 1 && path.charAt(pathLen - 1) === "/") {
path = path.substr(0, pathLen - 1);
originalPath = originalPath.substr(0, originalPath.length - 1);
isSlashDropped = true;
}
for (var i = 0; i < path.length; i++) {
states = recognizeChar(states, path.charCodeAt(i));
if (!states.length) {
break;
}
}
var solutions = [];
for (var i$1 = 0; i$1 < states.length; i$1++) {
if (states[i$1].handlers) {
solutions.push(states[i$1]);
}
}
states = sortSolutions(solutions);
var state = solutions[0];
if (state && state.handlers) {
// if a trailing slash was dropped and a star segment is the last segment
// specified, put the trailing slash back
if (isSlashDropped && state.pattern && state.pattern.slice(-5) === "(.+)$") {
originalPath = originalPath + "/";
}
results = findHandler(state, originalPath, queryParams);
}
return results;
};
RouteRecognizer.VERSION = "0.3.4";
// Set to false to opt-out of encoding and decoding path segments.
// See https://github.com/tildeio/route-recognizer/pull/55
RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS = true;
RouteRecognizer.Normalizer = {
normalizeSegment: normalizeSegment, normalizePath: normalizePath, encodePathSegment: encodePathSegment
};
RouteRecognizer.prototype.map = map;
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var fake_xml_http_request = createCommonjsModule(function (module, exports) {
(function (global, factory) {
module.exports = factory();
}(commonjsGlobal, function () {
/**
* Minimal Event interface implementation
*
* Original implementation by Sven Fuchs: https://gist.github.com/995028
* Modifications and tests by Christian Johansen.
*
* @author Sven Fuchs (svenfuchs@artweb-design.de)
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2011 Sven Fuchs, Christian Johansen
*/
var _Event = function Event(type, bubbles, cancelable, target) {
this.type = type;
this.bubbles = bubbles;
this.cancelable = cancelable;
this.target = target;
};
_Event.prototype = {
stopPropagation: function () {},
preventDefault: function () {
this.defaultPrevented = true;
}
};
/*
Used to set the statusText property of an xhr object
*/
var httpStatusCodes = {
100: "Continue",
101: "Switching Protocols",
200: "OK",
201: "Created",
202: "Accepted",
203: "Non-Authoritative Information",
204: "No Content",
205: "Reset Content",
206: "Partial Content",
300: "Multiple Choice",
301: "Moved Permanently",
302: "Found",
303: "See Other",
304: "Not Modified",
305: "Use Proxy",
307: "Temporary Redirect",
400: "Bad Request",
401: "Unauthorized",
402: "Payment Required",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
407: "Proxy Authentication Required",
408: "Request Timeout",
409: "Conflict",
410: "Gone",
411: "Length Required",
412: "Precondition Failed",
413: "Request Entity Too Large",
414: "Request-URI Too Long",
415: "Unsupported Media Type",
416: "Requested Range Not Satisfiable",
417: "Expectation Failed",
422: "Unprocessable Entity",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout",
505: "HTTP Version Not Supported"
};
/*
Cross-browser XML parsing. Used to turn
XML responses into Document objects
Borrowed from JSpec
*/
function parseXML(text) {
var xmlDoc;
if (typeof DOMParser != "undefined") {
var parser = new DOMParser();
xmlDoc = parser.parseFromString(text, "text/xml");
} else {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(text);
}
return xmlDoc;
}
/*
Without mocking, the native XMLHttpRequest object will throw
an error when attempting to set these headers. We match this behavior.
*/
var unsafeHeaders = {
"Accept-Charset": true,
"Accept-Encoding": true,
"Connection": true,
"Content-Length": true,
"Cookie": true,
"Cookie2": true,
"Content-Transfer-Encoding": true,
"Date": true,
"Expect": true,
"Host": true,
"Keep-Alive": true,
"Referer": true,
"TE": true,
"Trailer": true,
"Transfer-Encoding": true,
"Upgrade": true,
"User-Agent": true,
"Via": true
};
/*
Adds an "event" onto the fake xhr object
that just calls the same-named method. This is
in case a library adds callbacks for these events.
*/
function _addEventListener(eventName, xhr){
xhr.addEventListener(eventName, function (event) {
var listener = xhr["on" + eventName];
if (listener && typeof listener == "function") {
listener.call(event.target, event);
}
});
}
function EventedObject() {
this._eventListeners = {};
var events = ["loadstart", "progress", "load", "abort", "loadend"];
for (var i = events.length - 1; i >= 0; i--) {
_addEventListener(events[i], this);
}
}
EventedObject.prototype = {
/*
Duplicates the behavior of native XMLHttpRequest's addEventListener function
*/
addEventListener: function addEventListener(event, listener) {
this._eventListeners[event] = this._eventListeners[event] || [];
this._eventListeners[event].push(listener);
},
/*
Duplicates the behavior of native XMLHttpRequest's removeEventListener function
*/
removeEventListener: function removeEventListener(event, listener) {
var listeners = this._eventListeners[event] || [];
for (var i = 0, l = listeners.length; i < l; ++i) {
if (listeners[i] == listener) {
return listeners.splice(i, 1);
}
}
},
/*
Duplicates the behavior of native XMLHttpRequest's dispatchEvent function
*/
dispatchEvent: function dispatchEvent(event) {
var type = event.type;
var listeners = this._eventListeners[type] || [];
for (var i = 0; i < listeners.length; i++) {
if (typeof listeners[i] == "function") {
listeners[i].call(this, event);
} else {
listeners[i].handleEvent(event);
}
}
return !!event.defaultPrevented;
},
/*
Triggers an `onprogress` event with the given parameters.
*/
_progress: function _progress(lengthComputable, loaded, total) {
var event = new _Event('progress');
event.target = this;
event.lengthComputable = lengthComputable;
event.loaded = loaded;
event.total = total;
this.dispatchEvent(event);
}
};
/*
Constructor for a fake window.XMLHttpRequest
*/
function FakeXMLHttpRequest() {
EventedObject.call(this);
this.readyState = FakeXMLHttpRequest.UNSENT;
this.requestHeaders = {};
this.requestBody = null;
this.status = 0;
this.statusText = "";
this.upload = new EventedObject();
}
FakeXMLHttpRequest.prototype = new EventedObject();
// These status codes are available on the native XMLHttpRequest
// object, so we match that here in case a library is relying on them.
FakeXMLHttpRequest.UNSENT = 0;
FakeXMLHttpRequest.OPENED = 1;
FakeXMLHttpRequest.HEADERS_RECEIVED = 2;
FakeXMLHttpRequest.LOADING = 3;
FakeXMLHttpRequest.DONE = 4;
var FakeXMLHttpRequestProto = {
UNSENT: 0,
OPENED: 1,
HEADERS_RECEIVED: 2,
LOADING: 3,
DONE: 4,
async: true,
withCredentials: false,
/*
Duplicates the behavior of native XMLHttpRequest's open function
*/
open: function open(method, url, async, username, password) {
this.method = method;
this.url = url;
this.async = typeof async == "boolean" ? async : true;
this.username = username;
this.password = password;
this.responseText = null;
this.responseXML = null;
this.requestHeaders = {};
this.sendFlag = false;
this._readyStateChange(FakeXMLHttpRequest.OPENED);
},
/*
Duplicates the behavior of native XMLHttpRequest's setRequestHeader function
*/
setRequestHeader: function setRequestHeader(header, value) {
verifyState(this);
if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
throw new Error("Refused to set unsafe header \"" + header + "\"");
}
if (this.requestHeaders[header]) {
this.requestHeaders[header] += "," + value;
} else {
this.requestHeaders[header] = value;
}
},
/*
Duplicates the behavior of native XMLHttpRequest's send function
*/
send: function send(data) {
verifyState(this);
if (!/^(get|head)$/i.test(this.method)) {
var hasContentTypeHeader = false;
Object.keys(this.requestHeaders).forEach(function (key) {
if (key.toLowerCase() === 'content-type') {
hasContentTypeHeader = true;
}
});
if (!hasContentTypeHeader && !(data || '').toString().match('FormData')) {
this.requestHeaders["Content-Type"] = "text/plain;charset=UTF-8";
}
this.requestBody = data;
}
this.errorFlag = false;
this.sendFlag = this.async;
this._readyStateChange(FakeXMLHttpRequest.OPENED);
if (typeof this.onSend == "function") {
this.onSend(this);
}
this.dispatchEvent(new _Event("loadstart", false, false, this));
},
/*
Duplicates the behavior of native XMLHttpRequest's abort function
*/
abort: function abort() {
this.aborted = true;
this.responseText = null;
this.errorFlag = true;
this.requestHeaders = {};
if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag) {
this._readyStateChange(FakeXMLHttpRequest.DONE);
this.sendFlag = false;
}
this.readyState = FakeXMLHttpRequest.UNSENT;
this.dispatchEvent(new _Event("abort", false, false, this));
if (typeof this.onerror === "function") {
this.onerror();
}
},
/*
Duplicates the behavior of native XMLHttpRequest's getResponseHeader function
*/
getResponseHeader: function getResponseHeader(header) {
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
return null;
}
if (/^Set-Cookie2?$/i.test(header)) {
return null;
}
header = header.toLowerCase();
for (var h in this.responseHeaders) {
if (h.toLowerCase() == header) {
return this.responseHeaders[h];
}
}
return null;
},
/*
Duplicates the behavior of native XMLHttpRequest's getAllResponseHeaders function
*/
getAllResponseHeaders: function getAllResponseHeaders() {
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
return "";
}
var headers = "";
for (var header in this.responseHeaders) {
if (this.responseHeaders.hasOwnProperty(header) && !/^Set-Cookie2?$/i.test(header)) {
headers += header + ": " + this.responseHeaders[header] + "\r\n";
}
}
return headers;
},
/*
Duplicates the behavior of native XMLHttpRequest's overrideMimeType function
*/
overrideMimeType: function overrideMimeType(mimeType) {
if (typeof mimeType === "string") {
this.forceMimeType = mimeType.toLowerCase();
}
},
/*
Places a FakeXMLHttpRequest object into the passed
state.
*/
_readyStateChange: function _readyStateChange(state) {
this.readyState = state;
if (typeof this.onreadystatechange == "function") {
this.onreadystatechange(new _Event("readystatechange"));
}
this.dispatchEvent(new _Event("readystatechange"));
if (this.readyState == FakeXMLHttpRequest.DONE) {
this.dispatchEvent(new _Event("load", false, false, this));
this.dispatchEvent(new _Event("loadend", false, false, this));
}
},
/*
Sets the FakeXMLHttpRequest object's response headers and
places the object into readyState 2
*/
_setResponseHeaders: function _setResponseHeaders(headers) {
this.responseHeaders = {};
for (var header in headers) {
if (headers.hasOwnProperty(header)) {
this.responseHeaders[header] = headers[header];
}
}
if (this.forceMimeType) {
this.responseHeaders['Content-Type'] = this.forceMimeType;
}
if (this.async) {
this._readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
} else {
this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
}
},
/*
Sets the FakeXMLHttpRequest object's response body and
if body text is XML, sets responseXML to parsed document
object
*/
_setResponseBody: function _setResponseBody(body) {
verifyRequestSent(this);
verifyHeadersReceived(this);
verifyResponseBodyType(body);
var chunkSize = this.chunkSize || 10;
var index = 0;
this.responseText = "";
do {
if (this.async) {
this._readyStateChange(FakeXMLHttpRequest.LOADING);
}
this.responseText += body.substring(index, index + chunkSize);
index += chunkSize;
} while (index < body.length);
var type = this.getResponseHeader("Content-Type");
if (this.responseText && (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
try {
this.responseXML = parseXML(this.responseText);
} catch (e) {
// Unable to parse XML - no biggie
}
}
if (this.async) {
this._readyStateChange(FakeXMLHttpRequest.DONE);
} else {
this.readyState = FakeXMLHttpRequest.DONE;
}
},
/*
Forces a response on to the FakeXMLHttpRequest object.
This is the public API for faking responses. This function
takes a number status, headers object, and string body:
```
xhr.respond(404, {Content-Type: 'text/plain'}, "Sorry. This object was not found.")
```
*/
respond: function respond(status, headers, body) {
this._setResponseHeaders(headers || {});
this.status = typeof status == "number" ? status : 200;
this.statusText = httpStatusCodes[this.status];
this._setResponseBody(body || "");
}
};
for (var property in FakeXMLHttpRequestProto) {
FakeXMLHttpRequest.prototype[property] = FakeXMLHttpRequestProto[property];
}
function verifyState(xhr) {
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
throw new Error("INVALID_STATE_ERR");
}
if (xhr.sendFlag) {
throw new Error("INVALID_STATE_ERR");
}
}
function verifyRequestSent(xhr) {
if (xhr.readyState == FakeXMLHttpRequest.DONE) {
throw new Error("Request done");
}
}
function verifyHeadersReceived(xhr) {
if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
throw new Error("No headers received");
}
}
function verifyResponseBodyType(body) {
if (typeof body != "string") {
var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
body + ", which is not a string.");
error.name = "InvalidBodyException";
throw error;
}
}
var fake_xml_http_request = FakeXMLHttpRequest;
return fake_xml_http_request;
}));
});
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
};
function isDataView(obj) {
return obj && DataView.prototype.isPrototypeOf(obj)
}
if (support.arrayBuffer) {
var viewClasses = [
'[object Int8Array]',
'[object Uint8Array]',
'[object Uint8ClampedArray]',
'[object Int16Array]',
'[object Uint16Array]',
'[object Int32Array]',
'[object Uint32Array]',
'[object Float32Array]',
'[object Float64Array]'
];
var isArrayBufferView =
ArrayBuffer.isView ||
function(obj) {
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
};
}
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()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = String(value);
}
return value
}
// 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}
}
};
if (support.iterable) {
iterator[Symbol.iterator] = function() {
return iterator
};
}
return iterator
}
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);
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name);
value = normalizeValue(value);
var oldValue = this.map[name];
this.map[name] = oldValue ? oldValue + ', ' + value : value;
};
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)];
};
Headers.prototype.get = function(name) {
name = normalizeName(name);
return this.has(name) ? this.map[name] : null
};
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
};
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = normalizeValue(value);
};
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);
}
}
};
Headers.prototype.keys = function() {
var items = [];
this.forEach(function(value, name) {
items.push(name);
});
return iteratorFor(items)
};
Headers.prototype.values = function() {
var items = [];
this.forEach(function(value) {
items.push(value);
});
return iteratorFor(items)
};
Headers.prototype.entries = function() {
var items = [];
this.forEach(function(value, name) {
items.push([name, value]);
});
return iteratorFor(items)
};
if (support.iterable) {
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true;
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result);
};
reader.onerror = function() {
reject(reader.error);
};
})
}
function readBlobAsArrayBuffer(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsArrayBuffer(blob);
return promise
}
function readBlobAsText(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsText(blob);
return promise
}
function readArrayBufferAsText(buf) {
var view = new Uint8Array(buf);
var chars = new Array(view.length);
for (var i = 0; i < view.length; i++) {
chars[i] = String.fromCharCode(view[i]);
}
return chars.join('')
}
function bufferClone(buf) {
if (buf.slice) {
return buf.slice(0)
} else {
var view = new Uint8Array(buf.byteLength);
view.set(new Uint8Array(buf));
return view.buffer
}
}
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 {
this._bodyText = body = Object.prototype.toString.call(body);
}
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');
}
}
};
if (support.blob) {
this.blob = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
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]))
}
};
this.arrayBuffer = function() {
if (this._bodyArrayBuffer) {
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
} else {
return this.blob().then(readBlobAsArrayBuffer)
}
};
}
this.text = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
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)
}
};
if (support.formData) {
this.formData = function() {
return this.text().then(decode)
};
}
this.json = function() {
return this.text().then(JSON.parse)
};
return this
}
// HTTP methods whose capitalization should be normalized
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
function normalizeMethod(method) {
var upcased = method.toUpperCase();
return methods.indexOf(upcased) > -1 ? upcased : method
}
function Request(input, options) {
options = options || {};
var body = options.body;
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;
this.signal = input.signal;
if (!body && input._bodyInit != null) {
body = input._bodyInit;
input.bodyUsed = true;
}
} else {
this.url = String(input);
}
this.credentials = options.credentials || this.credentials || 'same-origin';
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.signal = options.signal || this.signal;
this.referrer = null;
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
throw new TypeError('Body not allowed for GET or HEAD requests')
}
this._initBody(body);
}
Request.prototype.clone = function() {
return new Request(this, {body: this._bodyInit})
};
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 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
}
Body.call(Request.prototype);
function Response(bodyInit, options) {
if (!options) {
options = {};
}
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);
}
Body.call(Response.prototype);
Response.prototype.clone = function() {
return new Response(this._bodyInit, {
status: this.status,
statusText: this.statusText,
headers: new Headers(this.headers),
url: this.url
})
};
Response.error = function() {
var response = new Response(null, {status: 0, statusText: ''});
response.type = 'error';
return response
};
var redirectStatuses = [301, 302, 303, 307, 308];
Response.redirect = function(url, status) {
if (redirectStatuses.indexOf(status) === -1) {
throw new RangeError('Invalid status code')
}
return new Response(null, {status: status, headers: {location: url}})
};
var DOMException = self.DOMException;
try {
new DOMException();
} catch (err) {
DOMException = function(message, name) {
this.message = message;
this.name = name;
var error = Error(message);
this.stack = error.stack;
};
DOMException.prototype = Object.create(Error.prototype);
DOMException.prototype.constructor = DOMException;
}
function fetch(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init);
if (request.signal && request.signal.aborted) {
return reject(new DOMException('Aborted', 'AbortError'))
}
var xhr = new XMLHttpRequest();
function abortXhr() {
xhr.abort();
}
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));
};
xhr.onerror = function() {
reject(new TypeError('Network request failed'));
};
xhr.ontimeout = function() {
reject(new TypeError('Network request failed'));
};
xhr.onabort = function() {
reject(new DOMException('Aborted', 'AbortError'));
};
xhr.open(request.method, request.url, true);
if (request.credentials === 'include') {
xhr.withCredentials = true;
} else if (request.credentials === 'omit') {
xhr.withCredentials = false;
}
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob';
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value);
});
if (request.signal) {
request.signal.addEventListener('abort', abortXhr);
xhr.onreadystatechange = function() {
// DONE (success or failure)
if (xhr.readyState === 4) {
request.signal.removeEventListener('abort', abortXhr);
}
};
}
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
})
}
fetch.polyfill = true;
if (!self.fetch) {
self.fetch = fetch;
self.Headers = Headers;
self.Request = Request;
self.Response = Response;
}
var FakeFetch = /*#__PURE__*/Object.freeze({
Headers: Headers,
Request: Request,
Response: Response,
get DOMException () { return DOMException; },
fetch: fetch
});
/**
* parseURL - decompose a URL into its parts
* @param {String} url a URL
* @return {Object} parts of the URL, including the following
*
* 'https://www.yahoo.com:1234/mypage?test=yes#abc'
*
* {
* host: 'www.yahoo.com:1234',
* protocol: 'https:',
* search: '?test=yes',
* hash: '#abc',
* href: 'https://www.yahoo.com:1234/mypage?test=yes#abc',
* pathname: '/mypage',
* fullpath: '/mypage?test=yes'
* }
*/
function parseURL(url) {
// TODO: something for when document isn't present... #yolo
var anchor = document.createElement('a');
anchor.href = url;
if (!anchor.host) {
anchor.href = anchor.href; // IE: load the host and protocol
}
var pathname = anchor.pathname;
if (pathname.charAt(0) !== '/') {
pathname = '/' + pathname; // IE: prepend leading slash
}
var host = anchor.host;
if (anchor.port === '80' || anchor.port === '443') {
host = anchor.hostname; // IE: remove default port
}
return {
host: host,
protocol: anchor.protocol,
search: anchor.search,
hash: anchor.hash,
href: anchor.href,
pathname: pathname,
fullpath: pathname + (anchor.search || '') + (anchor.hash || '')
};
}
/**
* Registry
*
* A registry is a map of HTTP verbs to route recognizers.
*/
function Registry( /* host */) {
// Herein we keep track of RouteRecognizer instances
// keyed by HTTP method. Feel free to add more as needed.
this.verbs = {
GET: new RouteRecognizer(),
PUT: new RouteRecognizer(),
POST: new RouteRecognizer(),
DELETE: new RouteRecognizer(),
PATCH: new RouteRecognizer(),
HEAD: new RouteRecognizer(),
OPTIONS: new RouteRecognizer()
};
}
/**
* Hosts
*
* a map of hosts to Registries, ultimately allowing
* a per-host-and-port, per HTTP verb lookup of RouteRecognizers
*/
function Hosts() {
this._registries = {};
}
/**
* Hosts#forURL - retrieve a map of HTTP verbs to RouteRecognizers
* for a given URL
*
* @param {String} url a URL
* @return {Registry} a map of HTTP verbs to RouteRecognizers
* corresponding to the provided URL's
* hostname and port
*/
Hosts.prototype.forURL = function (url) {
var host = parseURL(url).host;
var registry = this._registries[host];
if (registry === undefined) {
registry = (this._registries[host] = new Registry(host));
}
return registry.verbs;
};
function Pretender( /* routeMap1, routeMap2, ..., options*/) {
this.hosts = new Hosts();
var lastArg = arguments[arguments.length - 1];
var options = typeof lastArg === 'object' ? lastArg : null;
var shouldNotTrack = options && (options.trackRequests === false);
var noopArray = { push: function () { }, length: 0 };
this.handlers = [];
this.handledRequests = shouldNotTrack ? noopArray : [];
this.passthroughRequests = shouldNotTrack ? noopArray : [];
this.unhandledRequests = shouldNotTrack ? noopArray : [];
this.requestReferences = [];
this.forcePassthrough = options && (options.forcePassthrough === true);
this.disableUnhandled = options && (options.disableUnhandled === true);
// reference the native XMLHttpRequest object so
// it can be restored later
this._nativeXMLHttpRequest = window.XMLHttpRequest;
this.running = false;
var ctx = { pretender: this };
this.ctx = ctx;
// capture xhr requests, channeling them into
// the route map.
window.XMLHttpRequest = interceptor(ctx);
// polyfill fetch when xhr is ready
this._fetchProps = FakeFetch ? ['fetch', 'Headers', 'Request', 'Response'] : [];
this._fetchProps.forEach(function (name) {
this['_native' + name] = window[name];
window[name] = FakeFetch[name];
}, this);
// 'start' the server
this.running = true;
// trigger the route map DSL.
var argLength = options ? arguments.length - 1 : arguments.length;
for (var i = 0; i < argLength; i++) {
this.map(arguments[i]);
}
}
function interceptor(ctx) {
function FakeRequest() {
// super()
fake_xml_http_request.call(this);
}
FakeRequest.prototype = Object.create(fake_xml_http_request.prototype);
FakeRequest.prototype.constructor = FakeRequest;
// extend
FakeRequest.prototype.send = function send() {
if (!ctx.pretender.running) {
throw new Error('You shut down a Pretender instance while there was a pending request. ' +
'That request just tried to complete. Check to see if you accidentally shut down ' +
'a pretender earlier than you intended to');
}
fake_xml_http_request.prototype.send.apply(this, arguments);
if (ctx.pretender.checkPassthrough(this)) {
var xhr = createPassthrough(this);
xhr.send.apply(xhr, arguments);
}
else {
ctx.pretender.handleRequest(this);
}
};
function createPassthrough(fakeXHR) {
// event types to handle on the xhr
var evts = ['error', 'timeout', 'abort', 'readystatechange'];
// event types to handle on the xhr.upload
var uploadEvents = [];
// properties to copy from the native xhr to fake xhr
var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText'];
var xhr = fakeXHR._passthroughRequest = new ctx.pretender._nativeXMLHttpRequest();
xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password);
if (fakeXHR.responseType === 'arraybuffer') {
lifecycleProps = ['readyState', 'response', 'status', 'statusText'];
xhr.responseType = fakeXHR.responseType;
}
// use onload if the browser supports it
if ('onload' in xhr) {
evts.push('load');
}
// add progress event for async calls
// avoid using progress events for sync calls, they will hang https://bugs.webkit.org/show_bug.cgi?id=40996.
if (fakeXHR.async && fakeXHR.responseType !== 'arraybuffer') {
evts.push('progress');
uploadEvents.push('progress');
}
// update `propertyNames` properties from `fromXHR` to `toXHR`
function copyLifecycleProperties(propertyNames, fromXHR, toXHR) {
for (var i = 0; i < propertyNames.length; i++) {
var prop = propertyNames[i];
if (prop in fromXHR) {
toXHR[prop] = fromXHR[prop];
}
}
}
// fire fake event on `eventable`
function dispatchEvent(eventable, eventType, event) {
eventable.dispatchEvent(event);
if (eventable['on' + eventType]) {
eventable['on' + eventType](event);
}
}
// set the on- handler on the native xhr for the given eventType
function createHandler(eventType) {
xhr['on' + eventType] = function (event) {
copyLifecycleProperties(lifecycleProps, xhr, fakeXHR);
dispatchEvent(fakeXHR, eventType, event);
};
}
// set the on- handler on the native xhr's `upload` property for
// the given eventType
function createUploadHandler(eventType) {
if (xhr.upload) {
xhr.upload['on' + eventType] = function (event) {
dispatchEvent(fakeXHR.upload, eventType, event);
};
}
}
var i;
for (i = 0; i < evts.length; i++) {
createHandler(evts[i]);
}
for (i = 0; i < uploadEvents.length; i++) {
createUploadHandler(uploadEvents[i]);
}
if (fakeXHR.async) {
xhr.timeout = fakeXHR.timeout;
xhr.withCredentials = fakeXHR.withCredentials;
}
for (var h in fakeXHR.requestHeaders) {
xhr.setRequestHeader(h, fakeXHR.requestHeaders[h]);
}
return xhr;
}
FakeRequest.prototype._passthroughCheck = function (method, args) {
if (this._passthroughRequest) {
return this._passthroughRequest[method].apply(this._passthroughRequest, args);
}
return fake_xml_http_request.prototype[method].apply(this, args);
};
FakeRequest.prototype.abort = function abort() {
return this._passthroughCheck('abort', arguments);
};
FakeRequest.prototype.getResponseHeader = function getResponseHeader() {
return this._passthroughCheck('getResponseHeader', arguments);
};
FakeRequest.prototype.getAllResponseHeaders = function getAllResponseHeaders() {
return this._passthroughCheck('getAllResponseHeaders', arguments);
};
if (ctx.pretender._nativeXMLHttpRequest.prototype._passthroughCheck) {
console.warn('You created a second Pretender instance while there was already one running. ' +
'Running two Pretender servers at once will lead to unexpected results and will ' +
'be removed entirely in a future major version.' +
'Please call .shutdown() on your instances when you no longer need them to respond.');
}
return FakeRequest;
}
function verbify(verb) {
return function (path, handler, async) {
return this.register(verb, path, handler, async);
};
}
function scheduleProgressEvent(request, startTime, totalTime) {
setTimeout(function () {
if (!request.aborted && !request.status) {
var ellapsedTime = new Date().getTime() - startTime.getTime();
request.upload._progress(true, ellapsedTime, totalTime);
request._progress(true, ellapsedTime, totalTime);
scheduleProgressEvent(request, startTime, totalTime);
}
}, 50);
}
function isArray$1(array) {
return Object.prototype.toString.call(array) === '[object Array]';
}
var PASSTHROUGH = {};
Pretender.prototype = {
get: verbify('GET'),
post: verbify('POST'),
put: verbify('PUT'),
'delete': verbify('DELETE'),
patch: verbify('PATCH'),
head: verbify('HEAD'),
options: verbify('OPTIONS'),
map: function (maps) {
maps.call(this);
},
register: function register(verb, url, handler, async) {
if (!handler) {
throw new Error('The function you tried passing to Pretender to handle ' +
verb + ' ' + url + ' is undefined or missing.');
}
handler.numberOfCalls = 0;
handler.async = async;
this.handlers.push(handler);
var registry = this.hosts.forURL(url)[verb];
registry.add([{
path: parseURL(url).fullpath,
handler: handler
}]);
return handler;
},
passthrough: PASSTHROUGH,
checkPassthrough: function checkPassthrough(request) {
var verb = request.method.toUpperCase();
var path = parseURL(request.url).fullpath;
var recognized = this.hosts.forURL(request.url)[verb].recognize(path);
var match = recognized && recognized[0];
if ((match && match.handler === PASSTHROUGH) || this.forcePassthrough) {
this.passthroughRequests.push(request);
this.passthroughRequest(verb, path, request);
return true;
}
return false;
},
handleRequest: function handleRequest(request) {
var verb = request.method.toUpperCase();
var path = request.url;
var handler = this._handlerFor(verb, path, request);
if (handler) {
handler.handler.numberOfCalls++;
var async = handler.handler.async;
this.handledRequests.push(request);
var pretender = this;
var _handleRequest = function (statusHeadersAndBody) {
if (!isArray$1(statusHeadersAndBody)) {
var note = 'Remember to `return [status, headers, body];` in your route handler.';
throw new Error('Nothing returned by handler for ' + path + '. ' + note);
}
var status = statusHeadersAndBody[0], headers = pretender.prepareHeaders(statusHeadersAndBody[1]), body = pretender.prepareBody(statusHeadersAndBody[2], headers);
pretender.handleResponse(request, async, function () {
request.respond(status, headers, body);
pretender.handledRequest(verb, path, request);
});
};
try {
var result = handler.handler(request);
if (result && typeof result.then === 'function') {
// `result` is a promise, resolve it
result.then(function (resolvedResult) {
_handleRequest(resolvedResult);
});
}
else {
_handleRequest(result);
}
}
catch (error) {
this.erroredRequest(verb, path, request, error);
this.resolve(request);
}
}
else {
if (!this.disableUnhandled) {
this.unhandledRequests.push(request);
this.unhandledRequest(verb, path, request);
}
}
},
handleResponse: function handleResponse(request, strategy, callback) {
var delay = typeof strategy === 'function' ? strategy() : strategy;
delay = typeof delay === 'boolean' || typeof delay === 'number' ? delay : 0;
if (delay === false) {
callback();
}
else {
var pretender = this;
pretender.requestReferences.push({
request: request,
callback: callback
});
if (delay !== true) {
scheduleProgressEvent(request, new Date(), delay);
setTimeout(function () {
pretender.resolve(request);
}, delay);
}
}
},
resolve: function resolve(request) {
for (var i = 0, len = this.requestReferences.length; i < len; i++) {
var res = this.requestReferences[i];
if (res.request === request) {
res.callback();
this.requestReferences.splice(i, 1);
break;
}
}
},
requiresManualResolution: function (verb, path) {
var handler = this._handlerFor(verb.toUpperCase(), path, {});
if (!handler) {
return false;
}
var async = handler.handler.async;
return typeof async === 'function' ? async() === true : async === true;
},
prepareBody: function (body) { return body; },
prepareHeaders: function (headers) { return headers; },
handledRequest: function ( /* verb, path, request */) { },
passthroughRequest: function ( /* verb, path, request */) { },
unhandledRequest: function (verb, path /*, request */) {
throw new Error('Pretender intercepted ' + verb + ' ' +
path + ' but no handler was defined for this type of request');
},
erroredRequest: function (verb, path, request, error) {
error.message = 'Pretender intercepted ' + verb + ' ' +
path + ' but encountered an error: ' + error.message;
throw error;
},
_handlerFor: function (verb, url, request) {
var registry = this.hosts.forURL(url)[verb];
var matches = registry.recognize(parseURL(url).fullpath);
var match = matches ? matches[0] : null;
if (match) {
request.params = match.params;
request.queryParams = matches.queryParams;
}
return match;
},
shutdown: function shutdown() {
window.XMLHttpRequest = this._nativeXMLHttpRequest;
this._fetchProps.forEach(function (name) {
window[name] = this['_native' + name];
}, this);
this.ctx.pretender = undefined;
// 'stop' the server
this.running = false;
}
};
Pretender.parseURL = parseURL;
Pretender.Hosts = Hosts;
Pretender.Registry = Registry;
return Pretender;
}());
var Pretender=function(){"use strict";var t=Object.create;function r(){var e=t(null);return e.__=void 0,delete e.__,e}var i=function(e,t,r){this.path=e,this.matcher=t,this.delegate=r};i.prototype.to=function(e,t){var r=this.delegate;if(r&&r.willAddRoute&&(e=r.willAddRoute(this.matcher.target,e)),this.matcher.add(this.path,e),t){if(0===t.length)throw new Error("You must have an argument in the function passed to `to`");this.matcher.addChild(this.path,e,t,this.delegate)}};var a=function(e){this.routes=r(),this.children=r(),this.target=e};function h(n,s,o){return function(e,t){var r=n+e;if(!t)return new i(r,s,o);t(h(r,s,o))}}function p(e,t,r){for(var n=0,s=0;s<e.length;s++)n+=e[s].path.length;var o={path:t=t.substr(n),handler:r};e.push(o)}a.prototype.add=function(e,t){this.routes[e]=t},a.prototype.addChild=function(e,t,r,n){var s=new a(t),o=h(e,this.children[e]=s,n);n&&n.contextEntered&&n.contextEntered(t,o),r(o)};function l(e){return e.split("/").map(d).join("/")}var n=/%|\//g;function d(e){return e.length<3||-1===e.indexOf("%")?e:decodeURIComponent(e).replace(n,encodeURIComponent)}var s=/%(?:2(?:4|6|B|C)|3(?:B|D|A)|40)/g;function o(e){return encodeURIComponent(e).replace(s,decodeURIComponent)}var u=/(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\)/g,c=Array.isArray,f=Object.prototype.hasOwnProperty;function y(e,t){if("object"!=typeof e||null===e)throw new Error("You must pass an object as the second argument to `generate`.");if(!f.call(e,t))throw new Error("You must provide param `"+t+"` to `generate`.");var r=e[t],n="string"==typeof r?r:""+r;if(0===n.length)throw new Error("You must provide a param `"+t+"`.");return n}var v=[];v[0]=function(e,t){for(var r=t,n=e.value,s=0;s<n.length;s++){var o=n.charCodeAt(s);r=r.put(o,!1,!1)}return r},v[1]=function(e,t){return t.put(47,!0,!0)},v[2]=function(e,t){return t.put(-1,!1,!0)},v[4]=function(e,t){return t};var g=[];g[0]=function(e){return e.value.replace(u,"\\$1")},g[1]=function(){return"([^/]+)"},g[2]=function(){return"(.+)"},g[4]=function(){return""};var E=[];E[0]=function(e){return e.value},E[1]=function(e,t){var r=y(t,e.value);return D.ENCODE_AND_DECODE_PATH_SEGMENTS?o(r):r},E[2]=function(e,t){return y(t,e.value)},E[4]=function(){return""};var m=Object.freeze({}),w=Object.freeze([]);function b(e,t,r){0<t.length&&47===t.charCodeAt(0)&&(t=t.substr(1));for(var n=t.split("/"),s=void 0,o=void 0,i=0;i<n.length;i++){var a,h=n[i],u=0;12&(a=2<<(u=""===h?4:58===h.charCodeAt(0)?1:42===h.charCodeAt(0)?2:0))&&(h=h.slice(1),(s=s||[]).push(h),(o=o||[]).push(0!=(4&a))),14&a&&r[u]++,e.push({type:u,value:d(h)})}return{names:s||w,shouldDecodes:o||w}}function R(e,t,r){return e.char===t&&e.negate===r}var _=function(e,t,r,n,s){this.states=e,this.id=t,this.char=r,this.negate=n,this.nextStates=s?t:null,this.pattern="",this._regex=void 0,this.handlers=void 0,this.types=void 0};function T(e,t){return e.negate?e.char!==t&&-1!==e.char:e.char===t||-1===e.char}function A(e,t){for(var r=[],n=0,s=e.length;n<s;n++){var o=e[n];r=r.concat(o.match(t))}return r}_.prototype.regex=function(){return this._regex||(this._regex=new RegExp(this.pattern)),this._regex},_.prototype.get=function(e,t){var r=this.nextStates;if(null!==r)if(c(r))for(var n=0;n<r.length;n++){var s=this.states[r[n]];if(R(s,e,t))return s}else{var o=this.states[r];if(R(o,e,t))return o}},_.prototype.put=function(e,t,r){var n;if(n=this.get(e,t))return n;var s=this.states;return n=new _(s,s.length,e,t,r),s[s.length]=n,null==this.nextStates?this.nextStates=n.id:c(this.nextStates)?this.nextStates.push(n.id):this.nextStates=[this.nextStates,n.id],n},_.prototype.match=function(e){var t=this.nextStates;if(!t)return[];var r=[];if(c(t))for(var n=0;n<t.length;n++){var s=this.states[t[n]];T(s,e)&&r.push(s)}else{var o=this.states[t];T(o,e)&&r.push(o)}return r};var S=function(e){this.length=0,this.queryParams=e||{}};function C(e){var t;e=e.replace(/\+/gm,"%20");try{t=decodeURIComponent(e)}catch(e){t=""}return t}S.prototype.splice=Array.prototype.splice,S.prototype.slice=Array.prototype.slice,S.prototype.push=Array.prototype.push;var D=function(){this.names=r();var e=[],t=new _(e,0,-1,!0,!1);e[0]=t,this.states=e,this.rootState=t};D.prototype.add=function(e,t){for(var r,n=this.rootState,s="^",o=[0,0,0],i=new Array(e.length),a=[],h=!0,u=0,d=0;d<e.length;d++){for(var p=e[d],c=b(a,p.path,o),f=c.names,l=c.shouldDecodes;u<a.length;u++){var y=a[u];4!==y.type&&(h=!1,n=n.put(47,!1,!1),s+="/",n=v[y.type](y,n),s+=g[y.type](y))}i[d]={handler:p.handler,names:f,shouldDecodes:l}}h&&(n=n.put(47,!1,!1),s+="/"),n.handlers=i,n.pattern=s+"$",n.types=o,"object"==typeof t&&null!==t&&t.as&&(r=t.as),r&&(this.names[r]={segments:a,handlers:i})},D.prototype.handlersFor=function(e){var t=this.names[e];if(!t)throw new Error("There is no route named "+e);for(var r=new Array(t.handlers.length),n=0;n<t.handlers.length;n++){var s=t.handlers[n];r[n]=s}return r},D.prototype.hasRoute=function(e){return!!this.names[e]},D.prototype.generate=function(e,t){var r=this.names[e],n="";if(!r)throw new Error("There is no route named "+e);for(var s=r.segments,o=0;o<s.length;o++){var i=s[o];4!==i.type&&(n+="/",n+=E[i.type](i,t))}return"/"!==n.charAt(0)&&(n="/"+n),t&&t.queryParams&&(n+=this.generateQueryString(t.queryParams)),n},D.prototype.generateQueryString=function(e){var t=[],r=Object.keys(e);r.sort();for(var n=0;n<r.length;n++){var s=r[n],o=e[s];if(null!=o){var i=encodeURIComponent(s);if(c(o))for(var a=0;a<o.length;a++){var h=s+"[]="+encodeURIComponent(o[a]);t.push(h)}else i+="="+encodeURIComponent(o),t.push(i)}}return 0===t.length?"":"?"+t.join("&")},D.prototype.parseQueryString=function(e){for(var t=e.split("&"),r={},n=0;n<t.length;n++){var s=t[n].split("="),o=C(s[0]),i=o.length,a=!1,h=void 0;h=1===s.length?"true":(2<i&&"[]"===o.slice(i-2)&&(a=!0,r[o=o.slice(0,i-2)]||(r[o]=[])),s[1]?C(s[1]):""),a?r[o].push(h):r[o]=h}return r},D.prototype.recognize=function(e){var t,r=[this.rootState],n={},s=!1,o=e.indexOf("#");-1!==o&&(e=e.substr(0,o));var i=e.indexOf("?");if(-1!==i){var a=e.substr(i+1,e.length);e=e.substr(0,i),n=this.parseQueryString(a)}"/"!==e.charAt(0)&&(e="/"+e);var h=e;D.ENCODE_AND_DECODE_PATH_SEGMENTS?e=l(e):(e=decodeURI(e),h=decodeURI(h));var u=e.length;1<u&&"/"===e.charAt(u-1)&&(e=e.substr(0,u-1),h=h.substr(0,h.length-1),s=!0);for(var d=0;d<e.length&&(r=A(r,e.charCodeAt(d))).length;d++);for(var p=[],c=0;c<r.length;c++)r[c].handlers&&p.push(r[c]);r=p.sort(function(e,t){var r=e.types||[0,0,0],n=r[0],s=r[1],o=r[2],i=t.types||[0,0,0],a=i[0],h=i[1],u=i[2];if(o!==u)return o-u;if(o){if(n!==a)return a-n;if(s!==h)return h-s}return s!==h?s-h:n!==a?a-n:0});var f=p[0];return f&&f.handlers&&(s&&f.pattern&&"(.+)$"===f.pattern.slice(-5)&&(h+="/"),t=function(e,t,r){var n=e.handlers,s=e.regex();if(!s||!n)throw new Error("state not initialized");var o=t.match(s),i=1,a=new S(r);a.length=n.length;for(var h=0;h<n.length;h++){var u=n[h],d=u.names,p=u.shouldDecodes,c=m,f=!1;if(d!==w&&p!==w)for(var l=0;l<d.length;l++){f=!0;var y=d[l],v=o&&o[i++];c===m&&(c={}),D.ENCODE_AND_DECODE_PATH_SEGMENTS&&p[l]?c[y]=v&&decodeURIComponent(v):c[y]=v}a[h]={handler:u.handler,params:c,isDynamic:f}}return a}(f,h,n)),t},D.VERSION="0.3.4",D.ENCODE_AND_DECODE_PATH_SEGMENTS=!0,D.Normalizer={normalizeSegment:d,normalizePath:l,encodePathSegment:o},D.prototype.map=function(e,t){var r=new a;e(h("",r,this.delegate)),function e(t,r,n,s){for(var o=r.routes,i=Object.keys(o),a=0;a<i.length;a++){var h=i[a],u=t.slice();p(u,h,o[h]);var d=r.children[h];d?e(u,d,n,s):n.call(s,u)}}([],r,function(e){t?t(this,e):this.add(e)},this)};"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e,P=(function(e,t){e.exports=function(){var s=function(e,t,r,n){this.type=e,this.bubbles=t,this.cancelable=r,this.target=n};s.prototype={stopPropagation:function(){},preventDefault:function(){this.defaultPrevented=!0}};var n={100:"Continue",101:"Switching Protocols",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",300:"Multiple Choice",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported"},r={"Accept-Charset":!0,"Accept-Encoding":!0,Connection:!0,"Content-Length":!0,Cookie:!0,Cookie2:!0,"Content-Transfer-Encoding":!0,Date:!0,Expect:!0,Host:!0,"Keep-Alive":!0,Referer:!0,TE:!0,Trailer:!0,"Transfer-Encoding":!0,Upgrade:!0,"User-Agent":!0,Via:!0};function o(r,n){n.addEventListener(r,function(e){var t=n["on"+r];t&&"function"==typeof t&&t.call(e.target,e)})}function e(){this._eventListeners={};for(var e=["loadstart","progress","load","abort","loadend"],t=e.length-1;0<=t;t--)o(e[t],this)}function i(){e.call(this),this.readyState=i.UNSENT,this.requestHeaders={},this.requestBody=null,this.status=0,this.statusText="",this.upload=new e}e.prototype={addEventListener:function(e,t){this._eventListeners[e]=this._eventListeners[e]||[],this._eventListeners[e].push(t)},removeEventListener:function(e,t){for(var r=this._eventListeners[e]||[],n=0,s=r.length;n<s;++n)if(r[n]==t)return r.splice(n,1)},dispatchEvent:function(e){for(var t=e.type,r=this._eventListeners[t]||[],n=0;n<r.length;n++)"function"==typeof r[n]?r[n].call(this,e):r[n].handleEvent(e);return!!e.defaultPrevented},_progress:function(e,t,r){var n=new s("progress");n.target=this,n.lengthComputable=e,n.loaded=t,n.total=r,this.dispatchEvent(n)}},i.prototype=new e;var t={UNSENT:i.UNSENT=0,OPENED:i.OPENED=1,HEADERS_RECEIVED:i.HEADERS_RECEIVED=2,LOADING:i.LOADING=3,DONE:i.DONE=4,async:!0,withCredentials:!1,open:function(e,t,r,n,s){this.method=e,this.url=t,this.async="boolean"!=typeof r||r,this.username=n,this.password=s,this.responseText=null,this.responseXML=null,this.requestHeaders={},this.sendFlag=!1,this._readyStateChange(i.OPENED)},setRequestHeader:function(e,t){if(h(this),r[e]||/^(Sec-|Proxy-)/.test(e))throw new Error('Refused to set unsafe header "'+e+'"');this.requestHeaders[e]?this.requestHeaders[e]+=","+t:this.requestHeaders[e]=t},send:function(e){if(h(this),!/^(get|head)$/i.test(this.method)){var t=!1;Object.keys(this.requestHeaders).forEach(function(e){"content-type"===e.toLowerCase()&&(t=!0)}),t||(e||"").toString().match("FormData")||(this.requestHeaders["Content-Type"]="text/plain;charset=UTF-8"),this.requestBody=e}this.errorFlag=!1,this.sendFlag=this.async,this._readyStateChange(i.OPENED),"function"==typeof this.onSend&&this.onSend(this),this.dispatchEvent(new s("loadstart",!1,!1,this))},abort:function(){this.aborted=!0,this.responseText=null,this.errorFlag=!0,this.requestHeaders={},this.readyState>i.UNSENT&&this.sendFlag&&(this._readyStateChange(i.DONE),this.sendFlag=!1),this.readyState=i.UNSENT,this.dispatchEvent(new s("abort",!1,!1,this)),"function"==typeof this.onerror&&this.onerror()},getResponseHeader:function(e){if(this.readyState<i.HEADERS_RECEIVED)return null;if(/^Set-Cookie2?$/i.test(e))return null;for(var t in e=e.toLowerCase(),this.responseHeaders)if(t.toLowerCase()==e)return this.responseHeaders[t];return null},getAllResponseHeaders:function(){if(this.readyState<i.HEADERS_RECEIVED)return"";var e="";for(var t in this.responseHeaders)this.responseHeaders.hasOwnProperty(t)&&!/^Set-Cookie2?$/i.test(t)&&(e+=t+": "+this.responseHeaders[t]+"\r\n");return e},overrideMimeType:function(e){"string"==typeof e&&(this.forceMimeType=e.toLowerCase())},_readyStateChange:function(e){this.readyState=e,"function"==typeof this.onreadystatechange&&this.onreadystatechange(new s("readystatechange")),this.dispatchEvent(new s("readystatechange")),this.readyState==i.DONE&&(this.dispatchEvent(new s("load",!1,!1,this)),this.dispatchEvent(new s("loadend",!1,!1,this)))},_setResponseHeaders:function(e){for(var t in this.responseHeaders={},e)e.hasOwnProperty(t)&&(this.responseHeaders[t]=e[t]);this.forceMimeType&&(this.responseHeaders["Content-Type"]=this.forceMimeType),this.async?this._readyStateChange(i.HEADERS_RECEIVED):this.readyState=i.HEADERS_RECEIVED},_setResponseBody:function(e){!function(e){if(e.readyState==i.DONE)throw new Error("Request done")}(this),function(e){if(e.async&&e.readyState!=i.HEADERS_RECEIVED)throw new Error("No headers received")}(this),function(e){if("string"!=typeof e){var t=new Error("Attempted to respond to fake XMLHttpRequest with "+e+", which is not a string.");throw t.name="InvalidBodyException",t}}(e);var t=this.chunkSize||10,r=0;for(this.responseText="";this.async&&this._readyStateChange(i.LOADING),this.responseText+=e.substring(r,r+t),(r+=t)<e.length;);var n=this.getResponseHeader("Content-Type");if(this.responseText&&(!n||/(text\/xml)|(application\/xml)|(\+xml)/.test(n)))try{this.responseXML=function(e){var t;if("undefined"!=typeof DOMParser){var r=new DOMParser;t=r.parseFromString(e,"text/xml")}else(t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e);return t}(this.responseText)}catch(e){}this.async?this._readyStateChange(i.DONE):this.readyState=i.DONE},respond:function(e,t,r){this._setResponseHeaders(t||{}),this.status="number"==typeof e?e:200,this.statusText=n[this.status],this._setResponseBody(r||"")}};for(var a in t)i.prototype[a]=t[a];function h(e){if(e.readyState!==i.OPENED)throw new Error("INVALID_STATE_ERR");if(e.sendFlag)throw new Error("INVALID_STATE_ERR")}return i}()}(e={exports:{}},e.exports),e.exports),x="URLSearchParams"in self,q="Symbol"in self&&"iterator"in Symbol,O="FileReader"in self&&"Blob"in self&&function(){try{return new Blob,!0}catch(e){return!1}}(),H="FormData"in self,U="ArrayBuffer"in self;if(U)var N=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],L=ArrayBuffer.isView||function(e){return e&&-1<N.indexOf(Object.prototype.toString.call(e))};function I(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function B(e){return"string"!=typeof e&&(e=String(e)),e}function j(t){var e={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return q&&(e[Symbol.iterator]=function(){return e}),e}function F(t){this.map={},t instanceof F?t.forEach(function(e,t){this.append(t,e)},this):Array.isArray(t)?t.forEach(function(e){this.append(e[0],e[1])},this):t&&Object.getOwnPropertyNames(t).forEach(function(e){this.append(e,t[e])},this)}function M(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function k(r){return new Promise(function(e,t){r.onload=function(){e(r.result)},r.onerror=function(){t(r.error)}})}function G(e){var t=new FileReader,r=k(t);return t.readAsArrayBuffer(e),r}function X(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function V(){return this.bodyUsed=!1,this._initBody=function(e){var t;(this._bodyInit=e)?"string"==typeof e?this._bodyText=e:O&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:H&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:x&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():U&&O&&((t=e)&&DataView.prototype.isPrototypeOf(t))?(this._bodyArrayBuffer=X(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):U&&(ArrayBuffer.prototype.isPrototypeOf(e)||L(e))?this._bodyArrayBuffer=X(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):x&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},O&&(this.blob=function(){var e=M(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?M(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(G)}),this.text=function(){var e,t,r,n=M(this);if(n)return n;if(this._bodyBlob)return e=this._bodyBlob,t=new FileReader,r=k(t),t.readAsText(e),r;if(this._bodyArrayBuffer)return Promise.resolve(function(e){for(var t=new Uint8Array(e),r=new Array(t.length),n=0;n<t.length;n++)r[n]=String.fromCharCode(t[n]);return r.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},H&&(this.formData=function(){return this.text().then(Y)}),this.json=function(){return this.text().then(JSON.parse)},this}F.prototype.append=function(e,t){e=I(e),t=B(t);var r=this.map[e];this.map[e]=r?r+", "+t:t},F.prototype.delete=function(e){delete this.map[I(e)]},F.prototype.get=function(e){return e=I(e),this.has(e)?this.map[e]:null},F.prototype.has=function(e){return this.map.hasOwnProperty(I(e))},F.prototype.set=function(e,t){this.map[I(e)]=B(t)},F.prototype.forEach=function(e,t){for(var r in this.map)this.map.hasOwnProperty(r)&&e.call(t,this.map[r],r,this)},F.prototype.keys=function(){var r=[];return this.forEach(function(e,t){r.push(t)}),j(r)},F.prototype.values=function(){var t=[];return this.forEach(function(e){t.push(e)}),j(t)},F.prototype.entries=function(){var r=[];return this.forEach(function(e,t){r.push([t,e])}),j(r)},q&&(F.prototype[Symbol.iterator]=F.prototype.entries);var z=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];function $(e,t){var r,n,s=(t=t||{}).body;if(e instanceof $){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new F(e.headers)),this.method=e.method,this.mode=e.mode,this.signal=e.signal,s||null==e._bodyInit||(s=e._bodyInit,e.bodyUsed=!0)}else this.url=String(e);if(this.credentials=t.credentials||this.credentials||"same-origin",!t.headers&&this.headers||(this.headers=new F(t.headers)),this.method=(r=t.method||this.method||"GET",n=r.toUpperCase(),-1<z.indexOf(n)?n:r),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&s)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(s)}function Y(e){var s=new FormData;return e.trim().split("&").forEach(function(e){if(e){var t=e.split("="),r=t.shift().replace(/\+/g," "),n=t.join("=").replace(/\+/g," ");s.append(decodeURIComponent(r),decodeURIComponent(n))}}),s}function Q(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=200<=this.status&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new F(t.headers),this.url=t.url||"",this._initBody(e)}$.prototype.clone=function(){return new $(this,{body:this._bodyInit})},V.call($.prototype),V.call(Q.prototype),Q.prototype.clone=function(){return new Q(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new F(this.headers),url:this.url})},Q.error=function(){var e=new Q(null,{status:0,statusText:""});return e.type="error",e};var K=[301,302,303,307,308];Q.redirect=function(e,t){if(-1===K.indexOf(t))throw new RangeError("Invalid status code");return new Q(null,{status:t,headers:{location:e}})};var J=self.DOMException;try{new J}catch(e){(J=function(e,t){this.message=e,this.name=t;var r=Error(e);this.stack=r.stack}).prototype=Object.create(Error.prototype),J.prototype.constructor=J}function W(s,i){return new Promise(function(n,e){var t=new $(s,i);if(t.signal&&t.signal.aborted)return e(new J("Aborted","AbortError"));var o=new XMLHttpRequest;function r(){o.abort()}o.onload=function(){var e,s,t={status:o.status,statusText:o.statusText,headers:(e=o.getAllResponseHeaders()||"",s=new F,e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach(function(e){var t=e.split(":"),r=t.shift().trim();if(r){var n=t.join(":").trim();s.append(r,n)}}),s)};t.url="responseURL"in o?o.responseURL:t.headers.get("X-Request-URL");var r="response"in o?o.response:o.responseText;n(new Q(r,t))},o.onerror=function(){e(new TypeError("Network request failed"))},o.ontimeout=function(){e(new TypeError("Network request failed"))},o.onabort=function(){e(new J("Aborted","AbortError"))},o.open(t.method,t.url,!0),"include"===t.credentials?o.withCredentials=!0:"omit"===t.credentials&&(o.withCredentials=!1),"responseType"in o&&O&&(o.responseType="blob"),t.headers.forEach(function(e,t){o.setRequestHeader(t,e)}),t.signal&&(t.signal.addEventListener("abort",r),o.onreadystatechange=function(){4===o.readyState&&t.signal.removeEventListener("abort",r)}),o.send(void 0===t._bodyInit?null:t._bodyInit)})}W.polyfill=!0,self.fetch||(self.fetch=W,self.Headers=F,self.Request=$,self.Response=Q);var Z=Object.freeze({Headers:F,Request:$,Response:Q,get DOMException(){return J},fetch:W});function ee(e){var t=document.createElement("a");t.href=e,t.host||(t.href=t.href);var r=t.pathname;"/"!==r.charAt(0)&&(r="/"+r);var n=t.host;return"80"!==t.port&&"443"!==t.port||(n=t.hostname),{host:n,protocol:t.protocol,search:t.search,hash:t.hash,href:t.href,pathname:r,fullpath:r+(t.search||"")+(t.hash||"")}}function te(){this.verbs={GET:new D,PUT:new D,POST:new D,DELETE:new D,PATCH:new D,HEAD:new D,OPTIONS:new D}}function re(){this._registries={}}function ne(){this.hosts=new re;var e=arguments[arguments.length-1],t="object"==typeof e?e:null,r=t&&!1===t.trackRequests,n={push:function(){},length:0};this.handlers=[],this.handledRequests=r?n:[],this.passthroughRequests=r?n:[],this.unhandledRequests=r?n:[],this.requestReferences=[],this.forcePassthrough=t&&!0===t.forcePassthrough,this.disableUnhandled=t&&!0===t.disableUnhandled,this._nativeXMLHttpRequest=window.XMLHttpRequest,this.running=!1;var s={pretender:this};this.ctx=s,window.XMLHttpRequest=function(d){function e(){P.call(this)}((e.prototype=Object.create(P.prototype)).constructor=e).prototype.send=function(){if(!d.pretender.running)throw new Error("You shut down a Pretender instance while there was a pending request. That request just tried to complete. Check to see if you accidentally shut down a pretender earlier than you intended to");if(P.prototype.send.apply(this,arguments),d.pretender.checkPassthrough(this)){var e=function(r){var e,t=["error","timeout","abort","readystatechange"],n=[],s=["readyState","responseText","responseXML","status","statusText"],o=r._passthroughRequest=new d.pretender._nativeXMLHttpRequest;function i(e,t,r){e.dispatchEvent(r),e["on"+t]&&e["on"+t](r)}function a(t){o["on"+t]=function(e){!function(e,t,r){for(var n=0;n<e.length;n++){var s=e[n];s in t&&(r[s]=t[s])}}(s,o,r),i(r,t,e)}}function h(t){o.upload&&(o.upload["on"+t]=function(e){i(r.upload,t,e)})}o.open(r.method,r.url,r.async,r.username,r.password),"arraybuffer"===r.responseType&&(s=["readyState","response","status","statusText"],o.responseType=r.responseType),"onload"in o&&t.push("load"),r.async&&"arraybuffer"!==r.responseType&&(t.push("progress"),n.push("progress"));for(e=0;e<t.length;e++)a(t[e]);for(e=0;e<n.length;e++)h(n[e]);for(var u in r.async&&(o.timeout=r.timeout,o.withCredentials=r.withCredentials),r.requestHeaders)o.setRequestHeader(u,r.requestHeaders[u]);return o}(this);e.send.apply(e,arguments)}else d.pretender.handleRequest(this)},e.prototype._passthroughCheck=function(e,t){return this._passthroughRequest?this._passthroughRequest[e].apply(this._passthroughRequest,t):P.prototype[e].apply(this,t)},e.prototype.abort=function(){return this._passthroughCheck("abort",arguments)},e.prototype.getResponseHeader=function(){return this._passthroughCheck("getResponseHeader",arguments)},e.prototype.getAllResponseHeaders=function(){return this._passthroughCheck("getAllResponseHeaders",arguments)},d.pretender._nativeXMLHttpRequest.prototype._passthroughCheck&&console.warn("You created a second Pretender instance while there was already one running. Running two Pretender servers at once will lead to unexpected results and will be removed entirely in a future major version.Please call .shutdown() on your instances when you no longer need them to respond.");return e}(s),this._fetchProps=Z?["fetch","Headers","Request","Response"]:[],this._fetchProps.forEach(function(e){this["_native"+e]=window[e],window[e]=Z[e]},this),this.running=!0;for(var o=t?arguments.length-1:arguments.length,i=0;i<o;i++)this.map(arguments[i])}function se(n){return function(e,t,r){return this.register(n,e,t,r)}}re.prototype.forURL=function(e){var t=ee(e).host,r=this._registries[t];return void 0===r&&(r=this._registries[t]=new te(t)),r.verbs};var oe={};return ne.prototype={get:se("GET"),post:se("POST"),put:se("PUT"),delete:se("DELETE"),patch:se("PATCH"),head:se("HEAD"),options:se("OPTIONS"),map:function(e){e.call(this)},register:function(e,t,r,n){if(!r)throw new Error("The function you tried passing to Pretender to handle "+e+" "+t+" is undefined or missing.");return r.numberOfCalls=0,r.async=n,this.handlers.push(r),this.hosts.forURL(t)[e].add([{path:ee(t).fullpath,handler:r}]),r},passthrough:oe,checkPassthrough:function(e){var t=e.method.toUpperCase(),r=ee(e.url).fullpath,n=this.hosts.forURL(e.url)[t].recognize(r),s=n&&n[0];return!!(s&&s.handler===oe||this.forcePassthrough)&&(this.passthroughRequests.push(e),this.passthroughRequest(t,r,e),!0)},handleRequest:function(o){var i=o.method.toUpperCase(),a=o.url,e=this._handlerFor(i,a,o);if(e){e.handler.numberOfCalls++;var h=e.handler.async;this.handledRequests.push(o);var u=this,t=function(e){if(t=e,"[object Array]"!==Object.prototype.toString.call(t)){throw new Error("Nothing returned by handler for "+a+". Remember to `return [status, headers, body];` in your route handler.")}var t,r=e[0],n=u.prepareHeaders(e[1]),s=u.prepareBody(e[2],n);u.handleResponse(o,h,function(){o.respond(r,n,s),u.handledRequest(i,a,o)})};try{var r=e.handler(o);r&&"function"==typeof r.then?r.then(function(e){t(e)}):t(r)}catch(e){this.erroredRequest(i,a,o,e),this.resolve(o)}}else this.disableUnhandled||(this.unhandledRequests.push(o),this.unhandledRequest(i,a,o))},handleResponse:function(e,t,r){var n="function"==typeof t?t():t;if(!1===(n="boolean"==typeof n||"number"==typeof n?n:0))r();else{var s=this;s.requestReferences.push({request:e,callback:r}),!0!==n&&(!function t(r,n,s){setTimeout(function(){if(!r.aborted&&!r.status){var e=(new Date).getTime()-n.getTime();r.upload._progress(!0,e,s),r._progress(!0,e,s),t(r,n,s)}},50)}(e,new Date,n),setTimeout(function(){s.resolve(e)},n))}},resolve:function(e){for(var t=0,r=this.requestReferences.length;t<r;t++){var n=this.requestReferences[t];if(n.request===e){n.callback(),this.requestReferences.splice(t,1);break}}},requiresManualResolution:function(e,t){var r=this._handlerFor(e.toUpperCase(),t,{});if(!r)return!1;var n=r.handler.async;return"function"==typeof n?!0===n():!0===n},prepareBody:function(e){return e},prepareHeaders:function(e){return e},handledRequest:function(){},passthroughRequest:function(){},unhandledRequest:function(e,t){throw new Error("Pretender intercepted "+e+" "+t+" but no handler was defined for this type of request")},erroredRequest:function(e,t,r,n){throw n.message="Pretender intercepted "+e+" "+t+" but encountered an error: "+n.message,n},_handlerFor:function(e,t,r){var n=this.hosts.forURL(t)[e].recognize(ee(t).fullpath),s=n?n[0]:null;return s&&(r.params=s.params,r.queryParams=n.queryParams),s},shutdown:function(){window.XMLHttpRequest=this._nativeXMLHttpRequest,this._fetchProps.forEach(function(e){window[e]=this["_native"+e]},this),this.ctx.pretender=void 0,this.running=!1}},ne.parseURL=ee,ne.Hosts=re,ne.Registry=te,ne}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment