webpackJsonp([5],{ /***/ 0: /***/ (function(module, exports) { /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ // css base code, injected by the css-loader module.exports = function(useSourceMap) { var list = []; // return the list of modules as css string list.toString = function toString() { return this.map(function (item) { var content = cssWithMappingToString(item, useSourceMap); if(item[2]) { return "@media " + item[2] + "{" + content + "}"; } else { return content; } }).join(""); }; // import a list of modules into the list list.i = function(modules, mediaQuery) { if(typeof modules === "string") modules = [[null, modules, ""]]; var alreadyImportedModules = {}; for(var i = 0; i < this.length; i++) { var id = this[i][0]; if(typeof id === "number") alreadyImportedModules[id] = true; } for(i = 0; i < modules.length; i++) { var item = modules[i]; // skip already imported module // this implementation is not 100% perfect for weird media query combinations // when a module is imported multiple times with different media queries. // I hope this will never occur (Hey this way we have smaller bundles) if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { if(mediaQuery && !item[2]) { item[2] = mediaQuery; } else if(mediaQuery) { item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; } list.push(item); } } }; return list; }; function cssWithMappingToString(item, useSourceMap) { var content = item[1] || ''; var cssMapping = item[3]; if (!cssMapping) { return content; } if (useSourceMap && typeof btoa === 'function') { var sourceMapping = toComment(cssMapping); var sourceURLs = cssMapping.sources.map(function (source) { return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */' }); return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); } return [content].join('\n'); } // Adapted from convert-source-map (MIT) function toComment(sourceMap) { // eslint-disable-next-line no-undef var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; return '/*# ' + data + ' */'; } /***/ }), /***/ 1: /***/ (function(module, exports, __webpack_require__) { /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra Modified by Evan You @yyx990803 */ var hasDocument = typeof document !== 'undefined' if (typeof DEBUG !== 'undefined' && DEBUG) { if (!hasDocument) { throw new Error( 'vue-style-loader cannot be used in a non-browser environment. ' + "Use { target: 'node' } in your Webpack config to indicate a server-rendering environment." ) } } var listToStyles = __webpack_require__(1689) /* type StyleObject = { id: number; parts: Array } type StyleObjectPart = { css: string; media: string; sourceMap: ?string } */ var stylesInDom = {/* [id: number]: { id: number, refs: number, parts: Array<(obj?: StyleObjectPart) => void> } */} var head = hasDocument && (document.head || document.getElementsByTagName('head')[0]) var singletonElement = null var singletonCounter = 0 var isProduction = false var noop = function () {} var options = null var ssrIdKey = 'data-vue-ssr-id' // Force single-tag solution on IE6-9, which has a hard limit on the # of '; } var iframeContents = '' + script + ''; try { this.myIFrame.doc.open(); this.myIFrame.doc.write(iframeContents); this.myIFrame.doc.close(); } catch (e) { log('frame writing exception'); if (e.stack) { log(e.stack); } log(e); } } else { this.commandCB = commandCB; this.onMessageCB = onMessageCB; } } /** * Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can * actually use. */ FirebaseIFrameScriptHolder.createIFrame_ = function () { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; // This is necessary in order to initialize the document inside the iframe if (document.body) { document.body.appendChild(iframe); try { // If document.domain has been modified in IE, this will throw an error, and we need to set the // domain of the iframe's document manually. We can do this via a javascript: url as the src attribute // Also note that we must do this *after* the iframe has been appended to the page. Otherwise it doesn't work. var a = iframe.contentWindow.document; if (!a) { // Apologies for the log-spam, I need to do something to keep closure from optimizing out the assignment above. log('No IE domain setting required'); } } catch (e) { var domain = document.domain; iframe.src = "javascript:void((function(){document.open();document.domain='" + domain + "';document.close();})())"; } } else { // LongPollConnection attempts to delay initialization until the document is ready, so hopefully this // never gets hit. throw 'Document body has not initialized. Wait to initialize Firebase until after the document is ready.'; } // Get the document of the iframe in a browser-specific way. if (iframe.contentDocument) { iframe.doc = iframe.contentDocument; // Firefox, Opera, Safari } else if (iframe.contentWindow) { iframe.doc = iframe.contentWindow.document; // Internet Explorer // eslint-disable-next-line @typescript-eslint/no-explicit-any } else if (iframe.document) { // eslint-disable-next-line @typescript-eslint/no-explicit-any iframe.doc = iframe.document; //others? } return iframe; }; /** * Cancel all outstanding queries and remove the frame. */ FirebaseIFrameScriptHolder.prototype.close = function () { var _this = this; //Mark this iframe as dead, so no new requests are sent. this.alive = false; if (this.myIFrame) { //We have to actually remove all of the html inside this iframe before removing it from the //window, or IE will continue loading and executing the script tags we've already added, which //can lead to some errors being thrown. Setting innerHTML seems to be the easiest way to do this. this.myIFrame.doc.body.innerHTML = ''; setTimeout(function () { if (_this.myIFrame !== null) { document.body.removeChild(_this.myIFrame); _this.myIFrame = null; } }, Math.floor(0)); } // Protect from being called recursively. var onDisconnect = this.onDisconnect; if (onDisconnect) { this.onDisconnect = null; onDisconnect(); } }; /** * Actually start the long-polling session by adding the first script tag(s) to the iframe. * @param id - The ID of this connection * @param pw - The password for this connection */ FirebaseIFrameScriptHolder.prototype.startLongPoll = function (id, pw) { this.myID = id; this.myPW = pw; this.alive = true; //send the initial request. If there are requests queued, make sure that we transmit as many as we are currently able to. while (this.newRequest_()) { } }; /** * This is called any time someone might want a script tag to be added. It adds a script tag when there aren't * too many outstanding requests and we are still alive. * * If there are outstanding packet segments to send, it sends one. If there aren't, it sends a long-poll anyways if * needed. */ FirebaseIFrameScriptHolder.prototype.newRequest_ = function () { // We keep one outstanding request open all the time to receive data, but if we need to send data // (pendingSegs.length > 0) then we create a new request to send the data. The server will automatically // close the old request. if (this.alive && this.sendNewPolls && this.outstandingRequests.size < (this.pendingSegs.length > 0 ? 2 : 1)) { //construct our url this.currentSerial++; var urlParams = {}; urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID; urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW; urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial; var theURL = this.urlFn(urlParams); //Now add as much data as we can. var curDataString = ''; var i = 0; while (this.pendingSegs.length > 0) { //first, lets see if the next segment will fit. var nextSeg = this.pendingSegs[0]; if (nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <= MAX_URL_DATA_SIZE) { //great, the segment will fit. Lets append it. var theSeg = this.pendingSegs.shift(); curDataString = curDataString + '&' + FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM + i + '=' + theSeg.seg + '&' + FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET + i + '=' + theSeg.ts + '&' + FIREBASE_LONGPOLL_DATA_PARAM + i + '=' + theSeg.d; i++; } else { break; } } theURL = theURL + curDataString; this.addLongPollTag_(theURL, this.currentSerial); return true; } else { return false; } }; /** * Queue a packet for transmission to the server. * @param segnum - A sequential id for this packet segment used for reassembly * @param totalsegs - The total number of segments in this packet * @param data - The data for this segment. */ FirebaseIFrameScriptHolder.prototype.enqueueSegment = function (segnum, totalsegs, data) { //add this to the queue of segments to send. this.pendingSegs.push({ seg: segnum, ts: totalsegs, d: data }); //send the data immediately if there isn't already data being transmitted, unless //startLongPoll hasn't been called yet. if (this.alive) { this.newRequest_(); } }; /** * Add a script tag for a regular long-poll request. * @param url - The URL of the script tag. * @param serial - The serial number of the request. */ FirebaseIFrameScriptHolder.prototype.addLongPollTag_ = function (url, serial) { var _this = this; //remember that we sent this request. this.outstandingRequests.add(serial); var doNewRequest = function () { _this.outstandingRequests.delete(serial); _this.newRequest_(); }; // If this request doesn't return on its own accord (by the server sending us some data), we'll // create a new one after the KEEPALIVE interval to make sure we always keep a fresh request open. var keepaliveTimeout = setTimeout(doNewRequest, Math.floor(KEEPALIVE_REQUEST_INTERVAL)); var readyStateCB = function () { // Request completed. Cancel the keepalive. clearTimeout(keepaliveTimeout); // Trigger a new request so we can continue receiving data. doNewRequest(); }; this.addTag(url, readyStateCB); }; /** * Add an arbitrary script tag to the iframe. * @param url - The URL for the script tag source. * @param loadCB - A callback to be triggered once the script has loaded. */ FirebaseIFrameScriptHolder.prototype.addTag = function (url, loadCB) { var _this = this; if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["z" /* isNodeSdk */])()) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.doNodeLongPoll(url, loadCB); } else { setTimeout(function () { try { // if we're already closed, don't add this poll if (!_this.sendNewPolls) { return; } var newScript_1 = _this.myIFrame.doc.createElement('script'); newScript_1.type = 'text/javascript'; newScript_1.async = true; newScript_1.src = url; // eslint-disable-next-line @typescript-eslint/no-explicit-any newScript_1.onload = newScript_1.onreadystatechange = function () { // eslint-disable-next-line @typescript-eslint/no-explicit-any var rstate = newScript_1.readyState; if (!rstate || rstate === 'loaded' || rstate === 'complete') { // eslint-disable-next-line @typescript-eslint/no-explicit-any newScript_1.onload = newScript_1.onreadystatechange = null; if (newScript_1.parentNode) { newScript_1.parentNode.removeChild(newScript_1); } loadCB(); } }; newScript_1.onerror = function () { log('Long-poll script failed to load: ' + url); _this.sendNewPolls = false; _this.close(); }; _this.myIFrame.doc.body.appendChild(newScript_1); } catch (e) { // TODO: we should make this error visible somehow } }, Math.floor(1)); } }; return FirebaseIFrameScriptHolder; }()); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** The semver (www.semver.org) version of the SDK. */ var SDK_VERSION = ''; // SDK_VERSION should be set before any database instance is created function setSDKVersion(version) { SDK_VERSION = version; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var WEBSOCKET_MAX_FRAME_SIZE = 16384; var WEBSOCKET_KEEPALIVE_INTERVAL = 45000; var WebSocketImpl = null; if (typeof MozWebSocket !== 'undefined') { WebSocketImpl = MozWebSocket; } else if (typeof WebSocket !== 'undefined') { WebSocketImpl = WebSocket; } /** * Create a new websocket connection with the given callbacks. */ var WebSocketConnection = /** @class */ (function () { /** * @param connId identifier for this transport * @param repoInfo The info for the websocket endpoint. * @param applicationId The Firebase App ID for this project. * @param transportSessionId Optional transportSessionId if this is connecting to an existing transport * session * @param lastSessionId Optional lastSessionId if there was a previous connection */ function WebSocketConnection(connId, repoInfo, applicationId, transportSessionId, lastSessionId) { this.connId = connId; this.applicationId = applicationId; this.keepaliveTimer = null; this.frames = null; this.totalFrames = 0; this.bytesSent = 0; this.bytesReceived = 0; this.log_ = logWrapper(this.connId); this.stats_ = statsManagerGetCollection(repoInfo); this.connURL = WebSocketConnection.connectionURL_(repoInfo, transportSessionId, lastSessionId); this.nodeAdmin = repoInfo.nodeAdmin; } /** * @param repoInfo The info for the websocket endpoint. * @param transportSessionId Optional transportSessionId if this is connecting to an existing transport * session * @param lastSessionId Optional lastSessionId if there was a previous connection * @return connection url */ WebSocketConnection.connectionURL_ = function (repoInfo, transportSessionId, lastSessionId) { var urlParams = {}; urlParams[VERSION_PARAM] = PROTOCOL_VERSION; if (!Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["z" /* isNodeSdk */])() && typeof location !== 'undefined' && location.hostname && FORGE_DOMAIN_RE.test(location.hostname)) { urlParams[REFERER_PARAM] = FORGE_REF; } if (transportSessionId) { urlParams[TRANSPORT_SESSION_PARAM] = transportSessionId; } if (lastSessionId) { urlParams[LAST_SESSION_PARAM] = lastSessionId; } return repoInfoConnectionURL(repoInfo, WEBSOCKET, urlParams); }; /** * @param onMessage Callback when messages arrive * @param onDisconnect Callback with connection lost. */ WebSocketConnection.prototype.open = function (onMessage, onDisconnect) { var _this = this; this.onDisconnect = onDisconnect; this.onMessage = onMessage; this.log_('Websocket connecting to ' + this.connURL); this.everConnected_ = false; // Assume failure until proven otherwise. PersistentStorage.set('previous_websocket_failure', true); try { if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["z" /* isNodeSdk */])()) { var device = this.nodeAdmin ? 'AdminNode' : 'Node'; // UA Format: Firebase//// var options = { headers: { 'User-Agent': "Firebase/" + PROTOCOL_VERSION + "/" + SDK_VERSION + "/" + process.platform + "/" + device, 'X-Firebase-GMPID': this.applicationId || '' } }; // Plumb appropriate http_proxy environment variable into faye-websocket if it exists. var env = Object({"NODE_ENV":"production","SERVER":"https://soulapi.blueticket.com.br/api","PDV":"https://sistema.blueticket.com.br","CAMPAIGN_SERVER_URL":"https://campaigns.blueticket.com.br","CHECKOUT":"https://checkout.blueticket.com.br/btrest/forget/user/password","DEV03_SERVER":"https://soulapi.blueticket.com.br/api","DEV02_SERVER":"https://soulapi.blueticket.com.br/api","GOOGLE_API_KEY":"AIzaSyCO8xX-ayxnRvCy7nMTCUPSUpa2l436_n4","FIREBASE_API_KEY":"AIzaSyAIZdQ26rsZQmWkPKMnG8ui_8GBbd4dQoo","FIREBASE_AUTH_DOMAIN":"chat-eventos-online.firebaseapp.com","FIREBASE_DATABASE_URL":"https://chat-eventos-online-default-rtdb.firebaseio.com","FIREBASE_PROJECT_ID":"chat-eventos-online","FIRBASE_STORAGE_BUCKET":"chat-eventos-online.appspot.com","FIREBASE_MESSAGING_SENDER_ID":"557708174668","FIREBASE_APP_ID":"1:557708174668:web:3787feb553d135de779be9"}); var proxy = this.connURL.indexOf('wss://') === 0 ? env['HTTPS_PROXY'] || env['https_proxy'] : env['HTTP_PROXY'] || env['http_proxy']; if (proxy) { options['proxy'] = { origin: proxy }; } this.mySock = new WebSocketImpl(this.connURL, [], options); } else { var options = { headers: { 'X-Firebase-GMPID': this.applicationId || '' } }; this.mySock = new WebSocketImpl(this.connURL, [], options); } } catch (e) { this.log_('Error instantiating WebSocket.'); var error = e.message || e.data; if (error) { this.log_(error); } this.onClosed_(); return; } this.mySock.onopen = function () { _this.log_('Websocket connected.'); _this.everConnected_ = true; }; this.mySock.onclose = function () { _this.log_('Websocket connection was disconnected.'); _this.mySock = null; _this.onClosed_(); }; this.mySock.onmessage = function (m) { _this.handleIncomingFrame(m); }; this.mySock.onerror = function (e) { _this.log_('WebSocket error. Closing connection.'); // eslint-disable-next-line @typescript-eslint/no-explicit-any var error = e.message || e.data; if (error) { _this.log_(error); } _this.onClosed_(); }; }; /** * No-op for websockets, we don't need to do anything once the connection is confirmed as open */ WebSocketConnection.prototype.start = function () { }; WebSocketConnection.forceDisallow = function () { WebSocketConnection.forceDisallow_ = true; }; WebSocketConnection.isAvailable = function () { var isOldAndroid = false; if (typeof navigator !== 'undefined' && navigator.userAgent) { var oldAndroidRegex = /Android ([0-9]{0,}\.[0-9]{0,})/; var oldAndroidMatch = navigator.userAgent.match(oldAndroidRegex); if (oldAndroidMatch && oldAndroidMatch.length > 1) { if (parseFloat(oldAndroidMatch[1]) < 4.4) { isOldAndroid = true; } } } return (!isOldAndroid && WebSocketImpl !== null && !WebSocketConnection.forceDisallow_); }; /** * Returns true if we previously failed to connect with this transport. */ WebSocketConnection.previouslyFailed = function () { // If our persistent storage is actually only in-memory storage, // we default to assuming that it previously failed to be safe. return (PersistentStorage.isInMemoryStorage || PersistentStorage.get('previous_websocket_failure') === true); }; WebSocketConnection.prototype.markConnectionHealthy = function () { PersistentStorage.remove('previous_websocket_failure'); }; WebSocketConnection.prototype.appendFrame_ = function (data) { this.frames.push(data); if (this.frames.length === this.totalFrames) { var fullMess = this.frames.join(''); this.frames = null; var jsonMess = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["D" /* jsonEval */])(fullMess); //handle the message this.onMessage(jsonMess); } }; /** * @param frameCount The number of frames we are expecting from the server */ WebSocketConnection.prototype.handleNewFrameCount_ = function (frameCount) { this.totalFrames = frameCount; this.frames = []; }; /** * Attempts to parse a frame count out of some text. If it can't, assumes a value of 1 * @return Any remaining data to be process, or null if there is none */ WebSocketConnection.prototype.extractFrameCount_ = function (data) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(this.frames === null, 'We already have a frame buffer'); // TODO: The server is only supposed to send up to 9999 frames (i.e. length <= 4), but that isn't being enforced // currently. So allowing larger frame counts (length <= 6). See https://app.asana.com/0/search/8688598998380/8237608042508 if (data.length <= 6) { var frameCount = Number(data); if (!isNaN(frameCount)) { this.handleNewFrameCount_(frameCount); return null; } } this.handleNewFrameCount_(1); return data; }; /** * Process a websocket frame that has arrived from the server. * @param mess The frame data */ WebSocketConnection.prototype.handleIncomingFrame = function (mess) { if (this.mySock === null) { return; // Chrome apparently delivers incoming packets even after we .close() the connection sometimes. } var data = mess['data']; this.bytesReceived += data.length; this.stats_.incrementCounter('bytes_received', data.length); this.resetKeepAlive(); if (this.frames !== null) { // we're buffering this.appendFrame_(data); } else { // try to parse out a frame count, otherwise, assume 1 and process it var remainingData = this.extractFrameCount_(data); if (remainingData !== null) { this.appendFrame_(remainingData); } } }; /** * Send a message to the server * @param data The JSON object to transmit */ WebSocketConnection.prototype.send = function (data) { this.resetKeepAlive(); var dataStr = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(data); this.bytesSent += dataStr.length; this.stats_.incrementCounter('bytes_sent', dataStr.length); //We can only fit a certain amount in each websocket frame, so we need to split this request //up into multiple pieces if it doesn't fit in one request. var dataSegs = splitStringBySize(dataStr, WEBSOCKET_MAX_FRAME_SIZE); //Send the length header if (dataSegs.length > 1) { this.sendString_(String(dataSegs.length)); } //Send the actual data in segments. for (var i = 0; i < dataSegs.length; i++) { this.sendString_(dataSegs[i]); } }; WebSocketConnection.prototype.shutdown_ = function () { this.isClosed_ = true; if (this.keepaliveTimer) { clearInterval(this.keepaliveTimer); this.keepaliveTimer = null; } if (this.mySock) { this.mySock.close(); this.mySock = null; } }; WebSocketConnection.prototype.onClosed_ = function () { if (!this.isClosed_) { this.log_('WebSocket is closing itself'); this.shutdown_(); // since this is an internal close, trigger the close listener if (this.onDisconnect) { this.onDisconnect(this.everConnected_); this.onDisconnect = null; } } }; /** * External-facing close handler. * Close the websocket and kill the connection. */ WebSocketConnection.prototype.close = function () { if (!this.isClosed_) { this.log_('WebSocket is being closed'); this.shutdown_(); } }; /** * Kill the current keepalive timer and start a new one, to ensure that it always fires N seconds after * the last activity. */ WebSocketConnection.prototype.resetKeepAlive = function () { var _this = this; clearInterval(this.keepaliveTimer); this.keepaliveTimer = setInterval(function () { //If there has been no websocket activity for a while, send a no-op if (_this.mySock) { _this.sendString_('0'); } _this.resetKeepAlive(); // eslint-disable-next-line @typescript-eslint/no-explicit-any }, Math.floor(WEBSOCKET_KEEPALIVE_INTERVAL)); }; /** * Send a string over the websocket. * * @param str String to send. */ WebSocketConnection.prototype.sendString_ = function (str) { // Firefox seems to sometimes throw exceptions (NS_ERROR_UNEXPECTED) from websocket .send() // calls for some unknown reason. We treat these as an error and disconnect. // See https://app.asana.com/0/58926111402292/68021340250410 try { this.mySock.send(str); } catch (e) { this.log_('Exception thrown from WebSocket.send():', e.message || e.data, 'Closing connection.'); setTimeout(this.onClosed_.bind(this), 0); } }; /** * Number of response before we consider the connection "healthy." */ WebSocketConnection.responsesRequiredToBeHealthy = 2; /** * Time to wait for the connection te become healthy before giving up. */ WebSocketConnection.healthyTimeout = 30000; return WebSocketConnection; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Currently simplistic, this class manages what transport a Connection should use at various stages of its * lifecycle. * * It starts with longpolling in a browser, and httppolling on node. It then upgrades to websockets if * they are available. */ var TransportManager = /** @class */ (function () { /** * @param repoInfo Metadata around the namespace we're connecting to */ function TransportManager(repoInfo) { this.initTransports_(repoInfo); } Object.defineProperty(TransportManager, "ALL_TRANSPORTS", { get: function () { return [BrowserPollConnection, WebSocketConnection]; }, enumerable: false, configurable: true }); TransportManager.prototype.initTransports_ = function (repoInfo) { var e_1, _a; var isWebSocketsAvailable = WebSocketConnection && WebSocketConnection['isAvailable'](); var isSkipPollConnection = isWebSocketsAvailable && !WebSocketConnection.previouslyFailed(); if (repoInfo.webSocketOnly) { if (!isWebSocketsAvailable) { warn("wss:// URL used, but browser isn't known to support websockets. Trying anyway."); } isSkipPollConnection = true; } if (isSkipPollConnection) { this.transports_ = [WebSocketConnection]; } else { var transports = (this.transports_ = []); try { for (var _b = Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["g" /* __values */])(TransportManager.ALL_TRANSPORTS), _c = _b.next(); !_c.done; _c = _b.next()) { var transport = _c.value; if (transport && transport['isAvailable']()) { transports.push(transport); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } } }; /** * @return The constructor for the initial transport to use */ TransportManager.prototype.initialTransport = function () { if (this.transports_.length > 0) { return this.transports_[0]; } else { throw new Error('No transports available'); } }; /** * @return The constructor for the next transport, or null */ TransportManager.prototype.upgradeTransport = function () { if (this.transports_.length > 1) { return this.transports_[1]; } else { return null; } }; return TransportManager; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Abort upgrade attempt if it takes longer than 60s. var UPGRADE_TIMEOUT = 60000; // For some transports (WebSockets), we need to "validate" the transport by exchanging a few requests and responses. // If we haven't sent enough requests within 5s, we'll start sending noop ping requests. var DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5000; // If the initial data sent triggers a lot of bandwidth (i.e. it's a large put or a listen for a large amount of data) // then we may not be able to exchange our ping/pong requests within the healthy timeout. So if we reach the timeout // but we've sent/received enough bytes, we don't cancel the connection. var BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024; var BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024; var MESSAGE_TYPE = 't'; var MESSAGE_DATA = 'd'; var CONTROL_SHUTDOWN = 's'; var CONTROL_RESET = 'r'; var CONTROL_ERROR = 'e'; var CONTROL_PONG = 'o'; var SWITCH_ACK = 'a'; var END_TRANSMISSION = 'n'; var PING = 'p'; var SERVER_HELLO = 'h'; /** * Creates a new real-time connection to the server using whichever method works * best in the current browser. */ var Connection = /** @class */ (function () { /** * @param id - an id for this connection * @param repoInfo_ - the info for the endpoint to connect to * @param applicationId_ - the Firebase App ID for this project * @param onMessage_ - the callback to be triggered when a server-push message arrives * @param onReady_ - the callback to be triggered when this connection is ready to send messages. * @param onDisconnect_ - the callback to be triggered when a connection was lost * @param onKill_ - the callback to be triggered when this connection has permanently shut down. * @param lastSessionId - last session id in persistent connection. is used to clean up old session in real-time server */ function Connection(id, repoInfo_, applicationId_, onMessage_, onReady_, onDisconnect_, onKill_, lastSessionId) { this.id = id; this.repoInfo_ = repoInfo_; this.applicationId_ = applicationId_; this.onMessage_ = onMessage_; this.onReady_ = onReady_; this.onDisconnect_ = onDisconnect_; this.onKill_ = onKill_; this.lastSessionId = lastSessionId; this.connectionCount = 0; this.pendingDataMessages = []; this.state_ = 0 /* CONNECTING */; this.log_ = logWrapper('c:' + this.id + ':'); this.transportManager_ = new TransportManager(repoInfo_); this.log_('Connection created'); this.start_(); } /** * Starts a connection attempt */ Connection.prototype.start_ = function () { var _this = this; var conn = this.transportManager_.initialTransport(); this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.applicationId_, undefined, this.lastSessionId); // For certain transports (WebSockets), we need to send and receive several messages back and forth before we // can consider the transport healthy. this.primaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0; var onMessageReceived = this.connReceiver_(this.conn_); var onConnectionLost = this.disconnReceiver_(this.conn_); this.tx_ = this.conn_; this.rx_ = this.conn_; this.secondaryConn_ = null; this.isHealthy_ = false; /* * Firefox doesn't like when code from one iframe tries to create another iframe by way of the parent frame. * This can occur in the case of a redirect, i.e. we guessed wrong on what server to connect to and received a reset. * Somehow, setTimeout seems to make this ok. That doesn't make sense from a security perspective, since you should * still have the context of your originating frame. */ setTimeout(function () { // this.conn_ gets set to null in some of the tests. Check to make sure it still exists before using it _this.conn_ && _this.conn_.open(onMessageReceived, onConnectionLost); }, Math.floor(0)); var healthyTimeoutMS = conn['healthyTimeout'] || 0; if (healthyTimeoutMS > 0) { this.healthyTimeout_ = setTimeoutNonBlocking(function () { _this.healthyTimeout_ = null; if (!_this.isHealthy_) { if (_this.conn_ && _this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE) { _this.log_('Connection exceeded healthy timeout but has received ' + _this.conn_.bytesReceived + ' bytes. Marking connection healthy.'); _this.isHealthy_ = true; _this.conn_.markConnectionHealthy(); } else if (_this.conn_ && _this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE) { _this.log_('Connection exceeded healthy timeout but has sent ' + _this.conn_.bytesSent + ' bytes. Leaving connection alive.'); // NOTE: We don't want to mark it healthy, since we have no guarantee that the bytes have made it to // the server. } else { _this.log_('Closing unhealthy connection after timeout.'); _this.close(); } } // eslint-disable-next-line @typescript-eslint/no-explicit-any }, Math.floor(healthyTimeoutMS)); } }; Connection.prototype.nextTransportId_ = function () { return 'c:' + this.id + ':' + this.connectionCount++; }; Connection.prototype.disconnReceiver_ = function (conn) { var _this = this; return function (everConnected) { if (conn === _this.conn_) { _this.onConnectionLost_(everConnected); } else if (conn === _this.secondaryConn_) { _this.log_('Secondary connection lost.'); _this.onSecondaryConnectionLost_(); } else { _this.log_('closing an old connection'); } }; }; Connection.prototype.connReceiver_ = function (conn) { var _this = this; return function (message) { if (_this.state_ !== 2 /* DISCONNECTED */) { if (conn === _this.rx_) { _this.onPrimaryMessageReceived_(message); } else if (conn === _this.secondaryConn_) { _this.onSecondaryMessageReceived_(message); } else { _this.log_('message on old connection'); } } }; }; /** * @param dataMsg An arbitrary data message to be sent to the server */ Connection.prototype.sendRequest = function (dataMsg) { // wrap in a data message envelope and send it on var msg = { t: 'd', d: dataMsg }; this.sendData_(msg); }; Connection.prototype.tryCleanupConnection = function () { if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) { this.log_('cleaning up and promoting a connection: ' + this.secondaryConn_.connId); this.conn_ = this.secondaryConn_; this.secondaryConn_ = null; // the server will shutdown the old connection } }; Connection.prototype.onSecondaryControl_ = function (controlData) { if (MESSAGE_TYPE in controlData) { var cmd = controlData[MESSAGE_TYPE]; if (cmd === SWITCH_ACK) { this.upgradeIfSecondaryHealthy_(); } else if (cmd === CONTROL_RESET) { // Most likely the session wasn't valid. Abandon the switch attempt this.log_('Got a reset on secondary, closing it'); this.secondaryConn_.close(); // If we were already using this connection for something, than we need to fully close if (this.tx_ === this.secondaryConn_ || this.rx_ === this.secondaryConn_) { this.close(); } } else if (cmd === CONTROL_PONG) { this.log_('got pong on secondary.'); this.secondaryResponsesRequired_--; this.upgradeIfSecondaryHealthy_(); } } }; Connection.prototype.onSecondaryMessageReceived_ = function (parsedData) { var layer = requireKey('t', parsedData); var data = requireKey('d', parsedData); if (layer === 'c') { this.onSecondaryControl_(data); } else if (layer === 'd') { // got a data message, but we're still second connection. Need to buffer it up this.pendingDataMessages.push(data); } else { throw new Error('Unknown protocol layer: ' + layer); } }; Connection.prototype.upgradeIfSecondaryHealthy_ = function () { if (this.secondaryResponsesRequired_ <= 0) { this.log_('Secondary connection is healthy.'); this.isHealthy_ = true; this.secondaryConn_.markConnectionHealthy(); this.proceedWithUpgrade_(); } else { // Send a ping to make sure the connection is healthy. this.log_('sending ping on secondary.'); this.secondaryConn_.send({ t: 'c', d: { t: PING, d: {} } }); } }; Connection.prototype.proceedWithUpgrade_ = function () { // tell this connection to consider itself open this.secondaryConn_.start(); // send ack this.log_('sending client ack on secondary'); this.secondaryConn_.send({ t: 'c', d: { t: SWITCH_ACK, d: {} } }); // send end packet on primary transport, switch to sending on this one // can receive on this one, buffer responses until end received on primary transport this.log_('Ending transmission on primary'); this.conn_.send({ t: 'c', d: { t: END_TRANSMISSION, d: {} } }); this.tx_ = this.secondaryConn_; this.tryCleanupConnection(); }; Connection.prototype.onPrimaryMessageReceived_ = function (parsedData) { // Must refer to parsedData properties in quotes, so closure doesn't touch them. var layer = requireKey('t', parsedData); var data = requireKey('d', parsedData); if (layer === 'c') { this.onControl_(data); } else if (layer === 'd') { this.onDataMessage_(data); } }; Connection.prototype.onDataMessage_ = function (message) { this.onPrimaryResponse_(); // We don't do anything with data messages, just kick them up a level this.onMessage_(message); }; Connection.prototype.onPrimaryResponse_ = function () { if (!this.isHealthy_) { this.primaryResponsesRequired_--; if (this.primaryResponsesRequired_ <= 0) { this.log_('Primary connection is healthy.'); this.isHealthy_ = true; this.conn_.markConnectionHealthy(); } } }; Connection.prototype.onControl_ = function (controlData) { var cmd = requireKey(MESSAGE_TYPE, controlData); if (MESSAGE_DATA in controlData) { var payload = controlData[MESSAGE_DATA]; if (cmd === SERVER_HELLO) { this.onHandshake_(payload); } else if (cmd === END_TRANSMISSION) { this.log_('recvd end transmission on primary'); this.rx_ = this.secondaryConn_; for (var i = 0; i < this.pendingDataMessages.length; ++i) { this.onDataMessage_(this.pendingDataMessages[i]); } this.pendingDataMessages = []; this.tryCleanupConnection(); } else if (cmd === CONTROL_SHUTDOWN) { // This was previously the 'onKill' callback passed to the lower-level connection // payload in this case is the reason for the shutdown. Generally a human-readable error this.onConnectionShutdown_(payload); } else if (cmd === CONTROL_RESET) { // payload in this case is the host we should contact this.onReset_(payload); } else if (cmd === CONTROL_ERROR) { error('Server Error: ' + payload); } else if (cmd === CONTROL_PONG) { this.log_('got pong on primary.'); this.onPrimaryResponse_(); this.sendPingOnPrimaryIfNecessary_(); } else { error('Unknown control packet command: ' + cmd); } } }; /** * @param handshake The handshake data returned from the server */ Connection.prototype.onHandshake_ = function (handshake) { var timestamp = handshake.ts; var version = handshake.v; var host = handshake.h; this.sessionId = handshake.s; this.repoInfo_.host = host; // if we've already closed the connection, then don't bother trying to progress further if (this.state_ === 0 /* CONNECTING */) { this.conn_.start(); this.onConnectionEstablished_(this.conn_, timestamp); if (PROTOCOL_VERSION !== version) { warn('Protocol version mismatch detected'); } // TODO: do we want to upgrade? when? maybe a delay? this.tryStartUpgrade_(); } }; Connection.prototype.tryStartUpgrade_ = function () { var conn = this.transportManager_.upgradeTransport(); if (conn) { this.startUpgrade_(conn); } }; Connection.prototype.startUpgrade_ = function (conn) { var _this = this; this.secondaryConn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.applicationId_, this.sessionId); // For certain transports (WebSockets), we need to send and receive several messages back and forth before we // can consider the transport healthy. this.secondaryResponsesRequired_ = conn['responsesRequiredToBeHealthy'] || 0; var onMessage = this.connReceiver_(this.secondaryConn_); var onDisconnect = this.disconnReceiver_(this.secondaryConn_); this.secondaryConn_.open(onMessage, onDisconnect); // If we haven't successfully upgraded after UPGRADE_TIMEOUT, give up and kill the secondary. setTimeoutNonBlocking(function () { if (_this.secondaryConn_) { _this.log_('Timed out trying to upgrade.'); _this.secondaryConn_.close(); } }, Math.floor(UPGRADE_TIMEOUT)); }; Connection.prototype.onReset_ = function (host) { this.log_('Reset packet received. New host: ' + host); this.repoInfo_.host = host; // TODO: if we're already "connected", we need to trigger a disconnect at the next layer up. // We don't currently support resets after the connection has already been established if (this.state_ === 1 /* CONNECTED */) { this.close(); } else { // Close whatever connections we have open and start again. this.closeConnections_(); this.start_(); } }; Connection.prototype.onConnectionEstablished_ = function (conn, timestamp) { var _this = this; this.log_('Realtime connection established.'); this.conn_ = conn; this.state_ = 1 /* CONNECTED */; if (this.onReady_) { this.onReady_(timestamp, this.sessionId); this.onReady_ = null; } // If after 5 seconds we haven't sent enough requests to the server to get the connection healthy, // send some pings. if (this.primaryResponsesRequired_ === 0) { this.log_('Primary connection is healthy.'); this.isHealthy_ = true; } else { setTimeoutNonBlocking(function () { _this.sendPingOnPrimaryIfNecessary_(); }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS)); } }; Connection.prototype.sendPingOnPrimaryIfNecessary_ = function () { // If the connection isn't considered healthy yet, we'll send a noop ping packet request. if (!this.isHealthy_ && this.state_ === 1 /* CONNECTED */) { this.log_('sending ping on primary.'); this.sendData_({ t: 'c', d: { t: PING, d: {} } }); } }; Connection.prototype.onSecondaryConnectionLost_ = function () { var conn = this.secondaryConn_; this.secondaryConn_ = null; if (this.tx_ === conn || this.rx_ === conn) { // we are relying on this connection already in some capacity. Therefore, a failure is real this.close(); } }; /** * @param everConnected Whether or not the connection ever reached a server. Used to determine if * we should flush the host cache */ Connection.prototype.onConnectionLost_ = function (everConnected) { this.conn_ = null; // NOTE: IF you're seeing a Firefox error for this line, I think it might be because it's getting // called on window close and RealtimeState.CONNECTING is no longer defined. Just a guess. if (!everConnected && this.state_ === 0 /* CONNECTING */) { this.log_('Realtime connection failed.'); // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away if (this.repoInfo_.isCacheableHost()) { PersistentStorage.remove('host:' + this.repoInfo_.host); // reset the internal host to what we would show the user, i.e. .firebaseio.com this.repoInfo_.internalHost = this.repoInfo_.host; } } else if (this.state_ === 1 /* CONNECTED */) { this.log_('Realtime connection lost.'); } this.close(); }; Connection.prototype.onConnectionShutdown_ = function (reason) { this.log_('Connection shutdown command received. Shutting down...'); if (this.onKill_) { this.onKill_(reason); this.onKill_ = null; } // We intentionally don't want to fire onDisconnect (kill is a different case), // so clear the callback. this.onDisconnect_ = null; this.close(); }; Connection.prototype.sendData_ = function (data) { if (this.state_ !== 1 /* CONNECTED */) { throw 'Connection is not connected'; } else { this.tx_.send(data); } }; /** * Cleans up this connection, calling the appropriate callbacks */ Connection.prototype.close = function () { if (this.state_ !== 2 /* DISCONNECTED */) { this.log_('Closing realtime connection.'); this.state_ = 2 /* DISCONNECTED */; this.closeConnections_(); if (this.onDisconnect_) { this.onDisconnect_(); this.onDisconnect_ = null; } } }; Connection.prototype.closeConnections_ = function () { this.log_('Shutting down all connections'); if (this.conn_) { this.conn_.close(); this.conn_ = null; } if (this.secondaryConn_) { this.secondaryConn_.close(); this.secondaryConn_ = null; } if (this.healthyTimeout_) { clearTimeout(this.healthyTimeout_); this.healthyTimeout_ = null; } }; return Connection; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Interface defining the set of actions that can be performed against the Firebase server * (basically corresponds to our wire protocol). * * @interface */ var ServerActions = /** @class */ (function () { function ServerActions() { } ServerActions.prototype.put = function (pathString, data, onComplete, hash) { }; ServerActions.prototype.merge = function (pathString, data, onComplete, hash) { }; /** * Refreshes the auth token for the current connection. * @param token The authentication token */ ServerActions.prototype.refreshAuthToken = function (token) { }; ServerActions.prototype.onDisconnectPut = function (pathString, data, onComplete) { }; ServerActions.prototype.onDisconnectMerge = function (pathString, data, onComplete) { }; ServerActions.prototype.onDisconnectCancel = function (pathString, onComplete) { }; ServerActions.prototype.reportStats = function (stats) { }; return ServerActions; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var RECONNECT_MIN_DELAY = 1000; var RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1000; // 5 minutes in milliseconds (Case: 1858) var GET_CONNECT_TIMEOUT = 3 * 1000; var RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1000; // 30 seconds for admin clients (likely to be a backend server) var RECONNECT_DELAY_MULTIPLIER = 1.3; var RECONNECT_DELAY_RESET_TIMEOUT = 30000; // Reset delay back to MIN_DELAY after being connected for 30sec. var SERVER_KILL_INTERRUPT_REASON = 'server_kill'; // If auth fails repeatedly, we'll assume something is wrong and log a warning / back off. var INVALID_AUTH_TOKEN_THRESHOLD = 3; /** * Firebase connection. Abstracts wire protocol and handles reconnecting. * * NOTE: All JSON objects sent to the realtime connection must have property names enclosed * in quotes to make sure the closure compiler does not minify them. */ var PersistentConnection = /** @class */ (function (_super) { Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __extends */])(PersistentConnection, _super); /** * @param repoInfo_ Data about the namespace we are connecting to * @param applicationId_ The Firebase App ID for this project * @param onDataUpdate_ A callback for new data from the server */ function PersistentConnection(repoInfo_, applicationId_, onDataUpdate_, onConnectStatus_, onServerInfoUpdate_, authTokenProvider_, authOverride_) { var _this = _super.call(this) || this; _this.repoInfo_ = repoInfo_; _this.applicationId_ = applicationId_; _this.onDataUpdate_ = onDataUpdate_; _this.onConnectStatus_ = onConnectStatus_; _this.onServerInfoUpdate_ = onServerInfoUpdate_; _this.authTokenProvider_ = authTokenProvider_; _this.authOverride_ = authOverride_; // Used for diagnostic logging. _this.id = PersistentConnection.nextPersistentConnectionId_++; _this.log_ = logWrapper('p:' + _this.id + ':'); _this.interruptReasons_ = {}; /** Map> */ _this.listens = new Map(); _this.outstandingPuts_ = []; _this.outstandingGets_ = []; _this.outstandingPutCount_ = 0; _this.outstandingGetCount_ = 0; _this.onDisconnectRequestQueue_ = []; _this.connected_ = false; _this.reconnectDelay_ = RECONNECT_MIN_DELAY; _this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT; _this.securityDebugCallback_ = null; _this.lastSessionId = null; _this.establishConnectionTimer_ = null; _this.visible_ = false; // Before we get connected, we keep a queue of pending messages to send. _this.requestCBHash_ = {}; _this.requestNumber_ = 0; _this.realtime_ = null; _this.authToken_ = null; _this.forceTokenRefresh_ = false; _this.invalidAuthTokenCount_ = 0; _this.firstConnection_ = true; _this.lastConnectionAttemptTime_ = null; _this.lastConnectionEstablishedTime_ = null; if (authOverride_ && !Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["z" /* isNodeSdk */])()) { throw new Error('Auth override specified in options, but not supported on non Node.js platforms'); } _this.scheduleConnect_(0); VisibilityMonitor.getInstance().on('visible', _this.onVisible_, _this); if (repoInfo_.host.indexOf('fblocal') === -1) { OnlineMonitor.getInstance().on('online', _this.onOnline_, _this); } return _this; } PersistentConnection.prototype.sendRequest = function (action, body, onResponse) { var curReqNum = ++this.requestNumber_; var msg = { r: curReqNum, a: action, b: body }; this.log_(Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(msg)); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(this.connected_, "sendRequest call when we're not connected not allowed."); this.realtime_.sendRequest(msg); if (onResponse) { this.requestCBHash_[curReqNum] = onResponse; } }; PersistentConnection.prototype.get = function (query) { var _this = this; var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); var request = { p: query.path.toString(), q: query.queryObject() }; var outstandingGet = { action: 'g', request: request, onComplete: function (message) { var payload = message['d']; if (message['s'] === 'ok') { _this.onDataUpdate_(request['p'], payload, /*isMerge*/ false, /*tag*/ null); deferred.resolve(payload); } else { deferred.reject(payload); } } }; this.outstandingGets_.push(outstandingGet); this.outstandingGetCount_++; var index = this.outstandingGets_.length - 1; if (!this.connected_) { setTimeout(function () { var get = _this.outstandingGets_[index]; if (get === undefined || outstandingGet !== get) { return; } delete _this.outstandingGets_[index]; _this.outstandingGetCount_--; if (_this.outstandingGetCount_ === 0) { _this.outstandingGets_ = []; } _this.log_('get ' + index + ' timed out on connection'); deferred.reject(new Error('Client is offline.')); }, GET_CONNECT_TIMEOUT); } if (this.connected_) { this.sendGet_(index); } return deferred.promise; }; /** * @inheritDoc */ PersistentConnection.prototype.listen = function (query, currentHashFn, tag, onComplete) { var queryId = query.queryIdentifier(); var pathString = query.path.toString(); this.log_('Listen called for ' + pathString + ' ' + queryId); if (!this.listens.has(pathString)) { this.listens.set(pathString, new Map()); } Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), 'listen() called for non-default but complete query'); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(!this.listens.get(pathString).has(queryId), 'listen() called twice for same path/queryId.'); var listenSpec = { onComplete: onComplete, hashFn: currentHashFn, query: query, tag: tag }; this.listens.get(pathString).set(queryId, listenSpec); if (this.connected_) { this.sendListen_(listenSpec); } }; PersistentConnection.prototype.sendGet_ = function (index) { var _this = this; var get = this.outstandingGets_[index]; this.sendRequest('g', get.request, function (message) { delete _this.outstandingGets_[index]; _this.outstandingGetCount_--; if (_this.outstandingGetCount_ === 0) { _this.outstandingGets_ = []; } if (get.onComplete) { get.onComplete(message); } }); }; PersistentConnection.prototype.sendListen_ = function (listenSpec) { var _this = this; var query = listenSpec.query; var pathString = query.path.toString(); var queryId = query.queryIdentifier(); this.log_('Listen on ' + pathString + ' for ' + queryId); var req = { /*path*/ p: pathString }; var action = 'q'; // Only bother to send query if it's non-default. if (listenSpec.tag) { req['q'] = query.queryObject(); req['t'] = listenSpec.tag; } req[ /*hash*/'h'] = listenSpec.hashFn(); this.sendRequest(action, req, function (message) { var payload = message[ /*data*/'d']; var status = message[ /*status*/'s']; // print warnings in any case... PersistentConnection.warnOnListenWarnings_(payload, query); var currentListenSpec = _this.listens.get(pathString) && _this.listens.get(pathString).get(queryId); // only trigger actions if the listen hasn't been removed and readded if (currentListenSpec === listenSpec) { _this.log_('listen response', message); if (status !== 'ok') { _this.removeListen_(pathString, queryId); } if (listenSpec.onComplete) { listenSpec.onComplete(status, payload); } } }); }; PersistentConnection.warnOnListenWarnings_ = function (payload, query) { if (payload && typeof payload === 'object' && Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["k" /* contains */])(payload, 'w')) { // eslint-disable-next-line @typescript-eslint/no-explicit-any var warnings = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(payload, 'w'); if (Array.isArray(warnings) && ~warnings.indexOf('no_index')) { var indexSpec = '".indexOn": "' + query.getQueryParams().getIndex().toString() + '"'; var indexPath = query.path.toString(); warn("Using an unspecified index. Your data will be downloaded and " + ("filtered on the client. Consider adding " + indexSpec + " at ") + (indexPath + " to your security rules for better performance.")); } } }; /** * @inheritDoc */ PersistentConnection.prototype.refreshAuthToken = function (token) { this.authToken_ = token; this.log_('Auth token refreshed'); if (this.authToken_) { this.tryAuth(); } else { //If we're connected we want to let the server know to unauthenticate us. If we're not connected, simply delete //the credential so we dont become authenticated next time we connect. if (this.connected_) { this.sendRequest('unauth', {}, function () { }); } } this.reduceReconnectDelayIfAdminCredential_(token); }; PersistentConnection.prototype.reduceReconnectDelayIfAdminCredential_ = function (credential) { // NOTE: This isn't intended to be bulletproof (a malicious developer can always just modify the client). // Additionally, we don't bother resetting the max delay back to the default if auth fails / expires. var isFirebaseSecret = credential && credential.length === 40; if (isFirebaseSecret || Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["q" /* isAdmin */])(credential)) { this.log_('Admin auth credential detected. Reducing max reconnect time.'); this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS; } }; /** * Attempts to authenticate with the given credentials. If the authentication attempt fails, it's triggered like * a auth revoked (the connection is closed). */ PersistentConnection.prototype.tryAuth = function () { var _this = this; if (this.connected_ && this.authToken_) { var token_1 = this.authToken_; var authMethod = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["C" /* isValidFormat */])(token_1) ? 'auth' : 'gauth'; var requestData = { cred: token_1 }; if (this.authOverride_ === null) { requestData['noauth'] = true; } else if (typeof this.authOverride_ === 'object') { requestData['authvar'] = this.authOverride_; } this.sendRequest(authMethod, requestData, function (res) { var status = res[ /*status*/'s']; var data = res[ /*data*/'d'] || 'error'; if (_this.authToken_ === token_1) { if (status === 'ok') { _this.invalidAuthTokenCount_ = 0; } else { // Triggers reconnect and force refresh for auth token _this.onAuthRevoked_(status, data); } } }); } }; /** * @inheritDoc */ PersistentConnection.prototype.unlisten = function (query, tag) { var pathString = query.path.toString(); var queryId = query.queryIdentifier(); this.log_('Unlisten called for ' + pathString + ' ' + queryId); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), 'unlisten() called for non-default but complete query'); var listen = this.removeListen_(pathString, queryId); if (listen && this.connected_) { this.sendUnlisten_(pathString, queryId, query.queryObject(), tag); } }; PersistentConnection.prototype.sendUnlisten_ = function (pathString, queryId, queryObj, tag) { this.log_('Unlisten on ' + pathString + ' for ' + queryId); var req = { /*path*/ p: pathString }; var action = 'n'; // Only bother sending queryId if it's non-default. if (tag) { req['q'] = queryObj; req['t'] = tag; } this.sendRequest(action, req); }; /** * @inheritDoc */ PersistentConnection.prototype.onDisconnectPut = function (pathString, data, onComplete) { if (this.connected_) { this.sendOnDisconnect_('o', pathString, data, onComplete); } else { this.onDisconnectRequestQueue_.push({ pathString: pathString, action: 'o', data: data, onComplete: onComplete }); } }; /** * @inheritDoc */ PersistentConnection.prototype.onDisconnectMerge = function (pathString, data, onComplete) { if (this.connected_) { this.sendOnDisconnect_('om', pathString, data, onComplete); } else { this.onDisconnectRequestQueue_.push({ pathString: pathString, action: 'om', data: data, onComplete: onComplete }); } }; /** * @inheritDoc */ PersistentConnection.prototype.onDisconnectCancel = function (pathString, onComplete) { if (this.connected_) { this.sendOnDisconnect_('oc', pathString, null, onComplete); } else { this.onDisconnectRequestQueue_.push({ pathString: pathString, action: 'oc', data: null, onComplete: onComplete }); } }; PersistentConnection.prototype.sendOnDisconnect_ = function (action, pathString, data, onComplete) { var request = { /*path*/ p: pathString, /*data*/ d: data }; this.log_('onDisconnect ' + action, request); this.sendRequest(action, request, function (response) { if (onComplete) { setTimeout(function () { onComplete(response[ /*status*/'s'], response[ /* data */'d']); }, Math.floor(0)); } }); }; /** * @inheritDoc */ PersistentConnection.prototype.put = function (pathString, data, onComplete, hash) { this.putInternal('p', pathString, data, onComplete, hash); }; /** * @inheritDoc */ PersistentConnection.prototype.merge = function (pathString, data, onComplete, hash) { this.putInternal('m', pathString, data, onComplete, hash); }; PersistentConnection.prototype.putInternal = function (action, pathString, data, onComplete, hash) { var request = { /*path*/ p: pathString, /*data*/ d: data }; if (hash !== undefined) { request[ /*hash*/'h'] = hash; } // TODO: Only keep track of the most recent put for a given path? this.outstandingPuts_.push({ action: action, request: request, onComplete: onComplete }); this.outstandingPutCount_++; var index = this.outstandingPuts_.length - 1; if (this.connected_) { this.sendPut_(index); } else { this.log_('Buffering put: ' + pathString); } }; PersistentConnection.prototype.sendPut_ = function (index) { var _this = this; var action = this.outstandingPuts_[index].action; var request = this.outstandingPuts_[index].request; var onComplete = this.outstandingPuts_[index].onComplete; this.outstandingPuts_[index].queued = this.connected_; this.sendRequest(action, request, function (message) { _this.log_(action + ' response', message); delete _this.outstandingPuts_[index]; _this.outstandingPutCount_--; // Clean up array occasionally. if (_this.outstandingPutCount_ === 0) { _this.outstandingPuts_ = []; } if (onComplete) { onComplete(message[ /*status*/'s'], message[ /* data */'d']); } }); }; /** * @inheritDoc */ PersistentConnection.prototype.reportStats = function (stats) { var _this = this; // If we're not connected, we just drop the stats. if (this.connected_) { var request = { /*counters*/ c: stats }; this.log_('reportStats', request); this.sendRequest(/*stats*/ 's', request, function (result) { var status = result[ /*status*/'s']; if (status !== 'ok') { var errorReason = result[ /* data */'d']; _this.log_('reportStats', 'Error sending stats: ' + errorReason); } }); } }; PersistentConnection.prototype.onDataMessage_ = function (message) { if ('r' in message) { // this is a response this.log_('from server: ' + Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(message)); var reqNum = message['r']; var onResponse = this.requestCBHash_[reqNum]; if (onResponse) { delete this.requestCBHash_[reqNum]; onResponse(message[ /*body*/'b']); } } else if ('error' in message) { throw 'A server-side error has occurred: ' + message['error']; } else if ('a' in message) { // a and b are action and body, respectively this.onDataPush_(message['a'], message['b']); } }; PersistentConnection.prototype.onDataPush_ = function (action, body) { this.log_('handleServerMessage', action, body); if (action === 'd') { this.onDataUpdate_(body[ /*path*/'p'], body[ /*data*/'d'], /*isMerge*/ false, body['t']); } else if (action === 'm') { this.onDataUpdate_(body[ /*path*/'p'], body[ /*data*/'d'], /*isMerge=*/ true, body['t']); } else if (action === 'c') { this.onListenRevoked_(body[ /*path*/'p'], body[ /*query*/'q']); } else if (action === 'ac') { this.onAuthRevoked_(body[ /*status code*/'s'], body[ /* explanation */'d']); } else if (action === 'sd') { this.onSecurityDebugPacket_(body); } else { error('Unrecognized action received from server: ' + Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(action) + '\nAre you using the latest client?'); } }; PersistentConnection.prototype.onReady_ = function (timestamp, sessionId) { this.log_('connection ready'); this.connected_ = true; this.lastConnectionEstablishedTime_ = new Date().getTime(); this.handleTimestamp_(timestamp); this.lastSessionId = sessionId; if (this.firstConnection_) { this.sendConnectStats_(); } this.restoreState_(); this.firstConnection_ = false; this.onConnectStatus_(true); }; PersistentConnection.prototype.scheduleConnect_ = function (timeout) { var _this = this; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(!this.realtime_, "Scheduling a connect when we're already connected/ing?"); if (this.establishConnectionTimer_) { clearTimeout(this.establishConnectionTimer_); } // NOTE: Even when timeout is 0, it's important to do a setTimeout to work around an infuriating "Security Error" in // Firefox when trying to write to our long-polling iframe in some scenarios (e.g. Forge or our unit tests). this.establishConnectionTimer_ = setTimeout(function () { _this.establishConnectionTimer_ = null; _this.establishConnection_(); // eslint-disable-next-line @typescript-eslint/no-explicit-any }, Math.floor(timeout)); }; PersistentConnection.prototype.onVisible_ = function (visible) { // NOTE: Tabbing away and back to a window will defeat our reconnect backoff, but I think that's fine. if (visible && !this.visible_ && this.reconnectDelay_ === this.maxReconnectDelay_) { this.log_('Window became visible. Reducing delay.'); this.reconnectDelay_ = RECONNECT_MIN_DELAY; if (!this.realtime_) { this.scheduleConnect_(0); } } this.visible_ = visible; }; PersistentConnection.prototype.onOnline_ = function (online) { if (online) { this.log_('Browser went online.'); this.reconnectDelay_ = RECONNECT_MIN_DELAY; if (!this.realtime_) { this.scheduleConnect_(0); } } else { this.log_('Browser went offline. Killing connection.'); if (this.realtime_) { this.realtime_.close(); } } }; PersistentConnection.prototype.onRealtimeDisconnect_ = function () { this.log_('data client disconnected'); this.connected_ = false; this.realtime_ = null; // Since we don't know if our sent transactions succeeded or not, we need to cancel them. this.cancelSentTransactions_(); // Clear out the pending requests. this.requestCBHash_ = {}; if (this.shouldReconnect_()) { if (!this.visible_) { this.log_("Window isn't visible. Delaying reconnect."); this.reconnectDelay_ = this.maxReconnectDelay_; this.lastConnectionAttemptTime_ = new Date().getTime(); } else if (this.lastConnectionEstablishedTime_) { // If we've been connected long enough, reset reconnect delay to minimum. var timeSinceLastConnectSucceeded = new Date().getTime() - this.lastConnectionEstablishedTime_; if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT) { this.reconnectDelay_ = RECONNECT_MIN_DELAY; } this.lastConnectionEstablishedTime_ = null; } var timeSinceLastConnectAttempt = new Date().getTime() - this.lastConnectionAttemptTime_; var reconnectDelay = Math.max(0, this.reconnectDelay_ - timeSinceLastConnectAttempt); reconnectDelay = Math.random() * reconnectDelay; this.log_('Trying to reconnect in ' + reconnectDelay + 'ms'); this.scheduleConnect_(reconnectDelay); // Adjust reconnect delay for next time. this.reconnectDelay_ = Math.min(this.maxReconnectDelay_, this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER); } this.onConnectStatus_(false); }; PersistentConnection.prototype.establishConnection_ = function () { var _this = this; if (this.shouldReconnect_()) { this.log_('Making a connection attempt'); this.lastConnectionAttemptTime_ = new Date().getTime(); this.lastConnectionEstablishedTime_ = null; var onDataMessage_1 = this.onDataMessage_.bind(this); var onReady_1 = this.onReady_.bind(this); var onDisconnect_1 = this.onRealtimeDisconnect_.bind(this); var connId_1 = this.id + ':' + PersistentConnection.nextConnectionId_++; var self_1 = this; var lastSessionId_1 = this.lastSessionId; var canceled_1 = false; var connection_1 = null; var closeFn_1 = function () { if (connection_1) { connection_1.close(); } else { canceled_1 = true; onDisconnect_1(); } }; var sendRequestFn = function (msg) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(connection_1, "sendRequest call when we're not connected not allowed."); connection_1.sendRequest(msg); }; this.realtime_ = { close: closeFn_1, sendRequest: sendRequestFn }; var forceRefresh = this.forceTokenRefresh_; this.forceTokenRefresh_ = false; // First fetch auth token, and establish connection after fetching the token was successful this.authTokenProvider_ .getToken(forceRefresh) .then(function (result) { if (!canceled_1) { log('getToken() completed. Creating connection.'); self_1.authToken_ = result && result.accessToken; connection_1 = new Connection(connId_1, self_1.repoInfo_, self_1.applicationId_, onDataMessage_1, onReady_1, onDisconnect_1, /* onKill= */ function (reason) { warn(reason + ' (' + self_1.repoInfo_.toString() + ')'); self_1.interrupt(SERVER_KILL_INTERRUPT_REASON); }, lastSessionId_1); } else { log('getToken() completed but was canceled'); } }) .then(null, function (error) { self_1.log_('Failed to get token: ' + error); if (!canceled_1) { if (_this.repoInfo_.nodeAdmin) { // This may be a critical error for the Admin Node.js SDK, so log a warning. // But getToken() may also just have temporarily failed, so we still want to // continue retrying. warn(error); } closeFn_1(); } }); } }; PersistentConnection.prototype.interrupt = function (reason) { log('Interrupting connection for reason: ' + reason); this.interruptReasons_[reason] = true; if (this.realtime_) { this.realtime_.close(); } else { if (this.establishConnectionTimer_) { clearTimeout(this.establishConnectionTimer_); this.establishConnectionTimer_ = null; } if (this.connected_) { this.onRealtimeDisconnect_(); } } }; PersistentConnection.prototype.resume = function (reason) { log('Resuming connection for reason: ' + reason); delete this.interruptReasons_[reason]; if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["u" /* isEmpty */])(this.interruptReasons_)) { this.reconnectDelay_ = RECONNECT_MIN_DELAY; if (!this.realtime_) { this.scheduleConnect_(0); } } }; PersistentConnection.prototype.handleTimestamp_ = function (timestamp) { var delta = timestamp - new Date().getTime(); this.onServerInfoUpdate_({ serverTimeOffset: delta }); }; PersistentConnection.prototype.cancelSentTransactions_ = function () { for (var i = 0; i < this.outstandingPuts_.length; i++) { var put = this.outstandingPuts_[i]; if (put && /*hash*/ 'h' in put.request && put.queued) { if (put.onComplete) { put.onComplete('disconnect'); } delete this.outstandingPuts_[i]; this.outstandingPutCount_--; } } // Clean up array occasionally. if (this.outstandingPutCount_ === 0) { this.outstandingPuts_ = []; } }; PersistentConnection.prototype.onListenRevoked_ = function (pathString, query) { // Remove the listen and manufacture a "permission_denied" error for the failed listen. var queryId; if (!query) { queryId = 'default'; } else { queryId = query.map(function (q) { return ObjectToUniqueKey(q); }).join('$'); } var listen = this.removeListen_(pathString, queryId); if (listen && listen.onComplete) { listen.onComplete('permission_denied'); } }; PersistentConnection.prototype.removeListen_ = function (pathString, queryId) { var normalizedPathString = new Path(pathString).toString(); // normalize path. var listen; if (this.listens.has(normalizedPathString)) { var map = this.listens.get(normalizedPathString); listen = map.get(queryId); map.delete(queryId); if (map.size === 0) { this.listens.delete(normalizedPathString); } } else { // all listens for this path has already been removed listen = undefined; } return listen; }; PersistentConnection.prototype.onAuthRevoked_ = function (statusCode, explanation) { log('Auth token revoked: ' + statusCode + '/' + explanation); this.authToken_ = null; this.forceTokenRefresh_ = true; this.realtime_.close(); if (statusCode === 'invalid_token' || statusCode === 'permission_denied') { // We'll wait a couple times before logging the warning / increasing the // retry period since oauth tokens will report as "invalid" if they're // just expired. Plus there may be transient issues that resolve themselves. this.invalidAuthTokenCount_++; if (this.invalidAuthTokenCount_ >= INVALID_AUTH_TOKEN_THRESHOLD) { // Set a long reconnect delay because recovery is unlikely this.reconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS; // Notify the auth token provider that the token is invalid, which will log // a warning this.authTokenProvider_.notifyForInvalidToken(); } } }; PersistentConnection.prototype.onSecurityDebugPacket_ = function (body) { if (this.securityDebugCallback_) { this.securityDebugCallback_(body); } else { if ('msg' in body) { console.log('FIREBASE: ' + body['msg'].replace('\n', '\nFIREBASE: ')); } } }; PersistentConnection.prototype.restoreState_ = function () { var e_1, _a, e_2, _b; //Re-authenticate ourselves if we have a credential stored. this.tryAuth(); try { // Puts depend on having received the corresponding data update from the server before they complete, so we must // make sure to send listens before puts. for (var _c = Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["g" /* __values */])(this.listens.values()), _d = _c.next(); !_d.done; _d = _c.next()) { var queries = _d.value; try { for (var _e = (e_2 = void 0, Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["g" /* __values */])(queries.values())), _f = _e.next(); !_f.done; _f = _e.next()) { var listenSpec = _f.value; this.sendListen_(listenSpec); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_2) throw e_2.error; } } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_1) throw e_1.error; } } for (var i = 0; i < this.outstandingPuts_.length; i++) { if (this.outstandingPuts_[i]) { this.sendPut_(i); } } while (this.onDisconnectRequestQueue_.length) { var request = this.onDisconnectRequestQueue_.shift(); this.sendOnDisconnect_(request.action, request.pathString, request.data, request.onComplete); } for (var i = 0; i < this.outstandingGets_.length; i++) { if (this.outstandingGets_[i]) { this.sendGet_(i); } } }; /** * Sends client stats for first connection */ PersistentConnection.prototype.sendConnectStats_ = function () { var stats = {}; var clientName = 'js'; if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["z" /* isNodeSdk */])()) { if (this.repoInfo_.nodeAdmin) { clientName = 'admin_node'; } else { clientName = 'node'; } } stats['sdk.' + clientName + '.' + SDK_VERSION.replace(/\./g, '-')] = 1; if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["x" /* isMobileCordova */])()) { stats['framework.cordova'] = 1; } else if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["A" /* isReactNative */])()) { stats['framework.reactnative'] = 1; } this.reportStats(stats); }; PersistentConnection.prototype.shouldReconnect_ = function () { var online = OnlineMonitor.getInstance().currentlyOnline(); return Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["u" /* isEmpty */])(this.interruptReasons_) && online; }; PersistentConnection.nextPersistentConnectionId_ = 0; /** * Counter for number of connections created. Mainly used for tagging in the logs */ PersistentConnection.nextConnectionId_ = 0; return PersistentConnection; }(ServerActions)); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * An implementation of ServerActions that communicates with the server via REST requests. * This is mostly useful for compatibility with crawlers, where we don't want to spin up a full * persistent connection (using WebSockets or long-polling) */ var ReadonlyRestClient = /** @class */ (function (_super) { Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __extends */])(ReadonlyRestClient, _super); /** * @param repoInfo_ Data about the namespace we are connecting to * @param onDataUpdate_ A callback for new data from the server */ function ReadonlyRestClient(repoInfo_, onDataUpdate_, authTokenProvider_) { var _this = _super.call(this) || this; _this.repoInfo_ = repoInfo_; _this.onDataUpdate_ = onDataUpdate_; _this.authTokenProvider_ = authTokenProvider_; /** @private {function(...[*])} */ _this.log_ = logWrapper('p:rest:'); /** * We don't actually need to track listens, except to prevent us calling an onComplete for a listen * that's been removed. :-/ */ _this.listens_ = {}; return _this; } ReadonlyRestClient.prototype.reportStats = function (stats) { throw new Error('Method not implemented.'); }; ReadonlyRestClient.getListenId_ = function (query, tag) { if (tag !== undefined) { return 'tag$' + tag; } else { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(query.getQueryParams().isDefault(), "should have a tag if it's not a default query."); return query.path.toString(); } }; /** @inheritDoc */ ReadonlyRestClient.prototype.listen = function (query, currentHashFn, tag, onComplete) { var _this = this; var pathString = query.path.toString(); this.log_('Listen called for ' + pathString + ' ' + query.queryIdentifier()); // Mark this listener so we can tell if it's removed. var listenId = ReadonlyRestClient.getListenId_(query, tag); var thisListen = {}; this.listens_[listenId] = thisListen; var queryStringParameters = queryParamsToRestQueryStringParameters(query.getQueryParams()); this.restRequest_(pathString + '.json', queryStringParameters, function (error, result) { var data = result; if (error === 404) { data = null; error = null; } if (error === null) { _this.onDataUpdate_(pathString, data, /*isMerge=*/ false, tag); } if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(_this.listens_, listenId) === thisListen) { var status_1; if (!error) { status_1 = 'ok'; } else if (error === 401) { status_1 = 'permission_denied'; } else { status_1 = 'rest_error:' + error; } onComplete(status_1, null); } }); }; /** @inheritDoc */ ReadonlyRestClient.prototype.unlisten = function (query, tag) { var listenId = ReadonlyRestClient.getListenId_(query, tag); delete this.listens_[listenId]; }; ReadonlyRestClient.prototype.get = function (query) { var _this = this; var queryStringParameters = queryParamsToRestQueryStringParameters(query.getQueryParams()); var pathString = query.path.toString(); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); this.restRequest_(pathString + '.json', queryStringParameters, function (error, result) { var data = result; if (error === 404) { data = null; error = null; } if (error === null) { _this.onDataUpdate_(pathString, data, /*isMerge=*/ false, /*tag=*/ null); deferred.resolve(data); } else { deferred.reject(new Error(data)); } }); return deferred.promise; }; /** @inheritDoc */ ReadonlyRestClient.prototype.refreshAuthToken = function (token) { // no-op since we just always call getToken. }; /** * Performs a REST request to the given path, with the provided query string parameters, * and any auth credentials we have. */ ReadonlyRestClient.prototype.restRequest_ = function (pathString, queryStringParameters, callback) { var _this = this; if (queryStringParameters === void 0) { queryStringParameters = {}; } queryStringParameters['format'] = 'export'; this.authTokenProvider_ .getToken(/*forceRefresh=*/ false) .then(function (authTokenData) { var authToken = authTokenData && authTokenData.accessToken; if (authToken) { queryStringParameters['auth'] = authToken; } var url = (_this.repoInfo_.secure ? 'https://' : 'http://') + _this.repoInfo_.host + pathString + '?' + 'ns=' + _this.repoInfo_.namespace + Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["F" /* querystring */])(queryStringParameters); _this.log_('Sending REST request for ' + url); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (callback && xhr.readyState === 4) { _this.log_('REST Response for ' + url + ' received. status:', xhr.status, 'response:', xhr.responseText); var res = null; if (xhr.status >= 200 && xhr.status < 300) { try { res = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["D" /* jsonEval */])(xhr.responseText); } catch (e) { warn('Failed to parse JSON response for ' + url + ': ' + xhr.responseText); } callback(null, res); } else { // 401 and 404 are expected. if (xhr.status !== 401 && xhr.status !== 404) { warn('Got unsuccessful REST response for ' + url + ' Status: ' + xhr.status); } callback(xhr.status); } callback = null; } }; xhr.open('GET', url, /*asynchronous=*/ true); xhr.send(); }); }; return ReadonlyRestClient; }(ServerActions)); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Class representing a firebase data snapshot. It wraps a SnapshotNode and * surfaces the public methods (val, forEach, etc.) we want to expose. */ var DataSnapshot = /** @class */ (function () { /** * @param node_ A SnapshotNode to wrap. * @param ref_ The ref of the location this snapshot came from. * @param index_ The iteration order for this snapshot */ function DataSnapshot(node_, ref_, index_) { this.node_ = node_; this.ref_ = ref_; this.index_ = index_; } /** * Retrieves the snapshot contents as JSON. Returns null if the snapshot is * empty. * * @return JSON representation of the DataSnapshot contents, or null if empty. */ DataSnapshot.prototype.val = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.val', 0, 0, arguments.length); return this.node_.val(); }; /** * Returns the snapshot contents as JSON, including priorities of node. Suitable for exporting * the entire node contents. * @return JSON representation of the DataSnapshot contents, or null if empty. */ DataSnapshot.prototype.exportVal = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.exportVal', 0, 0, arguments.length); return this.node_.val(true); }; // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary // for end-users DataSnapshot.prototype.toJSON = function () { // Optional spacer argument is unnecessary because we're depending on recursion rather than stringifying the content Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.toJSON', 0, 1, arguments.length); return this.exportVal(); }; /** * Returns whether the snapshot contains a non-null value. * * @return Whether the snapshot contains a non-null value, or is empty. */ DataSnapshot.prototype.exists = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.exists', 0, 0, arguments.length); return !this.node_.isEmpty(); }; /** * Returns a DataSnapshot of the specified child node's contents. * * @param childPathString Path to a child. * @return DataSnapshot for child node. */ DataSnapshot.prototype.child = function (childPathString) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.child', 0, 1, arguments.length); // Ensure the childPath is a string (can be a number) childPathString = String(childPathString); validatePathString('DataSnapshot.child', 1, childPathString, false); var childPath = new Path(childPathString); var childRef = this.ref_.child(childPath); return new DataSnapshot(this.node_.getChild(childPath), childRef, PRIORITY_INDEX); }; /** * Returns whether the snapshot contains a child at the specified path. * * @param childPathString Path to a child. * @return Whether the child exists. */ DataSnapshot.prototype.hasChild = function (childPathString) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.hasChild', 1, 1, arguments.length); validatePathString('DataSnapshot.hasChild', 1, childPathString, false); var childPath = new Path(childPathString); return !this.node_.getChild(childPath).isEmpty(); }; /** * Returns the priority of the object, or null if no priority was set. * * @return The priority. */ DataSnapshot.prototype.getPriority = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.getPriority', 0, 0, arguments.length); // typecast here because we never return deferred values or internal priorities (MAX_PRIORITY) return this.node_.getPriority().val(); }; /** * Iterates through child nodes and calls the specified action for each one. * * @param action Callback function to be called * for each child. * @return True if forEach was canceled by action returning true for * one of the child nodes. */ DataSnapshot.prototype.forEach = function (action) { var _this = this; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.forEach', 1, 1, arguments.length); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('DataSnapshot.forEach', 1, action, false); if (this.node_.isLeafNode()) { return false; } var childrenNode = this.node_; // Sanitize the return value to a boolean. ChildrenNode.forEachChild has a weird return type... return !!childrenNode.forEachChild(this.index_, function (key, node) { return action(new DataSnapshot(node, _this.ref_.child(key), PRIORITY_INDEX)); }); }; /** * Returns whether this DataSnapshot has children. * @return True if the DataSnapshot contains 1 or more child nodes. */ DataSnapshot.prototype.hasChildren = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.hasChildren', 0, 0, arguments.length); if (this.node_.isLeafNode()) { return false; } else { return !this.node_.isEmpty(); } }; Object.defineProperty(DataSnapshot.prototype, "key", { get: function () { return this.ref_.getKey(); }, enumerable: false, configurable: true }); /** * Returns the number of children for this DataSnapshot. * @return The number of children that this DataSnapshot contains. */ DataSnapshot.prototype.numChildren = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.numChildren', 0, 0, arguments.length); return this.node_.numChildren(); }; /** * @return The Firebase reference for the location this snapshot's data came * from. */ DataSnapshot.prototype.getRef = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('DataSnapshot.ref', 0, 0, arguments.length); return this.ref_; }; Object.defineProperty(DataSnapshot.prototype, "ref", { get: function () { return this.getRef(); }, enumerable: false, configurable: true }); return DataSnapshot; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * A light-weight tree, traversable by path. Nodes can have both values and children. * Nodes are not enumerated (by forEachChild) unless they have a value or non-empty * children. */ var Tree = /** @class */ (function () { /** * @param name Optional name of the node. * @param parent Optional parent node. * @param node Optional node to wrap. */ function Tree(name, parent, node) { if (name === void 0) { name = ''; } if (parent === void 0) { parent = null; } if (node === void 0) { node = { children: {}, childCount: 0 }; } this.name = name; this.parent = parent; this.node = node; } return Tree; }()); /** * Returns a sub-Tree for the given path. * * @param pathObj Path to look up. * @return Tree for path. */ function treeSubTree(tree, pathObj) { // TODO: Require pathObj to be Path? var path = pathObj instanceof Path ? pathObj : new Path(pathObj); var child = tree, next = pathGetFront(path); while (next !== null) { var childNode = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(child.node.children, next) || { children: {}, childCount: 0 }; child = new Tree(next, child, childNode); path = pathPopFront(path); next = pathGetFront(path); } return child; } /** * Returns the data associated with this tree node. * * @return The data or null if no data exists. */ function treeGetValue(tree) { return tree.node.value; } /** * Sets data to this tree node. * * @param value Value to set. */ function treeSetValue(tree, value) { tree.node.value = value; treeUpdateParents(tree); } /** * @return Whether the tree has any children. */ function treeHasChildren(tree) { return tree.node.childCount > 0; } /** * @return Whethe rthe tree is empty (no value or children). */ function treeIsEmpty(tree) { return treeGetValue(tree) === undefined && !treeHasChildren(tree); } /** * Calls action for each child of this tree node. * * @param action Action to be called for each child. */ function treeForEachChild(tree, action) { each(tree.node.children, function (child, childTree) { action(new Tree(child, tree, childTree)); }); } /** * Does a depth-first traversal of this node's descendants, calling action for each one. * * @param action Action to be called for each child. * @param includeSelf Whether to call action on this node as well. Defaults to * false. * @param childrenFirst Whether to call action on children before calling it on * parent. */ function treeForEachDescendant(tree, action, includeSelf, childrenFirst) { if (includeSelf && !childrenFirst) { action(tree); } treeForEachChild(tree, function (child) { treeForEachDescendant(child, action, true, childrenFirst); }); if (includeSelf && childrenFirst) { action(tree); } } /** * Calls action on each ancestor node. * * @param action Action to be called on each parent; return * true to abort. * @param includeSelf Whether to call action on this node as well. * @return true if the action callback returned true. */ function treeForEachAncestor(tree, action, includeSelf) { var node = includeSelf ? tree : tree.parent; while (node !== null) { if (action(node)) { return true; } node = node.parent; } return false; } /** * @return The path of this tree node, as a Path. */ function treeGetPath(tree) { return new Path(tree.parent === null ? tree.name : treeGetPath(tree.parent) + '/' + tree.name); } /** * Adds or removes this child from its parent based on whether it's empty or not. */ function treeUpdateParents(tree) { if (tree.parent !== null) { treeUpdateChild(tree.parent, tree.name, tree); } } /** * Adds or removes the passed child to this tree node, depending on whether it's empty. * * @param childName The name of the child to update. * @param child The child to update. */ function treeUpdateChild(tree, childName, child) { var childEmpty = treeIsEmpty(child); var childExists = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["k" /* contains */])(tree.node.children, childName); if (childEmpty && childExists) { delete tree.node.children[childName]; tree.node.childCount--; treeUpdateParents(tree); } else if (!childEmpty && !childExists) { tree.node.children[childName] = child.node; tree.node.childCount++; treeUpdateParents(tree); } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var INTERRUPT_REASON = 'repo_interrupt'; /** * If a transaction does not succeed after 25 retries, we abort it. Among other * things this ensure that if there's ever a bug causing a mismatch between * client / server hashes for some data, we won't retry indefinitely. */ var MAX_TRANSACTION_RETRIES = 25; /** * A connection to a single data repository. */ var Repo = /** @class */ (function () { function Repo(repoInfo_, forceRestClient_, app, authTokenProvider_) { this.repoInfo_ = repoInfo_; this.forceRestClient_ = forceRestClient_; this.app = app; this.authTokenProvider_ = authTokenProvider_; this.dataUpdateCount = 0; this.statsListener_ = null; this.eventQueue_ = new EventQueue(); this.nextWriteId_ = 1; this.interceptServerDataCallback_ = null; /** A list of data pieces and paths to be set when this client disconnects. */ this.onDisconnect_ = newSparseSnapshotTree(); /** Stores queues of outstanding transactions for Firebase locations. */ this.transactionQueueTree_ = new Tree(); // TODO: This should be @private but it's used by test_access.js and internal.js this.persistentConnection_ = null; // This key is intentionally not updated if RepoInfo is later changed or replaced this.key = this.repoInfo_.toURLString(); } /** * @return The URL corresponding to the root of this Firebase. */ Repo.prototype.toString = function () { return ((this.repoInfo_.secure ? 'https://' : 'http://') + this.repoInfo_.host); }; return Repo; }()); function repoStart(repo) { repo.stats_ = statsManagerGetCollection(repo.repoInfo_); if (repo.forceRestClient_ || beingCrawled()) { repo.server_ = new ReadonlyRestClient(repo.repoInfo_, function (pathString, data, isMerge, tag) { repoOnDataUpdate(repo, pathString, data, isMerge, tag); }, repo.authTokenProvider_); // Minor hack: Fire onConnect immediately, since there's no actual connection. setTimeout(function () { return repoOnConnectStatus(repo, /* connectStatus= */ true); }, 0); } else { var authOverride = repo.app.options['databaseAuthVariableOverride']; // Validate authOverride if (typeof authOverride !== 'undefined' && authOverride !== null) { if (typeof authOverride !== 'object') { throw new Error('Only objects are supported for option databaseAuthVariableOverride'); } try { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(authOverride); } catch (e) { throw new Error('Invalid authOverride provided: ' + e); } } repo.persistentConnection_ = new PersistentConnection(repo.repoInfo_, repo.app.options.appId, function (pathString, data, isMerge, tag) { repoOnDataUpdate(repo, pathString, data, isMerge, tag); }, function (connectStatus) { repoOnConnectStatus(repo, connectStatus); }, function (updates) { repoOnServerInfoUpdate(repo, updates); }, repo.authTokenProvider_, authOverride); repo.server_ = repo.persistentConnection_; } repo.authTokenProvider_.addTokenChangeListener(function (token) { repo.server_.refreshAuthToken(token); }); // In the case of multiple Repos for the same repoInfo (i.e. there are multiple Firebase.Contexts being used), // we only want to create one StatsReporter. As such, we'll report stats over the first Repo created. repo.statsReporter_ = statsManagerGetOrCreateReporter(repo.repoInfo_, function () { return new StatsReporter(repo.stats_, repo.server_); }); // Used for .info. repo.infoData_ = new SnapshotHolder(); repo.infoSyncTree_ = new SyncTree({ startListening: function (query, tag, currentHashFn, onComplete) { var infoEvents = []; var node = repo.infoData_.getNode(query.path); // This is possibly a hack, but we have different semantics for .info endpoints. We don't raise null events // on initial data... if (!node.isEmpty()) { infoEvents = syncTreeApplyServerOverwrite(repo.infoSyncTree_, query.path, node); setTimeout(function () { onComplete('ok'); }, 0); } return infoEvents; }, stopListening: function () { } }); repoUpdateInfo(repo, 'connected', false); repo.serverSyncTree_ = new SyncTree({ startListening: function (query, tag, currentHashFn, onComplete) { repo.server_.listen(query, currentHashFn, tag, function (status, data) { var events = onComplete(status, data); eventQueueRaiseEventsForChangedPath(repo.eventQueue_, query.path, events); }); // No synchronous events for network-backed sync trees return []; }, stopListening: function (query, tag) { repo.server_.unlisten(query, tag); } }); } /** * @return The time in milliseconds, taking the server offset into account if we have one. */ function repoServerTime(repo) { var offsetNode = repo.infoData_.getNode(new Path('.info/serverTimeOffset')); var offset = offsetNode.val() || 0; return new Date().getTime() + offset; } /** * Generate ServerValues using some variables from the repo object. */ function repoGenerateServerValues(repo) { return generateWithValues({ timestamp: repoServerTime(repo) }); } /** * Called by realtime when we get new messages from the server. */ function repoOnDataUpdate(repo, pathString, data, isMerge, tag) { // For testing. repo.dataUpdateCount++; var path = new Path(pathString); data = repo.interceptServerDataCallback_ ? repo.interceptServerDataCallback_(pathString, data) : data; var events = []; if (tag) { if (isMerge) { var taggedChildren = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["E" /* map */])(data, function (raw) { return nodeFromJSON$1(raw); }); events = syncTreeApplyTaggedQueryMerge(repo.serverSyncTree_, path, taggedChildren, tag); } else { var taggedSnap = nodeFromJSON$1(data); events = syncTreeApplyTaggedQueryOverwrite(repo.serverSyncTree_, path, taggedSnap, tag); } } else if (isMerge) { var changedChildren = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["E" /* map */])(data, function (raw) { return nodeFromJSON$1(raw); }); events = syncTreeApplyServerMerge(repo.serverSyncTree_, path, changedChildren); } else { var snap = nodeFromJSON$1(data); events = syncTreeApplyServerOverwrite(repo.serverSyncTree_, path, snap); } var affectedPath = path; if (events.length > 0) { // Since we have a listener outstanding for each transaction, receiving any events // is a proxy for some change having occurred. affectedPath = repoRerunTransactions(repo, path); } eventQueueRaiseEventsForChangedPath(repo.eventQueue_, affectedPath, events); } // TODO: This should be @private but it's used by test_access.js and internal.js function repoInterceptServerData(repo, callback) { repo.interceptServerDataCallback_ = callback; } function repoOnConnectStatus(repo, connectStatus) { repoUpdateInfo(repo, 'connected', connectStatus); if (connectStatus === false) { repoRunOnDisconnectEvents(repo); } } function repoOnServerInfoUpdate(repo, updates) { each(updates, function (key, value) { repoUpdateInfo(repo, key, value); }); } function repoUpdateInfo(repo, pathString, value) { var path = new Path('/.info/' + pathString); var newNode = nodeFromJSON$1(value); repo.infoData_.updateSnapshot(path, newNode); var events = syncTreeApplyServerOverwrite(repo.infoSyncTree_, path, newNode); eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); } function repoGetNextWriteId(repo) { return repo.nextWriteId_++; } /** * The purpose of `getValue` is to return the latest known value * satisfying `query`. * * This method will first check for in-memory cached values * belonging to active listeners. If they are found, such values * are considered to be the most up-to-date. * * If the client is not connected, this method will try to * establish a connection and request the value for `query`. If * the client is not able to retrieve the query result, it reports * an error. * * @param query - The query to surface a value for. */ function repoGetValue(repo, query) { // Only active queries are cached. There is no persisted cache. var cached = syncTreeGetServerValue(repo.serverSyncTree_, query); if (cached != null) { return Promise.resolve(new DataSnapshot(cached, query.getRef(), query.getQueryParams().getIndex())); } return repo.server_.get(query).then(function (payload) { var node = nodeFromJSON$1(payload); var events = syncTreeApplyServerOverwrite(repo.serverSyncTree_, query.path, node); eventQueueRaiseEventsAtPath(repo.eventQueue_, query.path, events); return Promise.resolve(new DataSnapshot(node, query.getRef(), query.getQueryParams().getIndex())); }, function (err) { repoLog(repo, 'get for query ' + Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(query) + ' failed: ' + err); return Promise.reject(new Error(err)); }); } function repoSetWithPriority(repo, path, newVal, newPriority, onComplete) { repoLog(repo, 'set', { path: path.toString(), value: newVal, priority: newPriority }); // TODO: Optimize this behavior to either (a) store flag to skip resolving where possible and / or // (b) store unresolved paths on JSON parse var serverValues = repoGenerateServerValues(repo); var newNodeUnresolved = nodeFromJSON$1(newVal, newPriority); var existing = syncTreeCalcCompleteEventCache(repo.serverSyncTree_, path); var newNode = resolveDeferredValueSnapshot(newNodeUnresolved, existing, serverValues); var writeId = repoGetNextWriteId(repo); var events = syncTreeApplyUserOverwrite(repo.serverSyncTree_, path, newNode, writeId, true); eventQueueQueueEvents(repo.eventQueue_, events); repo.server_.put(path.toString(), newNodeUnresolved.val(/*export=*/ true), function (status, errorReason) { var success = status === 'ok'; if (!success) { warn('set at ' + path + ' failed: ' + status); } var clearEvents = syncTreeAckUserWrite(repo.serverSyncTree_, writeId, !success); eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, clearEvents); repoCallOnCompleteCallback(repo, onComplete, status, errorReason); }); var affectedPath = repoAbortTransactions(repo, path); repoRerunTransactions(repo, affectedPath); // We queued the events above, so just flush the queue here eventQueueRaiseEventsForChangedPath(repo.eventQueue_, affectedPath, []); } function repoUpdate(repo, path, childrenToMerge, onComplete) { repoLog(repo, 'update', { path: path.toString(), value: childrenToMerge }); // Start with our existing data and merge each child into it. var empty = true; var serverValues = repoGenerateServerValues(repo); var changedChildren = {}; each(childrenToMerge, function (changedKey, changedValue) { empty = false; changedChildren[changedKey] = resolveDeferredValueTree(pathChild(path, changedKey), nodeFromJSON$1(changedValue), repo.serverSyncTree_, serverValues); }); if (!empty) { var writeId_1 = repoGetNextWriteId(repo); var events = syncTreeApplyUserMerge(repo.serverSyncTree_, path, changedChildren, writeId_1); eventQueueQueueEvents(repo.eventQueue_, events); repo.server_.merge(path.toString(), childrenToMerge, function (status, errorReason) { var success = status === 'ok'; if (!success) { warn('update at ' + path + ' failed: ' + status); } var clearEvents = syncTreeAckUserWrite(repo.serverSyncTree_, writeId_1, !success); var affectedPath = clearEvents.length > 0 ? repoRerunTransactions(repo, path) : path; eventQueueRaiseEventsForChangedPath(repo.eventQueue_, affectedPath, clearEvents); repoCallOnCompleteCallback(repo, onComplete, status, errorReason); }); each(childrenToMerge, function (changedPath) { var affectedPath = repoAbortTransactions(repo, pathChild(path, changedPath)); repoRerunTransactions(repo, affectedPath); }); // We queued the events above, so just flush the queue here eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, []); } else { log("update() called with empty data. Don't do anything."); repoCallOnCompleteCallback(repo, onComplete, 'ok', undefined); } } /** * Applies all of the changes stored up in the onDisconnect_ tree. */ function repoRunOnDisconnectEvents(repo) { repoLog(repo, 'onDisconnectEvents'); var serverValues = repoGenerateServerValues(repo); var resolvedOnDisconnectTree = newSparseSnapshotTree(); sparseSnapshotTreeForEachTree(repo.onDisconnect_, newEmptyPath(), function (path, node) { var resolved = resolveDeferredValueTree(path, node, repo.serverSyncTree_, serverValues); sparseSnapshotTreeRemember(resolvedOnDisconnectTree, path, resolved); }); var events = []; sparseSnapshotTreeForEachTree(resolvedOnDisconnectTree, newEmptyPath(), function (path, snap) { events = events.concat(syncTreeApplyServerOverwrite(repo.serverSyncTree_, path, snap)); var affectedPath = repoAbortTransactions(repo, path); repoRerunTransactions(repo, affectedPath); }); repo.onDisconnect_ = newSparseSnapshotTree(); eventQueueRaiseEventsForChangedPath(repo.eventQueue_, newEmptyPath(), events); } function repoOnDisconnectCancel(repo, path, onComplete) { repo.server_.onDisconnectCancel(path.toString(), function (status, errorReason) { if (status === 'ok') { sparseSnapshotTreeForget(repo.onDisconnect_, path); } repoCallOnCompleteCallback(repo, onComplete, status, errorReason); }); } function repoOnDisconnectSet(repo, path, value, onComplete) { var newNode = nodeFromJSON$1(value); repo.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/ true), function (status, errorReason) { if (status === 'ok') { sparseSnapshotTreeRemember(repo.onDisconnect_, path, newNode); } repoCallOnCompleteCallback(repo, onComplete, status, errorReason); }); } function repoOnDisconnectSetWithPriority(repo, path, value, priority, onComplete) { var newNode = nodeFromJSON$1(value, priority); repo.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/ true), function (status, errorReason) { if (status === 'ok') { sparseSnapshotTreeRemember(repo.onDisconnect_, path, newNode); } repoCallOnCompleteCallback(repo, onComplete, status, errorReason); }); } function repoOnDisconnectUpdate(repo, path, childrenToMerge, onComplete) { if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["u" /* isEmpty */])(childrenToMerge)) { log("onDisconnect().update() called with empty data. Don't do anything."); repoCallOnCompleteCallback(repo, onComplete, 'ok', undefined); return; } repo.server_.onDisconnectMerge(path.toString(), childrenToMerge, function (status, errorReason) { if (status === 'ok') { each(childrenToMerge, function (childName, childNode) { var newChildNode = nodeFromJSON$1(childNode); sparseSnapshotTreeRemember(repo.onDisconnect_, pathChild(path, childName), newChildNode); }); } repoCallOnCompleteCallback(repo, onComplete, status, errorReason); }); } function repoAddEventCallbackForQuery(repo, query, eventRegistration) { var events; if (pathGetFront(query.path) === '.info') { events = syncTreeAddEventRegistration(repo.infoSyncTree_, query, eventRegistration); } else { events = syncTreeAddEventRegistration(repo.serverSyncTree_, query, eventRegistration); } eventQueueRaiseEventsAtPath(repo.eventQueue_, query.path, events); } function repoRemoveEventCallbackForQuery(repo, query, eventRegistration) { // These are guaranteed not to raise events, since we're not passing in a cancelError. However, we can future-proof // a little bit by handling the return values anyways. var events; if (pathGetFront(query.path) === '.info') { events = syncTreeRemoveEventRegistration(repo.infoSyncTree_, query, eventRegistration); } else { events = syncTreeRemoveEventRegistration(repo.serverSyncTree_, query, eventRegistration); } eventQueueRaiseEventsAtPath(repo.eventQueue_, query.path, events); } function repoInterrupt(repo) { if (repo.persistentConnection_) { repo.persistentConnection_.interrupt(INTERRUPT_REASON); } } function repoResume(repo) { if (repo.persistentConnection_) { repo.persistentConnection_.resume(INTERRUPT_REASON); } } function repoStats(repo, showDelta) { if (showDelta === void 0) { showDelta = false; } if (typeof console === 'undefined') { return; } var stats; if (showDelta) { if (!repo.statsListener_) { repo.statsListener_ = new StatsListener(repo.stats_); } stats = repo.statsListener_.get(); } else { stats = repo.stats_.get(); } var longestName = Object.keys(stats).reduce(function (previousValue, currentValue) { return Math.max(currentValue.length, previousValue); }, 0); each(stats, function (stat, value) { var paddedStat = stat; // pad stat names to be the same length (plus 2 extra spaces). for (var i = stat.length; i < longestName + 2; i++) { paddedStat += ' '; } console.log(paddedStat + value); }); } function repoStatsIncrementCounter(repo, metric) { repo.stats_.incrementCounter(metric); statsReporterIncludeStat(repo.statsReporter_, metric); } function repoLog(repo) { var varArgs = []; for (var _i = 1; _i < arguments.length; _i++) { varArgs[_i - 1] = arguments[_i]; } var prefix = ''; if (repo.persistentConnection_) { prefix = repo.persistentConnection_.id + ':'; } log.apply(void 0, Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["f" /* __spreadArray */])([prefix], Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["e" /* __read */])(varArgs))); } function repoCallOnCompleteCallback(repo, callback, status, errorReason) { if (callback) { exceptionGuard(function () { if (status === 'ok') { callback(null); } else { var code = (status || 'error').toUpperCase(); var message = code; if (errorReason) { message += ': ' + errorReason; } var error = new Error(message); // eslint-disable-next-line @typescript-eslint/no-explicit-any error.code = code; callback(error); } }); } } function repoGetDatabase(repo) { return repo.__database || (repo.__database = new Database(repo)); } /** * Creates a new transaction, adds it to the transactions we're tracking, and * sends it to the server if possible. * * @param path Path at which to do transaction. * @param transactionUpdate Update callback. * @param onComplete Completion callback. * @param applyLocally Whether or not to make intermediate results visible */ function repoStartTransaction(repo, path, transactionUpdate, onComplete, applyLocally) { repoLog(repo, 'transaction on ' + path); // Add a watch to make sure we get server updates. var valueCallback = function () { }; var watchRef = new Reference(repo, path); watchRef.on('value', valueCallback); var unwatcher = function () { watchRef.off('value', valueCallback); }; // Initialize transaction. var transaction = { path: path, update: transactionUpdate, onComplete: onComplete, // One of TransactionStatus enums. status: null, // Used when combining transactions at different locations to figure out // which one goes first. order: LUIDGenerator(), // Whether to raise local events for this transaction. applyLocally: applyLocally, // Count of how many times we've retried the transaction. retryCount: 0, // Function to call to clean up our .on() listener. unwatcher: unwatcher, // Stores why a transaction was aborted. abortReason: null, currentWriteId: null, currentInputSnapshot: null, currentOutputSnapshotRaw: null, currentOutputSnapshotResolved: null }; // Run transaction initially. var currentState = repoGetLatestState(repo, path, undefined); transaction.currentInputSnapshot = currentState; var newVal = transaction.update(currentState.val()); if (newVal === undefined) { // Abort transaction. transaction.unwatcher(); transaction.currentOutputSnapshotRaw = null; transaction.currentOutputSnapshotResolved = null; if (transaction.onComplete) { // We just set the input snapshot, so this cast should be safe var snapshot = new DataSnapshot(transaction.currentInputSnapshot, new Reference(repo, transaction.path), PRIORITY_INDEX); transaction.onComplete(null, false, snapshot); } } else { validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path); // Mark as run and add to our queue. transaction.status = 0 /* RUN */; var queueNode = treeSubTree(repo.transactionQueueTree_, path); var nodeQueue = treeGetValue(queueNode) || []; nodeQueue.push(transaction); treeSetValue(queueNode, nodeQueue); // Update visibleData and raise events // Note: We intentionally raise events after updating all of our // transaction state, since the user could start new transactions from the // event callbacks. var priorityForNode = void 0; if (typeof newVal === 'object' && newVal !== null && Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["k" /* contains */])(newVal, '.priority')) { // eslint-disable-next-line @typescript-eslint/no-explicit-any priorityForNode = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(newVal, '.priority'); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(isValidPriority(priorityForNode), 'Invalid priority returned by transaction. ' + 'Priority must be a valid string, finite number, server value, or null.'); } else { var currentNode = syncTreeCalcCompleteEventCache(repo.serverSyncTree_, path) || ChildrenNode.EMPTY_NODE; priorityForNode = currentNode.getPriority().val(); } var serverValues = repoGenerateServerValues(repo); var newNodeUnresolved = nodeFromJSON$1(newVal, priorityForNode); var newNode = resolveDeferredValueSnapshot(newNodeUnresolved, currentState, serverValues); transaction.currentOutputSnapshotRaw = newNodeUnresolved; transaction.currentOutputSnapshotResolved = newNode; transaction.currentWriteId = repoGetNextWriteId(repo); var events = syncTreeApplyUserOverwrite(repo.serverSyncTree_, path, newNode, transaction.currentWriteId, transaction.applyLocally); eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); repoSendReadyTransactions(repo, repo.transactionQueueTree_); } } /** * @param excludeSets A specific set to exclude */ function repoGetLatestState(repo, path, excludeSets) { return (syncTreeCalcCompleteEventCache(repo.serverSyncTree_, path, excludeSets) || ChildrenNode.EMPTY_NODE); } /** * Sends any already-run transactions that aren't waiting for outstanding * transactions to complete. * * Externally it's called with no arguments, but it calls itself recursively * with a particular transactionQueueTree node to recurse through the tree. * * @param node transactionQueueTree node to start at. */ function repoSendReadyTransactions(repo, node) { if (node === void 0) { node = repo.transactionQueueTree_; } // Before recursing, make sure any completed transactions are removed. if (!node) { repoPruneCompletedTransactionsBelowNode(repo, node); } if (treeGetValue(node)) { var queue = repoBuildTransactionQueue(repo, node); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(queue.length > 0, 'Sending zero length transaction queue'); var allRun = queue.every(function (transaction) { return transaction.status === 0 /* RUN */; }); // If they're all run (and not sent), we can send them. Else, we must wait. if (allRun) { repoSendTransactionQueue(repo, treeGetPath(node), queue); } } else if (treeHasChildren(node)) { treeForEachChild(node, function (childNode) { repoSendReadyTransactions(repo, childNode); }); } } /** * Given a list of run transactions, send them to the server and then handle * the result (success or failure). * * @param path The location of the queue. * @param queue Queue of transactions under the specified location. */ function repoSendTransactionQueue(repo, path, queue) { // Mark transactions as sent and increment retry count! var setsToIgnore = queue.map(function (txn) { return txn.currentWriteId; }); var latestState = repoGetLatestState(repo, path, setsToIgnore); var snapToSend = latestState; var latestHash = latestState.hash(); for (var i = 0; i < queue.length; i++) { var txn = queue[i]; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(txn.status === 0 /* RUN */, 'tryToSendTransactionQueue_: items in queue should all be run.'); txn.status = 1 /* SENT */; txn.retryCount++; var relativePath = newRelativePath(path, txn.path); // If we've gotten to this point, the output snapshot must be defined. snapToSend = snapToSend.updateChild(relativePath /** @type {!Node} */, txn.currentOutputSnapshotRaw); } var dataToSend = snapToSend.val(true); var pathToSend = path; // Send the put. repo.server_.put(pathToSend.toString(), dataToSend, function (status) { repoLog(repo, 'transaction put response', { path: pathToSend.toString(), status: status }); var events = []; if (status === 'ok') { // Queue up the callbacks and fire them after cleaning up all of our // transaction state, since the callback could trigger more // transactions or sets. var callbacks = []; for (var i = 0; i < queue.length; i++) { queue[i].status = 2 /* COMPLETED */; events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId)); if (queue[i].onComplete) { // We never unset the output snapshot, and given that this // transaction is complete, it should be set var node = queue[i].currentOutputSnapshotResolved; var ref = new Reference(repo, queue[i].path); var snapshot = new DataSnapshot(node, ref, PRIORITY_INDEX); callbacks.push(queue[i].onComplete.bind(null, null, true, snapshot)); } queue[i].unwatcher(); } // Now remove the completed transactions. repoPruneCompletedTransactionsBelowNode(repo, treeSubTree(repo.transactionQueueTree_, path)); // There may be pending transactions that we can now send. repoSendReadyTransactions(repo, repo.transactionQueueTree_); eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); // Finally, trigger onComplete callbacks. for (var i = 0; i < callbacks.length; i++) { exceptionGuard(callbacks[i]); } } else { // transactions are no longer sent. Update their status appropriately. if (status === 'datastale') { for (var i = 0; i < queue.length; i++) { if (queue[i].status === 3 /* SENT_NEEDS_ABORT */) { queue[i].status = 4 /* NEEDS_ABORT */; } else { queue[i].status = 0 /* RUN */; } } } else { warn('transaction at ' + pathToSend.toString() + ' failed: ' + status); for (var i = 0; i < queue.length; i++) { queue[i].status = 4 /* NEEDS_ABORT */; queue[i].abortReason = status; } } repoRerunTransactions(repo, path); } }, latestHash); } /** * Finds all transactions dependent on the data at changedPath and reruns them. * * Should be called any time cached data changes. * * Return the highest path that was affected by rerunning transactions. This * is the path at which events need to be raised for. * * @param changedPath The path in mergedData that changed. * @return The rootmost path that was affected by rerunning transactions. */ function repoRerunTransactions(repo, changedPath) { var rootMostTransactionNode = repoGetAncestorTransactionNode(repo, changedPath); var path = treeGetPath(rootMostTransactionNode); var queue = repoBuildTransactionQueue(repo, rootMostTransactionNode); repoRerunTransactionQueue(repo, queue, path); return path; } /** * Does all the work of rerunning transactions (as well as cleans up aborted * transactions and whatnot). * * @param queue The queue of transactions to run. * @param path The path the queue is for. */ function repoRerunTransactionQueue(repo, queue, path) { if (queue.length === 0) { return; // Nothing to do! } // Queue up the callbacks and fire them after cleaning up all of our // transaction state, since the callback could trigger more transactions or // sets. var callbacks = []; var events = []; // Ignore all of the sets we're going to re-run. var txnsToRerun = queue.filter(function (q) { return q.status === 0 /* RUN */; }); var setsToIgnore = txnsToRerun.map(function (q) { return q.currentWriteId; }); for (var i = 0; i < queue.length; i++) { var transaction = queue[i]; var relativePath = newRelativePath(path, transaction.path); var abortTransaction = false, abortReason = void 0; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(relativePath !== null, 'rerunTransactionsUnderNode_: relativePath should not be null.'); if (transaction.status === 4 /* NEEDS_ABORT */) { abortTransaction = true; abortReason = transaction.abortReason; events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true)); } else if (transaction.status === 0 /* RUN */) { if (transaction.retryCount >= MAX_TRANSACTION_RETRIES) { abortTransaction = true; abortReason = 'maxretry'; events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true)); } else { // This code reruns a transaction var currentNode = repoGetLatestState(repo, transaction.path, setsToIgnore); transaction.currentInputSnapshot = currentNode; var newData = queue[i].update(currentNode.val()); if (newData !== undefined) { validateFirebaseData('transaction failed: Data returned ', newData, transaction.path); var newDataNode = nodeFromJSON$1(newData); var hasExplicitPriority = typeof newData === 'object' && newData != null && Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["k" /* contains */])(newData, '.priority'); if (!hasExplicitPriority) { // Keep the old priority if there wasn't a priority explicitly specified. newDataNode = newDataNode.updatePriority(currentNode.getPriority()); } var oldWriteId = transaction.currentWriteId; var serverValues = repoGenerateServerValues(repo); var newNodeResolved = resolveDeferredValueSnapshot(newDataNode, currentNode, serverValues); transaction.currentOutputSnapshotRaw = newDataNode; transaction.currentOutputSnapshotResolved = newNodeResolved; transaction.currentWriteId = repoGetNextWriteId(repo); // Mutates setsToIgnore in place setsToIgnore.splice(setsToIgnore.indexOf(oldWriteId), 1); events = events.concat(syncTreeApplyUserOverwrite(repo.serverSyncTree_, transaction.path, newNodeResolved, transaction.currentWriteId, transaction.applyLocally)); events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, oldWriteId, true)); } else { abortTransaction = true; abortReason = 'nodata'; events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true)); } } } eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); events = []; if (abortTransaction) { // Abort. queue[i].status = 2 /* COMPLETED */; // Removing a listener can trigger pruning which can muck with // mergedData/visibleData (as it prunes data). So defer the unwatcher // until we're done. (function (unwatcher) { setTimeout(unwatcher, Math.floor(0)); })(queue[i].unwatcher); if (queue[i].onComplete) { if (abortReason === 'nodata') { var ref = new Reference(repo, queue[i].path); // We set this field immediately, so it's safe to cast to an actual snapshot var lastInput /** @type {!Node} */ = queue[i].currentInputSnapshot; var snapshot = new DataSnapshot(lastInput, ref, PRIORITY_INDEX); callbacks.push(queue[i].onComplete.bind(null, null, false, snapshot)); } else { callbacks.push(queue[i].onComplete.bind(null, new Error(abortReason), false, null)); } } } } // Clean up completed transactions. repoPruneCompletedTransactionsBelowNode(repo, repo.transactionQueueTree_); // Now fire callbacks, now that we're in a good, known state. for (var i = 0; i < callbacks.length; i++) { exceptionGuard(callbacks[i]); } // Try to send the transaction result to the server. repoSendReadyTransactions(repo, repo.transactionQueueTree_); } /** * Returns the rootmost ancestor node of the specified path that has a pending * transaction on it, or just returns the node for the given path if there are * no pending transactions on any ancestor. * * @param path The location to start at. * @return The rootmost node with a transaction. */ function repoGetAncestorTransactionNode(repo, path) { var front; // Start at the root and walk deeper into the tree towards path until we // find a node with pending transactions. var transactionNode = repo.transactionQueueTree_; front = pathGetFront(path); while (front !== null && treeGetValue(transactionNode) === undefined) { transactionNode = treeSubTree(transactionNode, front); path = pathPopFront(path); front = pathGetFront(path); } return transactionNode; } /** * Builds the queue of all transactions at or below the specified * transactionNode. * * @param transactionNode * @return The generated queue. */ function repoBuildTransactionQueue(repo, transactionNode) { // Walk any child transaction queues and aggregate them into a single queue. var transactionQueue = []; repoAggregateTransactionQueuesForNode(repo, transactionNode, transactionQueue); // Sort them by the order the transactions were created. transactionQueue.sort(function (a, b) { return a.order - b.order; }); return transactionQueue; } function repoAggregateTransactionQueuesForNode(repo, node, queue) { var nodeQueue = treeGetValue(node); if (nodeQueue) { for (var i = 0; i < nodeQueue.length; i++) { queue.push(nodeQueue[i]); } } treeForEachChild(node, function (child) { repoAggregateTransactionQueuesForNode(repo, child, queue); }); } /** * Remove COMPLETED transactions at or below this node in the transactionQueueTree_. */ function repoPruneCompletedTransactionsBelowNode(repo, node) { var queue = treeGetValue(node); if (queue) { var to = 0; for (var from = 0; from < queue.length; from++) { if (queue[from].status !== 2 /* COMPLETED */) { queue[to] = queue[from]; to++; } } queue.length = to; treeSetValue(node, queue.length > 0 ? queue : undefined); } treeForEachChild(node, function (childNode) { repoPruneCompletedTransactionsBelowNode(repo, childNode); }); } /** * Aborts all transactions on ancestors or descendants of the specified path. * Called when doing a set() or update() since we consider them incompatible * with transactions. * * @param path Path for which we want to abort related transactions. */ function repoAbortTransactions(repo, path) { var affectedPath = treeGetPath(repoGetAncestorTransactionNode(repo, path)); var transactionNode = treeSubTree(repo.transactionQueueTree_, path); treeForEachAncestor(transactionNode, function (node) { repoAbortTransactionsOnNode(repo, node); }); repoAbortTransactionsOnNode(repo, transactionNode); treeForEachDescendant(transactionNode, function (node) { repoAbortTransactionsOnNode(repo, node); }); return affectedPath; } /** * Abort transactions stored in this transaction queue node. * * @param node Node to abort transactions for. */ function repoAbortTransactionsOnNode(repo, node) { var queue = treeGetValue(node); if (queue) { // Queue up the callbacks and fire them after cleaning up all of our // transaction state, since the callback could trigger more transactions // or sets. var callbacks = []; // Go through queue. Any already-sent transactions must be marked for // abort, while the unsent ones can be immediately aborted and removed. var events = []; var lastSent = -1; for (var i = 0; i < queue.length; i++) { if (queue[i].status === 3 /* SENT_NEEDS_ABORT */) ; else if (queue[i].status === 1 /* SENT */) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(lastSent === i - 1, 'All SENT items should be at beginning of queue.'); lastSent = i; // Mark transaction for abort when it comes back. queue[i].status = 3 /* SENT_NEEDS_ABORT */; queue[i].abortReason = 'set'; } else { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(queue[i].status === 0 /* RUN */, 'Unexpected transaction status in abort'); // We can abort it immediately. queue[i].unwatcher(); events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId, true)); if (queue[i].onComplete) { var snapshot = null; callbacks.push(queue[i].onComplete.bind(null, new Error('set'), false, snapshot)); } } } if (lastSent === -1) { // We're not waiting for any sent transactions. We can clear the queue. treeSetValue(node, undefined); } else { // Remove the transactions we aborted. queue.length = lastSent + 1; } // Now fire the callbacks. eventQueueRaiseEventsForChangedPath(repo.eventQueue_, treeGetPath(node), events); for (var i = 0; i < callbacks.length; i++) { exceptionGuard(callbacks[i]); } } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var OnDisconnect = /** @class */ (function () { function OnDisconnect(repo_, path_) { this.repo_ = repo_; this.path_ = path_; } OnDisconnect.prototype.cancel = function (onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('OnDisconnect.cancel', 0, 1, arguments.length); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('OnDisconnect.cancel', 1, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoOnDisconnectCancel(this.repo_, this.path_, deferred.wrapCallback(onComplete)); return deferred.promise; }; OnDisconnect.prototype.remove = function (onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('OnDisconnect.remove', 0, 1, arguments.length); validateWritablePath('OnDisconnect.remove', this.path_); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('OnDisconnect.remove', 1, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoOnDisconnectSet(this.repo_, this.path_, null, deferred.wrapCallback(onComplete)); return deferred.promise; }; OnDisconnect.prototype.set = function (value, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('OnDisconnect.set', 1, 2, arguments.length); validateWritablePath('OnDisconnect.set', this.path_); validateFirebaseDataArg('OnDisconnect.set', 1, value, this.path_, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('OnDisconnect.set', 2, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoOnDisconnectSet(this.repo_, this.path_, value, deferred.wrapCallback(onComplete)); return deferred.promise; }; OnDisconnect.prototype.setWithPriority = function (value, priority, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('OnDisconnect.setWithPriority', 2, 3, arguments.length); validateWritablePath('OnDisconnect.setWithPriority', this.path_); validateFirebaseDataArg('OnDisconnect.setWithPriority', 1, value, this.path_, false); validatePriority('OnDisconnect.setWithPriority', 2, priority, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('OnDisconnect.setWithPriority', 3, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoOnDisconnectSetWithPriority(this.repo_, this.path_, value, priority, deferred.wrapCallback(onComplete)); return deferred.promise; }; OnDisconnect.prototype.update = function (objectToMerge, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('OnDisconnect.update', 1, 2, arguments.length); validateWritablePath('OnDisconnect.update', this.path_); if (Array.isArray(objectToMerge)) { var newObjectToMerge = {}; for (var i = 0; i < objectToMerge.length; ++i) { newObjectToMerge['' + i] = objectToMerge[i]; } objectToMerge = newObjectToMerge; warn('Passing an Array to firebase.database.onDisconnect().update() is deprecated. Use set() if you want to overwrite the ' + 'existing data, or an Object with integer keys if you really do want to only update some of the children.'); } validateFirebaseMergeDataArg('OnDisconnect.update', 1, objectToMerge, this.path_, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('OnDisconnect.update', 2, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoOnDisconnectUpdate(this.repo_, this.path_, objectToMerge, deferred.wrapCallback(onComplete)); return deferred.promise; }; return OnDisconnect; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var TransactionResult = /** @class */ (function () { /** * A type for the resolve value of Firebase.transaction. */ function TransactionResult(committed, snapshot) { this.committed = committed; this.snapshot = snapshot; } // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary // for end-users TransactionResult.prototype.toJSON = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('TransactionResult.toJSON', 0, 1, arguments.length); return { committed: this.committed, snapshot: this.snapshot.toJSON() }; }; return TransactionResult; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Encapsulates the data needed to raise an event */ var DataEvent = /** @class */ (function () { /** * @param eventType One of: value, child_added, child_changed, child_moved, child_removed * @param eventRegistration The function to call to with the event data. User provided * @param snapshot The data backing the event * @param prevName Optional, the name of the previous child for child_* events. */ function DataEvent(eventType, eventRegistration, snapshot, prevName) { this.eventType = eventType; this.eventRegistration = eventRegistration; this.snapshot = snapshot; this.prevName = prevName; } /** * @inheritDoc */ DataEvent.prototype.getPath = function () { var ref = this.snapshot.getRef(); if (this.eventType === 'value') { return ref.path; } else { return ref.getParent().path; } }; /** * @inheritDoc */ DataEvent.prototype.getEventType = function () { return this.eventType; }; /** * @inheritDoc */ DataEvent.prototype.getEventRunner = function () { return this.eventRegistration.getEventRunner(this); }; /** * @inheritDoc */ DataEvent.prototype.toString = function () { return (this.getPath().toString() + ':' + this.eventType + ':' + Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["J" /* stringify */])(this.snapshot.exportVal())); }; return DataEvent; }()); var CancelEvent = /** @class */ (function () { function CancelEvent(eventRegistration, error, path) { this.eventRegistration = eventRegistration; this.error = error; this.path = path; } /** * @inheritDoc */ CancelEvent.prototype.getPath = function () { return this.path; }; /** * @inheritDoc */ CancelEvent.prototype.getEventType = function () { return 'cancel'; }; /** * @inheritDoc */ CancelEvent.prototype.getEventRunner = function () { return this.eventRegistration.getEventRunner(this); }; /** * @inheritDoc */ CancelEvent.prototype.toString = function () { return this.path.toString() + ':cancel'; }; return CancelEvent; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Represents registration for 'value' events. */ var ValueEventRegistration = /** @class */ (function () { function ValueEventRegistration(callback_, cancelCallback_, context_) { this.callback_ = callback_; this.cancelCallback_ = cancelCallback_; this.context_ = context_; } /** * @inheritDoc */ ValueEventRegistration.prototype.respondsTo = function (eventType) { return eventType === 'value'; }; /** * @inheritDoc */ ValueEventRegistration.prototype.createEvent = function (change, query) { var index = query.getQueryParams().getIndex(); return new DataEvent('value', this, new DataSnapshot(change.snapshotNode, query.getRef(), index)); }; /** * @inheritDoc */ ValueEventRegistration.prototype.getEventRunner = function (eventData) { var ctx = this.context_; if (eventData.getEventType() === 'cancel') { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback'); var cancelCB_1 = this.cancelCallback_; return function () { // We know that error exists, we checked above that this is a cancel event cancelCB_1.call(ctx, eventData.error); }; } else { var cb_1 = this.callback_; return function () { cb_1.call(ctx, eventData.snapshot); }; } }; /** * @inheritDoc */ ValueEventRegistration.prototype.createCancelEvent = function (error, path) { if (this.cancelCallback_) { return new CancelEvent(this, error, path); } else { return null; } }; /** * @inheritDoc */ ValueEventRegistration.prototype.matches = function (other) { if (!(other instanceof ValueEventRegistration)) { return false; } else if (!other.callback_ || !this.callback_) { // If no callback specified, we consider it to match any callback. return true; } else { return (other.callback_ === this.callback_ && other.context_ === this.context_); } }; /** * @inheritDoc */ ValueEventRegistration.prototype.hasAnyCallback = function () { return this.callback_ !== null; }; return ValueEventRegistration; }()); /** * Represents the registration of 1 or more child_xxx events. * * Currently, it is always exactly 1 child_xxx event, but the idea is we might let you * register a group of callbacks together in the future. */ var ChildEventRegistration = /** @class */ (function () { function ChildEventRegistration(callbacks_, cancelCallback_, context_) { this.callbacks_ = callbacks_; this.cancelCallback_ = cancelCallback_; this.context_ = context_; } /** * @inheritDoc */ ChildEventRegistration.prototype.respondsTo = function (eventType) { var eventToCheck = eventType === 'children_added' ? 'child_added' : eventType; eventToCheck = eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck; return Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["k" /* contains */])(this.callbacks_, eventToCheck); }; /** * @inheritDoc */ ChildEventRegistration.prototype.createCancelEvent = function (error, path) { if (this.cancelCallback_) { return new CancelEvent(this, error, path); } else { return null; } }; /** * @inheritDoc */ ChildEventRegistration.prototype.createEvent = function (change, query) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(change.childName != null, 'Child events should have a childName.'); var ref = query.getRef().child(change.childName); var index = query.getQueryParams().getIndex(); return new DataEvent(change.type, this, new DataSnapshot(change.snapshotNode, ref, index), change.prevName); }; /** * @inheritDoc */ ChildEventRegistration.prototype.getEventRunner = function (eventData) { var ctx = this.context_; if (eventData.getEventType() === 'cancel') { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(this.cancelCallback_, 'Raising a cancel event on a listener with no cancel callback'); var cancelCB_2 = this.cancelCallback_; return function () { // We know that error exists, we checked above that this is a cancel event cancelCB_2.call(ctx, eventData.error); }; } else { var cb_2 = this.callbacks_[eventData.eventType]; return function () { cb_2.call(ctx, eventData.snapshot, eventData.prevName); }; } }; /** * @inheritDoc */ ChildEventRegistration.prototype.matches = function (other) { var _this = this; if (other instanceof ChildEventRegistration) { if (!this.callbacks_ || !other.callbacks_) { return true; } else if (this.context_ === other.context_) { var otherKeys = Object.keys(other.callbacks_); var thisKeys = Object.keys(this.callbacks_); var otherCount = otherKeys.length; var thisCount = thisKeys.length; if (otherCount === thisCount) { // If count is 1, do an exact match on eventType, if either is defined but null, it's a match. // If event types don't match, not a match // If count is not 1, exact match across all if (otherCount === 1) { var otherKey = otherKeys[0]; var thisKey = thisKeys[0]; return (thisKey === otherKey && (!other.callbacks_[otherKey] || !this.callbacks_[thisKey] || other.callbacks_[otherKey] === this.callbacks_[thisKey])); } else { // Exact match on each key. return thisKeys.every(function (eventType) { return other.callbacks_[eventType] === _this.callbacks_[eventType]; }); } } } } return false; }; /** * @inheritDoc */ ChildEventRegistration.prototype.hasAnyCallback = function () { return this.callbacks_ !== null; }; return ChildEventRegistration; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __referenceConstructor; /** * A Query represents a filter to be applied to a firebase location. This object purely represents the * query expression (and exposes our public API to build the query). The actual query logic is in ViewBase.js. * * Since every Firebase reference is a query, Firebase inherits from this object. */ var Query = /** @class */ (function () { function Query(repo, path, queryParams_, orderByCalled_) { this.repo = repo; this.path = path; this.queryParams_ = queryParams_; this.orderByCalled_ = orderByCalled_; } Object.defineProperty(Query, "__referenceConstructor", { get: function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(__referenceConstructor, 'Reference.ts has not been loaded'); return __referenceConstructor; }, set: function (val) { __referenceConstructor = val; }, enumerable: false, configurable: true }); /** * Validates start/end values for queries. */ Query.validateQueryEndpoints_ = function (params) { var startNode = null; var endNode = null; if (params.hasStart()) { startNode = params.getIndexStartValue(); } if (params.hasEnd()) { endNode = params.getIndexEndValue(); } if (params.getIndex() === KEY_INDEX) { var tooManyArgsError = 'Query: When ordering by key, you may only pass one argument to ' + 'startAt(), endAt(), or equalTo().'; var wrongArgTypeError = 'Query: When ordering by key, the argument passed to startAt(), startAfter(), ' + 'endAt(), endBefore(), or equalTo() must be a string.'; if (params.hasStart()) { var startName = params.getIndexStartName(); if (startName !== MIN_NAME) { throw new Error(tooManyArgsError); } else if (typeof startNode !== 'string') { throw new Error(wrongArgTypeError); } } if (params.hasEnd()) { var endName = params.getIndexEndName(); if (endName !== MAX_NAME) { throw new Error(tooManyArgsError); } else if (typeof endNode !== 'string') { throw new Error(wrongArgTypeError); } } } else if (params.getIndex() === PRIORITY_INDEX) { if ((startNode != null && !isValidPriority(startNode)) || (endNode != null && !isValidPriority(endNode))) { throw new Error('Query: When ordering by priority, the first argument passed to startAt(), ' + 'startAfter() endAt(), endBefore(), or equalTo() must be a valid priority value ' + '(null, a number, or a string).'); } } else { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["f" /* assert */])(params.getIndex() instanceof PathIndex || params.getIndex() === VALUE_INDEX, 'unknown index type.'); if ((startNode != null && typeof startNode === 'object') || (endNode != null && typeof endNode === 'object')) { throw new Error('Query: First argument passed to startAt(), startAfter(), endAt(), endBefore(), or ' + 'equalTo() cannot be an object.'); } } }; /** * Validates that limit* has been called with the correct combination of parameters */ Query.validateLimit_ = function (params) { if (params.hasStart() && params.hasEnd() && params.hasLimit() && !params.hasAnchoredLimit()) { throw new Error("Query: Can't combine startAt(), startAfter(), endAt(), endBefore(), and limit(). Use " + 'limitToFirst() or limitToLast() instead.'); } }; /** * Validates that no other order by call has been made */ Query.prototype.validateNoPreviousOrderByCall_ = function (fnName) { if (this.orderByCalled_ === true) { throw new Error(fnName + ": You can't combine multiple orderBy calls."); } }; Query.prototype.getQueryParams = function () { return this.queryParams_; }; Query.prototype.getRef = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.ref', 0, 0, arguments.length); // This is a slight hack. We cannot goog.require('fb.api.Firebase'), since Firebase requires fb.api.Query. // However, we will always export 'Firebase' to the global namespace, so it's guaranteed to exist by the time this // method gets called. return new Query.__referenceConstructor(this.repo, this.path); }; Query.prototype.on = function (eventType, callback, cancelCallbackOrContext, context) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.on', 2, 4, arguments.length); validateEventType('Query.on', 1, eventType, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Query.on', 2, callback, false); var ret = Query.getCancelAndContextArgs_('Query.on', cancelCallbackOrContext, context); if (eventType === 'value') { this.onValueEvent(callback, ret.cancel, ret.context); } else { var callbacks = {}; callbacks[eventType] = callback; this.onChildEvent(callbacks, ret.cancel, ret.context); } return callback; }; Query.prototype.onValueEvent = function (callback, cancelCallback, context) { var container = new ValueEventRegistration(callback, cancelCallback || null, context || null); repoAddEventCallbackForQuery(this.repo, this, container); }; Query.prototype.onChildEvent = function (callbacks, cancelCallback, context) { var container = new ChildEventRegistration(callbacks, cancelCallback, context); repoAddEventCallbackForQuery(this.repo, this, container); }; Query.prototype.off = function (eventType, callback, context) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.off', 0, 3, arguments.length); validateEventType('Query.off', 1, eventType, true); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Query.off', 2, callback, true); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["M" /* validateContextObject */])('Query.off', 3, context, true); var container = null; var callbacks = null; if (eventType === 'value') { var valueCallback = callback || null; container = new ValueEventRegistration(valueCallback, null, context || null); } else if (eventType) { if (callback) { callbacks = {}; callbacks[eventType] = callback; } container = new ChildEventRegistration(callbacks, null, context || null); } repoRemoveEventCallbackForQuery(this.repo, this, container); }; /** * Get the server-value for this query, or return a cached value if not connected. */ Query.prototype.get = function () { return repoGetValue(this.repo, this); }; /** * Attaches a listener, waits for the first event, and then removes the listener */ Query.prototype.once = function (eventType, userCallback, failureCallbackOrContext, context) { var _this = this; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.once', 1, 4, arguments.length); validateEventType('Query.once', 1, eventType, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Query.once', 2, userCallback, true); var ret = Query.getCancelAndContextArgs_('Query.once', failureCallbackOrContext, context); // TODO: Implement this more efficiently (in particular, use 'get' wire protocol for 'value' event) // TODO: consider actually wiring the callbacks into the promise. We cannot do this without a breaking change // because the API currently expects callbacks will be called synchronously if the data is cached, but this is // against the Promise specification. var firstCall = true; var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); // A dummy error handler in case a user wasn't expecting promises deferred.promise.catch(function () { }); var onceCallback = function (snapshot) { // NOTE: Even though we unsubscribe, we may get called multiple times if a single action (e.g. set() with JSON) // triggers multiple events (e.g. child_added or child_changed). if (firstCall) { firstCall = false; _this.off(eventType, onceCallback); if (userCallback) { userCallback.bind(ret.context)(snapshot); } deferred.resolve(snapshot); } }; this.on(eventType, onceCallback, /*cancel=*/ function (err) { _this.off(eventType, onceCallback); if (ret.cancel) { ret.cancel.bind(ret.context)(err); } deferred.reject(err); }); return deferred.promise; }; /** * Set a limit and anchor it to the start of the window. */ Query.prototype.limitToFirst = function (limit) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.limitToFirst', 1, 1, arguments.length); if (typeof limit !== 'number' || Math.floor(limit) !== limit || limit <= 0) { throw new Error('Query.limitToFirst: First argument must be a positive integer.'); } if (this.queryParams_.hasLimit()) { throw new Error('Query.limitToFirst: Limit was already set (by another call to limit, ' + 'limitToFirst, or limitToLast).'); } return new Query(this.repo, this.path, queryParamsLimitToFirst(this.queryParams_, limit), this.orderByCalled_); }; /** * Set a limit and anchor it to the end of the window. */ Query.prototype.limitToLast = function (limit) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.limitToLast', 1, 1, arguments.length); if (typeof limit !== 'number' || Math.floor(limit) !== limit || limit <= 0) { throw new Error('Query.limitToLast: First argument must be a positive integer.'); } if (this.queryParams_.hasLimit()) { throw new Error('Query.limitToLast: Limit was already set (by another call to limit, ' + 'limitToFirst, or limitToLast).'); } return new Query(this.repo, this.path, queryParamsLimitToLast(this.queryParams_, limit), this.orderByCalled_); }; /** * Given a child path, return a new query ordered by the specified grandchild path. */ Query.prototype.orderByChild = function (path) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.orderByChild', 1, 1, arguments.length); if (path === '$key') { throw new Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.'); } else if (path === '$priority') { throw new Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.'); } else if (path === '$value') { throw new Error('Query.orderByChild: "$value" is invalid. Use Query.orderByValue() instead.'); } validatePathString('Query.orderByChild', 1, path, false); this.validateNoPreviousOrderByCall_('Query.orderByChild'); var parsedPath = new Path(path); if (pathIsEmpty(parsedPath)) { throw new Error('Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.'); } var index = new PathIndex(parsedPath); var newParams = queryParamsOrderBy(this.queryParams_, index); Query.validateQueryEndpoints_(newParams); return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true); }; /** * Return a new query ordered by the KeyIndex */ Query.prototype.orderByKey = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.orderByKey', 0, 0, arguments.length); this.validateNoPreviousOrderByCall_('Query.orderByKey'); var newParams = queryParamsOrderBy(this.queryParams_, KEY_INDEX); Query.validateQueryEndpoints_(newParams); return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true); }; /** * Return a new query ordered by the PriorityIndex */ Query.prototype.orderByPriority = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.orderByPriority', 0, 0, arguments.length); this.validateNoPreviousOrderByCall_('Query.orderByPriority'); var newParams = queryParamsOrderBy(this.queryParams_, PRIORITY_INDEX); Query.validateQueryEndpoints_(newParams); return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true); }; /** * Return a new query ordered by the ValueIndex */ Query.prototype.orderByValue = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.orderByValue', 0, 0, arguments.length); this.validateNoPreviousOrderByCall_('Query.orderByValue'); var newParams = queryParamsOrderBy(this.queryParams_, VALUE_INDEX); Query.validateQueryEndpoints_(newParams); return new Query(this.repo, this.path, newParams, /*orderByCalled=*/ true); }; Query.prototype.startAt = function (value, name) { if (value === void 0) { value = null; } Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.startAt', 0, 2, arguments.length); validateFirebaseDataArg('Query.startAt', 1, value, this.path, true); validateKey('Query.startAt', 2, name, true); var newParams = queryParamsStartAt(this.queryParams_, value, name); Query.validateLimit_(newParams); Query.validateQueryEndpoints_(newParams); if (this.queryParams_.hasStart()) { throw new Error('Query.startAt: Starting point was already set (by another call to startAt ' + 'or equalTo).'); } // Calling with no params tells us to start at the beginning. if (value === undefined) { value = null; name = null; } return new Query(this.repo, this.path, newParams, this.orderByCalled_); }; Query.prototype.startAfter = function (value, name) { if (value === void 0) { value = null; } Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.startAfter', 0, 2, arguments.length); validateFirebaseDataArg('Query.startAfter', 1, value, this.path, false); validateKey('Query.startAfter', 2, name, true); var newParams = queryParamsStartAfter(this.queryParams_, value, name); Query.validateLimit_(newParams); Query.validateQueryEndpoints_(newParams); if (this.queryParams_.hasStart()) { throw new Error('Query.startAfter: Starting point was already set (by another call to startAt, startAfter ' + 'or equalTo).'); } return new Query(this.repo, this.path, newParams, this.orderByCalled_); }; Query.prototype.endAt = function (value, name) { if (value === void 0) { value = null; } Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.endAt', 0, 2, arguments.length); validateFirebaseDataArg('Query.endAt', 1, value, this.path, true); validateKey('Query.endAt', 2, name, true); var newParams = queryParamsEndAt(this.queryParams_, value, name); Query.validateLimit_(newParams); Query.validateQueryEndpoints_(newParams); if (this.queryParams_.hasEnd()) { throw new Error('Query.endAt: Ending point was already set (by another call to endAt, endBefore, or ' + 'equalTo).'); } return new Query(this.repo, this.path, newParams, this.orderByCalled_); }; Query.prototype.endBefore = function (value, name) { if (value === void 0) { value = null; } Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.endBefore', 0, 2, arguments.length); validateFirebaseDataArg('Query.endBefore', 1, value, this.path, false); validateKey('Query.endBefore', 2, name, true); var newParams = queryParamsEndBefore(this.queryParams_, value, name); Query.validateLimit_(newParams); Query.validateQueryEndpoints_(newParams); if (this.queryParams_.hasEnd()) { throw new Error('Query.endBefore: Ending point was already set (by another call to endAt, endBefore, or ' + 'equalTo).'); } return new Query(this.repo, this.path, newParams, this.orderByCalled_); }; /** * Load the selection of children with exactly the specified value, and, optionally, * the specified name. */ Query.prototype.equalTo = function (value, name) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.equalTo', 1, 2, arguments.length); validateFirebaseDataArg('Query.equalTo', 1, value, this.path, false); validateKey('Query.equalTo', 2, name, true); if (this.queryParams_.hasStart()) { throw new Error('Query.equalTo: Starting point was already set (by another call to startAt/startAfter or ' + 'equalTo).'); } if (this.queryParams_.hasEnd()) { throw new Error('Query.equalTo: Ending point was already set (by another call to endAt/endBefore or ' + 'equalTo).'); } return this.startAt(value, name).endAt(value, name); }; /** * @return URL for this location. */ Query.prototype.toString = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.toString', 0, 0, arguments.length); return this.repo.toString() + pathToUrlEncodedString(this.path); }; // Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary // for end-users. Query.prototype.toJSON = function () { // An optional spacer argument is unnecessary for a string. Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.toJSON', 0, 1, arguments.length); return this.toString(); }; /** * An object representation of the query parameters used by this Query. */ Query.prototype.queryObject = function () { return queryParamsGetQueryObject(this.queryParams_); }; Query.prototype.queryIdentifier = function () { var obj = this.queryObject(); var id = ObjectToUniqueKey(obj); return id === '{}' ? 'default' : id; }; /** * Return true if this query and the provided query are equivalent; otherwise, return false. */ Query.prototype.isEqual = function (other) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Query.isEqual', 1, 1, arguments.length); if (!(other instanceof Query)) { var error = 'Query.isEqual failed: First argument must be an instance of firebase.database.Query.'; throw new Error(error); } var sameRepo = this.repo === other.repo; var samePath = pathEquals(this.path, other.path); var sameQueryIdentifier = this.queryIdentifier() === other.queryIdentifier(); return sameRepo && samePath && sameQueryIdentifier; }; /** * Helper used by .on and .once to extract the context and or cancel arguments. * @param fnName The function name (on or once) * */ Query.getCancelAndContextArgs_ = function (fnName, cancelOrContext, context) { var ret = { cancel: null, context: null }; if (cancelOrContext && context) { ret.cancel = cancelOrContext; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])(fnName, 3, ret.cancel, true); ret.context = context; Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["M" /* validateContextObject */])(fnName, 4, ret.context, true); } else if (cancelOrContext) { // we have either a cancel callback or a context. if (typeof cancelOrContext === 'object' && cancelOrContext !== null) { // it's a context! ret.context = cancelOrContext; } else if (typeof cancelOrContext === 'function') { ret.cancel = cancelOrContext; } else { throw new Error(Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["o" /* errorPrefix */])(fnName, 3, true) + ' must either be a cancel callback or a context object.'); } } return ret; }; Object.defineProperty(Query.prototype, "ref", { get: function () { return this.getRef(); }, enumerable: false, configurable: true }); return Query; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Reference = /** @class */ (function (_super) { Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __extends */])(Reference, _super); /** * Call options: * new Reference(Repo, Path) or * new Reference(url: string, string|RepoManager) * * Externally - this is the firebase.database.Reference type. */ function Reference(repo, path) { var _this = this; if (!(repo instanceof Repo)) { throw new Error('new Reference() no longer supported - use app.database().'); } // call Query's constructor, passing in the repo and path. _this = _super.call(this, repo, path, new QueryParams(), false) || this; return _this; } /** @return {?string} */ Reference.prototype.getKey = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.key', 0, 0, arguments.length); if (pathIsEmpty(this.path)) { return null; } else { return pathGetBack(this.path); } }; Reference.prototype.child = function (pathString) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.child', 1, 1, arguments.length); if (typeof pathString === 'number') { pathString = String(pathString); } else if (!(pathString instanceof Path)) { if (pathGetFront(this.path) === null) { validateRootPathString('Reference.child', 1, pathString, false); } else { validatePathString('Reference.child', 1, pathString, false); } } return new Reference(this.repo, pathChild(this.path, pathString)); }; /** @return {?Reference} */ Reference.prototype.getParent = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.parent', 0, 0, arguments.length); var parentPath = pathParent(this.path); return parentPath === null ? null : new Reference(this.repo, parentPath); }; /** @return {!Reference} */ Reference.prototype.getRoot = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.root', 0, 0, arguments.length); var ref = this; while (ref.getParent() !== null) { ref = ref.getParent(); } return ref; }; /** @return {!Database} */ Reference.prototype.databaseProp = function () { return repoGetDatabase(this.repo); }; Reference.prototype.set = function (newVal, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.set', 1, 2, arguments.length); validateWritablePath('Reference.set', this.path); validateFirebaseDataArg('Reference.set', 1, newVal, this.path, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.set', 2, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoSetWithPriority(this.repo, this.path, newVal, /*priority=*/ null, deferred.wrapCallback(onComplete)); return deferred.promise; }; Reference.prototype.update = function (objectToMerge, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.update', 1, 2, arguments.length); validateWritablePath('Reference.update', this.path); if (Array.isArray(objectToMerge)) { var newObjectToMerge = {}; for (var i = 0; i < objectToMerge.length; ++i) { newObjectToMerge['' + i] = objectToMerge[i]; } objectToMerge = newObjectToMerge; warn('Passing an Array to Firebase.update() is deprecated. ' + 'Use set() if you want to overwrite the existing data, or ' + 'an Object with integer keys if you really do want to ' + 'only update some of the children.'); } validateFirebaseMergeDataArg('Reference.update', 1, objectToMerge, this.path, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.update', 2, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoUpdate(this.repo, this.path, objectToMerge, deferred.wrapCallback(onComplete)); return deferred.promise; }; Reference.prototype.setWithPriority = function (newVal, newPriority, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.setWithPriority', 2, 3, arguments.length); validateWritablePath('Reference.setWithPriority', this.path); validateFirebaseDataArg('Reference.setWithPriority', 1, newVal, this.path, false); validatePriority('Reference.setWithPriority', 2, newPriority, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.setWithPriority', 3, onComplete, true); if (this.getKey() === '.length' || this.getKey() === '.keys') { throw ('Reference.setWithPriority failed: ' + this.getKey() + ' is a read-only object.'); } var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoSetWithPriority(this.repo, this.path, newVal, newPriority, deferred.wrapCallback(onComplete)); return deferred.promise; }; Reference.prototype.remove = function (onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.remove', 0, 1, arguments.length); validateWritablePath('Reference.remove', this.path); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.remove', 1, onComplete, true); return this.set(null, onComplete); }; Reference.prototype.transaction = function (transactionUpdate, onComplete, applyLocally) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.transaction', 1, 3, arguments.length); validateWritablePath('Reference.transaction', this.path); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.transaction', 1, transactionUpdate, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.transaction', 2, onComplete, true); // NOTE: applyLocally is an internal-only option for now. We need to decide if we want to keep it and how // to expose it. validateBoolean('Reference.transaction', 3, applyLocally, true); if (this.getKey() === '.length' || this.getKey() === '.keys') { throw ('Reference.transaction failed: ' + this.getKey() + ' is a read-only object.'); } if (applyLocally === undefined) { applyLocally = true; } var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); if (typeof onComplete === 'function') { deferred.promise.catch(function () { }); } var promiseComplete = function (error, committed, snapshot) { if (error) { deferred.reject(error); } else { deferred.resolve(new TransactionResult(committed, snapshot)); } if (typeof onComplete === 'function') { onComplete(error, committed, snapshot); } }; repoStartTransaction(this.repo, this.path, transactionUpdate, promiseComplete, applyLocally); return deferred.promise; }; Reference.prototype.setPriority = function (priority, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.setPriority', 1, 2, arguments.length); validateWritablePath('Reference.setPriority', this.path); validatePriority('Reference.setPriority', 1, priority, false); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.setPriority', 2, onComplete, true); var deferred = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["a" /* Deferred */](); repoSetWithPriority(this.repo, pathChild(this.path, '.priority'), priority, null, deferred.wrapCallback(onComplete)); return deferred.promise; }; Reference.prototype.push = function (value, onComplete) { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('Reference.push', 0, 2, arguments.length); validateWritablePath('Reference.push', this.path); validateFirebaseDataArg('Reference.push', 1, value, this.path, true); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["L" /* validateCallback */])('Reference.push', 2, onComplete, true); var now = repoServerTime(this.repo); var name = nextPushId(now); // push() returns a ThennableReference whose promise is fulfilled with a regular Reference. // We use child() to create handles to two different references. The first is turned into a // ThennableReference below by adding then() and catch() methods and is used as the // return value of push(). The second remains a regular Reference and is used as the fulfilled // value of the first ThennableReference. var thennablePushRef = this.child(name); var pushRef = this.child(name); var promise; if (value != null) { promise = thennablePushRef.set(value, onComplete).then(function () { return pushRef; }); } else { promise = Promise.resolve(pushRef); } thennablePushRef.then = promise.then.bind(promise); thennablePushRef.catch = promise.then.bind(promise, undefined); if (typeof onComplete === 'function') { promise.catch(function () { }); } return thennablePushRef; }; Reference.prototype.onDisconnect = function () { validateWritablePath('Reference.onDisconnect', this.path); return new OnDisconnect(this.repo, this.path); }; Object.defineProperty(Reference.prototype, "database", { get: function () { return this.databaseProp(); }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "key", { get: function () { return this.getKey(); }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "parent", { get: function () { return this.getParent(); }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "root", { get: function () { return this.getRoot(); }, enumerable: false, configurable: true }); return Reference; }(Query)); /** * Define reference constructor in various modules * * We are doing this here to avoid several circular * dependency issues */ Query.__referenceConstructor = Reference; syncPointSetReferenceConstructor(Reference); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Abstraction around FirebaseApp's token fetching capabilities. */ var FirebaseAuthTokenProvider = /** @class */ (function () { function FirebaseAuthTokenProvider(app_, authProvider_) { var _this = this; this.app_ = app_; this.authProvider_ = authProvider_; this.auth_ = null; this.auth_ = authProvider_.getImmediate({ optional: true }); if (!this.auth_) { authProvider_.get().then(function (auth) { return (_this.auth_ = auth); }); } } FirebaseAuthTokenProvider.prototype.getToken = function (forceRefresh) { if (!this.auth_) { return Promise.resolve(null); } return this.auth_.getToken(forceRefresh).catch(function (error) { // TODO: Need to figure out all the cases this is raised and whether // this makes sense. if (error && error.code === 'auth/token-not-initialized') { log('Got auth/token-not-initialized error. Treating as null token.'); return null; } else { return Promise.reject(error); } }); }; FirebaseAuthTokenProvider.prototype.addTokenChangeListener = function (listener) { // TODO: We might want to wrap the listener and call it with no args to // avoid a leaky abstraction, but that makes removing the listener harder. if (this.auth_) { this.auth_.addAuthTokenListener(listener); } else { setTimeout(function () { return listener(null); }, 0); this.authProvider_ .get() .then(function (auth) { return auth.addAuthTokenListener(listener); }); } }; FirebaseAuthTokenProvider.prototype.removeTokenChangeListener = function (listener) { this.authProvider_ .get() .then(function (auth) { return auth.removeAuthTokenListener(listener); }); }; FirebaseAuthTokenProvider.prototype.notifyForInvalidToken = function () { var errorMessage = 'Provided authentication credentials for the app named "' + this.app_.name + '" are invalid. This usually indicates your app was not ' + 'initialized correctly. '; if ('credential' in this.app_.options) { errorMessage += 'Make sure the "credential" property provided to initializeApp() ' + 'is authorized to access the specified "databaseURL" and is from the correct ' + 'project.'; } else if ('serviceAccount' in this.app_.options) { errorMessage += 'Make sure the "serviceAccount" property provided to initializeApp() ' + 'is authorized to access the specified "databaseURL" and is from the correct ' + 'project.'; } else { errorMessage += 'Make sure the "apiKey" and "databaseURL" properties provided to ' + 'initializeApp() match the values provided for your app at ' + 'https://console.firebase.google.com/.'; } warn(errorMessage); }; return FirebaseAuthTokenProvider; }()); /* Auth token provider that the Admin SDK uses to connect to the Emulator. */ var EmulatorAdminTokenProvider = /** @class */ (function () { function EmulatorAdminTokenProvider() { } EmulatorAdminTokenProvider.prototype.getToken = function (forceRefresh) { return Promise.resolve({ accessToken: EmulatorAdminTokenProvider.EMULATOR_AUTH_TOKEN }); }; EmulatorAdminTokenProvider.prototype.addTokenChangeListener = function (listener) { // Invoke the listener immediately to match the behavior in Firebase Auth // (see packages/auth/src/auth.js#L1807) listener(EmulatorAdminTokenProvider.EMULATOR_AUTH_TOKEN); }; EmulatorAdminTokenProvider.prototype.removeTokenChangeListener = function (listener) { }; EmulatorAdminTokenProvider.prototype.notifyForInvalidToken = function () { }; EmulatorAdminTokenProvider.EMULATOR_AUTH_TOKEN = 'owner'; return EmulatorAdminTokenProvider; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * This variable is also defined in the firebase node.js admin SDK. Before * modifying this definition, consult the definition in: * * https://github.com/firebase/firebase-admin-node * * and make sure the two are consistent. */ var FIREBASE_DATABASE_EMULATOR_HOST_VAR = 'FIREBASE_DATABASE_EMULATOR_HOST'; /** * Creates and caches Repo instances. */ var repos = {}; /** * If true, new Repos will be created to use ReadonlyRestClient (for testing purposes). */ var useRestClient = false; /** * Update an existing repo in place to point to a new host/port. */ function repoManagerApplyEmulatorSettings(repo, host, port) { repo.repoInfo_ = new RepoInfo(host + ":" + port, /* secure= */ false, repo.repoInfo_.namespace, repo.repoInfo_.webSocketOnly, repo.repoInfo_.nodeAdmin, repo.repoInfo_.persistenceKey, repo.repoInfo_.includeNamespaceInQueryParams); if (repo.repoInfo_.nodeAdmin) { repo.authTokenProvider_ = new EmulatorAdminTokenProvider(); } } /** * This function should only ever be called to CREATE a new database instance. */ function repoManagerDatabaseFromApp(app, authProvider, url, nodeAdmin) { var dbUrl = url || app.options.databaseURL; if (dbUrl === undefined) { if (!app.options.projectId) { fatal("Can't determine Firebase Database URL. Be sure to include " + ' a Project ID when calling firebase.initializeApp().'); } log('Using default host for project ', app.options.projectId); dbUrl = app.options.projectId + "-default-rtdb.firebaseio.com"; } var parsedUrl = parseRepoInfo(dbUrl, nodeAdmin); var repoInfo = parsedUrl.repoInfo; var isEmulator; var dbEmulatorHost = undefined; if (typeof process !== 'undefined') { dbEmulatorHost = Object({"NODE_ENV":"production","SERVER":"https://soulapi.blueticket.com.br/api","PDV":"https://sistema.blueticket.com.br","CAMPAIGN_SERVER_URL":"https://campaigns.blueticket.com.br","CHECKOUT":"https://checkout.blueticket.com.br/btrest/forget/user/password","DEV03_SERVER":"https://soulapi.blueticket.com.br/api","DEV02_SERVER":"https://soulapi.blueticket.com.br/api","GOOGLE_API_KEY":"AIzaSyCO8xX-ayxnRvCy7nMTCUPSUpa2l436_n4","FIREBASE_API_KEY":"AIzaSyAIZdQ26rsZQmWkPKMnG8ui_8GBbd4dQoo","FIREBASE_AUTH_DOMAIN":"chat-eventos-online.firebaseapp.com","FIREBASE_DATABASE_URL":"https://chat-eventos-online-default-rtdb.firebaseio.com","FIREBASE_PROJECT_ID":"chat-eventos-online","FIRBASE_STORAGE_BUCKET":"chat-eventos-online.appspot.com","FIREBASE_MESSAGING_SENDER_ID":"557708174668","FIREBASE_APP_ID":"1:557708174668:web:3787feb553d135de779be9"})[FIREBASE_DATABASE_EMULATOR_HOST_VAR]; } if (dbEmulatorHost) { isEmulator = true; dbUrl = "http://" + dbEmulatorHost + "?ns=" + repoInfo.namespace; parsedUrl = parseRepoInfo(dbUrl, nodeAdmin); repoInfo = parsedUrl.repoInfo; } else { isEmulator = !parsedUrl.repoInfo.secure; } var authTokenProvider = nodeAdmin && isEmulator ? new EmulatorAdminTokenProvider() : new FirebaseAuthTokenProvider(app, authProvider); validateUrl('Invalid Firebase Database URL', 1, parsedUrl); if (!pathIsEmpty(parsedUrl.path)) { fatal('Database URL must point to the root of a Firebase Database ' + '(not including a child path).'); } var repo = repoManagerCreateRepo(repoInfo, app, authTokenProvider); return repoGetDatabase(repo); } /** * Remove the repo and make sure it is disconnected. * */ function repoManagerDeleteRepo(repo) { var appRepos = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(repos, repo.app.name); // This should never happen... if (!appRepos || Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(appRepos, repo.key) !== repo) { fatal("Database " + repo.app.name + "(" + repo.repoInfo_ + ") has already been deleted."); } repoInterrupt(repo); delete appRepos[repo.key]; } /** * Ensures a repo doesn't already exist and then creates one using the * provided app. * * @param repoInfo The metadata about the Repo * @return The Repo object for the specified server / repoName. */ function repoManagerCreateRepo(repoInfo, app, authTokenProvider) { var appRepos = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(repos, app.name); if (!appRepos) { appRepos = {}; repos[app.name] = appRepos; } var repo = Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["G" /* safeGet */])(appRepos, repoInfo.toURLString()); if (repo) { fatal('Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.'); } repo = new Repo(repoInfo, useRestClient, app, authTokenProvider); appRepos[repoInfo.toURLString()] = repo; return repo; } /** * Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos. */ function repoManagerForceRestClient(forceRestClient) { useRestClient = forceRestClient; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Class representing a firebase database. */ var Database = /** @class */ (function () { /** * The constructor should not be called by users of our public API. */ function Database(repoInternal_) { var _this = this; this.repoInternal_ = repoInternal_; /** Track if the instance has been used (root or repo accessed) */ this.instanceStarted_ = false; this.INTERNAL = { delete: function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(_this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { this.checkDeleted_('delete'); repoManagerDeleteRepo(this.repo_); this.repoInternal_ = null; this.rootInternal_ = null; return [2 /*return*/]; }); }); } }; if (!(repoInternal_ instanceof Repo)) { fatal("Don't call new Database() directly - please use firebase.database()."); } } Object.defineProperty(Database.prototype, "repo_", { get: function () { if (!this.instanceStarted_) { repoStart(this.repoInternal_); this.instanceStarted_ = true; } return this.repoInternal_; }, enumerable: false, configurable: true }); Object.defineProperty(Database.prototype, "root_", { get: function () { if (!this.rootInternal_) { this.rootInternal_ = new Reference(this.repo_, newEmptyPath()); } return this.rootInternal_; }, enumerable: false, configurable: true }); Object.defineProperty(Database.prototype, "app", { get: function () { return this.repo_.app; }, enumerable: false, configurable: true }); /** * Modify this instance to communicate with the Realtime Database emulator. * *

Note: This method must be called before performing any other operation. * * @param host the emulator host (ex: localhost) * @param port the emulator port (ex: 8080) */ Database.prototype.useEmulator = function (host, port) { this.checkDeleted_('useEmulator'); if (this.instanceStarted_) { fatal('Cannot call useEmulator() after instance has already been initialized.'); return; } // Modify the repo to apply emulator settings repoManagerApplyEmulatorSettings(this.repoInternal_, host, port); }; Database.prototype.ref = function (path) { this.checkDeleted_('ref'); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('database.ref', 0, 1, arguments.length); if (path instanceof Reference) { return this.refFromURL(path.toString()); } return path !== undefined ? this.root_.child(path) : this.root_; }; /** * Returns a reference to the root or the path specified in url. * We throw a exception if the url is not in the same domain as the * current repo. * @return Firebase reference. */ Database.prototype.refFromURL = function (url) { /** @const {string} */ var apiName = 'database.refFromURL'; this.checkDeleted_(apiName); Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])(apiName, 1, 1, arguments.length); var parsedURL = parseRepoInfo(url, this.repo_.repoInfo_.nodeAdmin); validateUrl(apiName, 1, parsedURL); var repoInfo = parsedURL.repoInfo; if (!this.repo_.repoInfo_.isCustomHost() && repoInfo.host !== this.repo_.repoInfo_.host) { fatal(apiName + ': Host name does not match the current database: ' + '(found ' + repoInfo.host + ' but expected ' + this.repo_.repoInfo_.host + ')'); } return this.ref(parsedURL.path.toString()); }; Database.prototype.checkDeleted_ = function (apiName) { if (this.repoInternal_ === null) { fatal('Cannot call ' + apiName + ' on a deleted database.'); } }; // Make individual repo go offline. Database.prototype.goOffline = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('database.goOffline', 0, 0, arguments.length); this.checkDeleted_('goOffline'); repoInterrupt(this.repo_); }; Database.prototype.goOnline = function () { Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["K" /* validateArgCount */])('database.goOnline', 0, 0, arguments.length); this.checkDeleted_('goOnline'); repoResume(this.repo_); }; Database.ServerValue = { TIMESTAMP: { '.sv': 'timestamp' }, increment: function (delta) { return { '.sv': { 'increment': delta } }; } }; return Database; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * INTERNAL methods for internal-use only (tests, etc.). * * Customers shouldn't use these or else should be aware that they could break at any time. */ var forceLongPolling = function () { WebSocketConnection.forceDisallow(); BrowserPollConnection.forceAllow(); }; var forceWebSockets = function () { BrowserPollConnection.forceDisallow(); }; /* Used by App Manager */ var isWebSocketsAvailable = function () { return WebSocketConnection['isAvailable'](); }; var setSecurityDebugCallback = function (ref, callback) { // eslint-disable-next-line @typescript-eslint/no-explicit-any ref.repo.persistentConnection_.securityDebugCallback_ = callback; }; var stats = function (ref, showDelta) { repoStats(ref.repo, showDelta); }; var statsIncrementCounter = function (ref, metric) { repoStatsIncrementCounter(ref.repo, metric); }; var dataUpdateCount = function (ref) { return ref.repo.dataUpdateCount; }; var interceptServerData = function (ref, callback) { return repoInterceptServerData(ref.repo, callback); }; /** * Used by console to create a database based on the app, * passed database URL and a custom auth implementation. * * @param app A valid FirebaseApp-like object * @param url A valid Firebase databaseURL * @param version custom version e.g. firebase-admin version * @param customAuthImpl custom auth implementation */ function initStandalone(_a) { var app = _a.app, url = _a.url, version = _a.version, customAuthImpl = _a.customAuthImpl, namespace = _a.namespace, _b = _a.nodeAdmin, nodeAdmin = _b === void 0 ? false : _b; setSDKVersion(version); /** * ComponentContainer('database-standalone') is just a placeholder that doesn't perform * any actual function. */ var authProvider = new __WEBPACK_IMPORTED_MODULE_4__firebase_component__["c" /* Provider */]('auth-internal', new __WEBPACK_IMPORTED_MODULE_4__firebase_component__["b" /* ComponentContainer */]('database-standalone')); authProvider.setComponent(new __WEBPACK_IMPORTED_MODULE_4__firebase_component__["a" /* Component */]('auth-internal', function () { return customAuthImpl; }, "PRIVATE" /* PRIVATE */)); return { instance: repoManagerDatabaseFromApp(app, authProvider, url, nodeAdmin), namespace: namespace }; } var INTERNAL = /*#__PURE__*/Object.freeze({ __proto__: null, forceLongPolling: forceLongPolling, forceWebSockets: forceWebSockets, isWebSocketsAvailable: isWebSocketsAvailable, setSecurityDebugCallback: setSecurityDebugCallback, stats: stats, statsIncrementCounter: statsIncrementCounter, dataUpdateCount: dataUpdateCount, interceptServerData: interceptServerData, initStandalone: initStandalone }); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var DataConnection = PersistentConnection; // eslint-disable-next-line @typescript-eslint/no-explicit-any PersistentConnection.prototype.simpleListen = function (pathString, onComplete) { this.sendRequest('q', { p: pathString }, onComplete); }; // eslint-disable-next-line @typescript-eslint/no-explicit-any PersistentConnection.prototype.echo = function (data, onEcho) { this.sendRequest('echo', { d: data }, onEcho); }; // RealTimeConnection properties that we use in tests. var RealTimeConnection = Connection; var hijackHash = function (newHash) { var oldPut = PersistentConnection.prototype.put; PersistentConnection.prototype.put = function (pathString, data, onComplete, hash) { if (hash !== undefined) { hash = newHash(); } oldPut.call(this, pathString, data, onComplete, hash); }; return function () { PersistentConnection.prototype.put = oldPut; }; }; var ConnectionTarget = RepoInfo; var queryIdentifier = function (query) { return query.queryIdentifier(); }; /** * Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection. */ var forceRestClient = function (forceRestClient) { repoManagerForceRestClient(forceRestClient); }; var TEST_ACCESS = /*#__PURE__*/Object.freeze({ __proto__: null, DataConnection: DataConnection, RealTimeConnection: RealTimeConnection, hijackHash: hijackHash, ConnectionTarget: ConnectionTarget, queryIdentifier: queryIdentifier, forceRestClient: forceRestClient }); var name = "@firebase/database"; var version = "0.9.6"; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var ServerValue = Database.ServerValue; function registerDatabase(instance) { // set SDK_VERSION setSDKVersion(instance.SDK_VERSION); // Register the Database Service with the 'firebase' namespace. var namespace = instance.INTERNAL.registerComponent(new __WEBPACK_IMPORTED_MODULE_4__firebase_component__["a" /* Component */]('database', function (container, _a) { var url = _a.instanceIdentifier; /* Dependencies */ // getImmediate for FirebaseApp will always succeed var app = container.getProvider('app').getImmediate(); var authProvider = container.getProvider('auth-internal'); return repoManagerDatabaseFromApp(app, authProvider, url, undefined); }, "PUBLIC" /* PUBLIC */) .setServiceProps( // firebase.database namespace properties { Reference: Reference, Query: Query, Database: Database, DataSnapshot: DataSnapshot, enableLogging: enableLogging, INTERNAL: INTERNAL, ServerValue: ServerValue, TEST_ACCESS: TEST_ACCESS }) .setMultipleInstances(true)); instance.registerVersion(name, version); if (Object(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["z" /* isNodeSdk */])()) { module.exports = namespace; } } registerDatabase(__WEBPACK_IMPORTED_MODULE_0__firebase_app__["a" /* default */]); //# sourceMappingURL=index.esm.js.map /* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(91), __webpack_require__(1620)(module))) /***/ }), /***/ 6144: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["c"] = __extends; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __assign; }); /* unused harmony export __rest */ /* unused harmony export __decorate */ /* unused harmony export __param */ /* unused harmony export __metadata */ /* harmony export (immutable) */ __webpack_exports__["b"] = __awaiter; /* harmony export (immutable) */ __webpack_exports__["d"] = __generator; /* unused harmony export __createBinding */ /* unused harmony export __exportStar */ /* harmony export (immutable) */ __webpack_exports__["g"] = __values; /* harmony export (immutable) */ __webpack_exports__["e"] = __read; /* unused harmony export __spread */ /* unused harmony export __spreadArrays */ /* harmony export (immutable) */ __webpack_exports__["f"] = __spreadArray; /* unused harmony export __await */ /* unused harmony export __asyncGenerator */ /* unused harmony export __asyncDelegator */ /* unused harmony export __asyncValues */ /* unused harmony export __makeTemplateObject */ /* unused harmony export __importStar */ /* unused harmony export __importDefault */ /* unused harmony export __classPrivateFieldGet */ /* unused harmony export __classPrivateFieldSet */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; } return __assign.apply(this, arguments); } function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /***/ }), /***/ 6145: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export registerBundle */ /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__firebase_logger__ = __webpack_require__(89); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__firebase_util__ = __webpack_require__(56); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__firebase_webchannel_wrapper__ = __webpack_require__(285); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_tslib__ = __webpack_require__(286); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__prebuilt_7525c6cb_cb60b4b9_js__ = __webpack_require__(1225); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Prototype patches bundle loading to Firestore. */ function t(o) { o.prototype.loadBundle = __WEBPACK_IMPORTED_MODULE_4__prebuilt_7525c6cb_cb60b4b9_js__["k" /* a */], o.prototype.namedQuery = __WEBPACK_IMPORTED_MODULE_4__prebuilt_7525c6cb_cb60b4b9_js__["s" /* u */]; } t(__WEBPACK_IMPORTED_MODULE_4__prebuilt_7525c6cb_cb60b4b9_js__["f" /* Q */]); //# sourceMappingURL=bundle.js.map /***/ }), /***/ 6146: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__firebase_app__ = __webpack_require__(50); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_tslib__ = __webpack_require__(6147); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__firebase_component__ = __webpack_require__(74); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Standard error codes for different ways a request can fail, as defined by: * https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto * * This map is used primarily to convert from a backend error code string to * a client SDK error code string, and make sure it's in the supported set. */ var errorCodeMap = { OK: 'ok', CANCELLED: 'cancelled', UNKNOWN: 'unknown', INVALID_ARGUMENT: 'invalid-argument', DEADLINE_EXCEEDED: 'deadline-exceeded', NOT_FOUND: 'not-found', ALREADY_EXISTS: 'already-exists', PERMISSION_DENIED: 'permission-denied', UNAUTHENTICATED: 'unauthenticated', RESOURCE_EXHAUSTED: 'resource-exhausted', FAILED_PRECONDITION: 'failed-precondition', ABORTED: 'aborted', OUT_OF_RANGE: 'out-of-range', UNIMPLEMENTED: 'unimplemented', INTERNAL: 'internal', UNAVAILABLE: 'unavailable', DATA_LOSS: 'data-loss' }; /** * An explicit error that can be thrown from a handler to send an error to the * client that called the function. */ var HttpsErrorImpl = /** @class */ (function (_super) { Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __extends */])(HttpsErrorImpl, _super); function HttpsErrorImpl(code, message, details) { var _this = _super.call(this, message) || this; // This is a workaround for a bug in TypeScript when extending Error: // tslint:disable-next-line // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work Object.setPrototypeOf(_this, HttpsErrorImpl.prototype); _this.code = code; _this.details = details; return _this; } return HttpsErrorImpl; }(Error)); /** * Takes an HTTP status code and returns the corresponding ErrorCode. * This is the standard HTTP status code -> error mapping defined in: * https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto * * @param status An HTTP status code. * @return The corresponding ErrorCode, or ErrorCode.UNKNOWN if none. */ function codeForHTTPStatus(status) { // Make sure any successful status is OK. if (status >= 200 && status < 300) { return 'ok'; } switch (status) { case 0: // This can happen if the server returns 500. return 'internal'; case 400: return 'invalid-argument'; case 401: return 'unauthenticated'; case 403: return 'permission-denied'; case 404: return 'not-found'; case 409: return 'aborted'; case 429: return 'resource-exhausted'; case 499: return 'cancelled'; case 500: return 'internal'; case 501: return 'unimplemented'; case 503: return 'unavailable'; case 504: return 'deadline-exceeded'; } return 'unknown'; } /** * Takes an HTTP response and returns the corresponding Error, if any. */ function _errorForResponse(status, bodyJSON, serializer) { var code = codeForHTTPStatus(status); // Start with reasonable defaults from the status code. var description = code; var details = undefined; // Then look through the body for explicit details. try { var errorJSON = bodyJSON && bodyJSON.error; if (errorJSON) { var status_1 = errorJSON.status; if (typeof status_1 === 'string') { if (!errorCodeMap[status_1]) { // They must've included an unknown error code in the body. return new HttpsErrorImpl('internal', 'internal'); } code = errorCodeMap[status_1]; // TODO(klimt): Add better default descriptions for error enums. // The default description needs to be updated for the new code. description = status_1; } var message = errorJSON.message; if (typeof message === 'string') { description = message; } details = errorJSON.details; if (details !== undefined) { details = serializer.decode(details); } } } catch (e) { // If we couldn't parse explicit error data, that's fine. } if (code === 'ok') { // Technically, there's an edge case where a developer could explicitly // return an error code of OK, and we will treat it as success, but that // seems reasonable. return null; } return new HttpsErrorImpl(code, description, details); } /** * Helper class to get metadata that should be included with a function call. */ var ContextProvider = /** @class */ (function () { function ContextProvider(authProvider, messagingProvider) { var _this = this; this.auth = null; this.messaging = null; this.auth = authProvider.getImmediate({ optional: true }); this.messaging = messagingProvider.getImmediate({ optional: true }); if (!this.auth) { authProvider.get().then(function (auth) { return (_this.auth = auth); }, function () { /* get() never rejects */ }); } if (!this.messaging) { messagingProvider.get().then(function (messaging) { return (_this.messaging = messaging); }, function () { /* get() never rejects */ }); } } ContextProvider.prototype.getAuthToken = function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __awaiter */])(this, void 0, void 0, function () { var token, e_1; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!this.auth) { return [2 /*return*/, undefined]; } _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.auth.getToken()]; case 2: token = _a.sent(); if (!token) { return [2 /*return*/, undefined]; } return [2 /*return*/, token.accessToken]; case 3: e_1 = _a.sent(); // If there's any error when trying to get the auth token, leave it off. return [2 /*return*/, undefined]; case 4: return [2 /*return*/]; } }); }); }; ContextProvider.prototype.getInstanceIdToken = function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __awaiter */])(this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __generator */])(this, function (_a) { if (!this.messaging || !('Notification' in self) || Notification.permission !== 'granted') { return [2 /*return*/, undefined]; } try { return [2 /*return*/, this.messaging.getToken()]; } catch (e) { // We don't warn on this, because it usually means messaging isn't set up. // console.warn('Failed to retrieve instance id token.', e); // If there's any error when trying to get the token, leave it off. return [2 /*return*/, undefined]; } return [2 /*return*/]; }); }); }; ContextProvider.prototype.getContext = function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __awaiter */])(this, void 0, void 0, function () { var authToken, instanceIdToken; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getAuthToken()]; case 1: authToken = _a.sent(); return [4 /*yield*/, this.getInstanceIdToken()]; case 2: instanceIdToken = _a.sent(); return [2 /*return*/, { authToken: authToken, instanceIdToken: instanceIdToken }]; } }); }); }; return ContextProvider; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var LONG_TYPE = 'type.googleapis.com/google.protobuf.Int64Value'; var UNSIGNED_LONG_TYPE = 'type.googleapis.com/google.protobuf.UInt64Value'; function mapValues( // { [k: string]: unknown } is no longer a wildcard assignment target after typescript 3.5 // eslint-disable-next-line @typescript-eslint/no-explicit-any o, f) { var result = {}; for (var key in o) { if (o.hasOwnProperty(key)) { result[key] = f(o[key]); } } return result; } var Serializer = /** @class */ (function () { function Serializer() { } // Takes data and encodes it in a JSON-friendly way, such that types such as // Date are preserved. Serializer.prototype.encode = function (data) { var _this = this; if (data == null) { return null; } if (data instanceof Number) { data = data.valueOf(); } if (typeof data === 'number' && isFinite(data)) { // Any number in JS is safe to put directly in JSON and parse as a double // without any loss of precision. return data; } if (data === true || data === false) { return data; } if (Object.prototype.toString.call(data) === '[object String]') { return data; } if (Array.isArray(data)) { return data.map(function (x) { return _this.encode(x); }); } if (typeof data === 'function' || typeof data === 'object') { return mapValues(data, function (x) { return _this.encode(x); }); } // If we got this far, the data is not encodable. throw new Error('Data cannot be encoded in JSON: ' + data); }; // Takes data that's been encoded in a JSON-friendly form and returns a form // with richer datatypes, such as Dates, etc. Serializer.prototype.decode = function (json) { var _this = this; if (json == null) { return json; } if (json['@type']) { switch (json['@type']) { case LONG_TYPE: // Fall through and handle this the same as unsigned. case UNSIGNED_LONG_TYPE: { // Technically, this could work return a valid number for malformed // data if there was a number followed by garbage. But it's just not // worth all the extra code to detect that case. var value = Number(json['value']); if (isNaN(value)) { throw new Error('Data cannot be decoded from JSON: ' + json); } return value; } default: { throw new Error('Data cannot be decoded from JSON: ' + json); } } } if (Array.isArray(json)) { return json.map(function (x) { return _this.decode(x); }); } if (typeof json === 'function' || typeof json === 'object') { return mapValues(json, function (x) { return _this.decode(x); }); } // Anything else is safe to return. return json; }; return Serializer; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Returns a Promise that will be rejected after the given duration. * The error will be of type HttpsErrorImpl. * * @param millis Number of milliseconds to wait before rejecting. */ function failAfter(millis) { var timer; var promise = new Promise(function (_, reject) { timer = setTimeout(function () { reject(new HttpsErrorImpl('deadline-exceeded', 'deadline-exceeded')); }, millis); }); return { timer: timer, promise: promise }; } /** * The main class for the Firebase Functions SDK. */ var Service = /** @class */ (function () { /** * Creates a new Functions service for the given app and (optional) region or custom domain. * @param app_ The FirebaseApp to use. * @param regionOrCustomDomain_ one of: * a) A region to call functions from, such as us-central1 * b) A custom domain to use as a functions prefix, such as https://mydomain.com */ function Service(app_, authProvider, messagingProvider, regionOrCustomDomain_, fetchImpl) { var _this = this; if (regionOrCustomDomain_ === void 0) { regionOrCustomDomain_ = 'us-central1'; } this.app_ = app_; this.fetchImpl = fetchImpl; this.serializer = new Serializer(); this.emulatorOrigin = null; this.INTERNAL = { delete: function () { return Promise.resolve(_this.deleteService()); } }; this.contextProvider = new ContextProvider(authProvider, messagingProvider); // Cancels all ongoing requests when resolved. this.cancelAllRequests = new Promise(function (resolve) { _this.deleteService = function () { return resolve(); }; }); // Resolve the region or custom domain overload by attempting to parse it. try { var url = new URL(regionOrCustomDomain_); this.customDomain = url.origin; this.region = 'us-central1'; } catch (e) { this.customDomain = null; this.region = regionOrCustomDomain_; } } Object.defineProperty(Service.prototype, "app", { get: function () { return this.app_; }, enumerable: false, configurable: true }); /** * Returns the URL for a callable with the given name. * @param name The name of the callable. */ Service.prototype._url = function (name) { var projectId = this.app_.options.projectId; if (this.emulatorOrigin !== null) { var origin_1 = this.emulatorOrigin; return origin_1 + "/" + projectId + "/" + this.region + "/" + name; } if (this.customDomain !== null) { return this.customDomain + "/" + name; } return "https://" + this.region + "-" + projectId + ".cloudfunctions.net/" + name; }; /** * Modify this instance to communicate with the Cloud Functions emulator. * * Note: this must be called before this instance has been used to do any operations. * * @param host The emulator host (ex: localhost) * @param port The emulator port (ex: 5001) */ Service.prototype.useEmulator = function (host, port) { this.emulatorOrigin = "http://" + host + ":" + port; }; /** * Changes this instance to point to a Cloud Functions emulator running * locally. See https://firebase.google.com/docs/functions/local-emulator * * @deprecated Prefer the useEmulator(host, port) method. * @param origin The origin of the local emulator, such as * "http://localhost:5005". */ Service.prototype.useFunctionsEmulator = function (origin) { this.emulatorOrigin = origin; }; /** * Returns a reference to the callable https trigger with the given name. * @param name The name of the trigger. */ Service.prototype.httpsCallable = function (name, options) { var _this = this; return function (data) { return _this.call(name, data, options || {}); }; }; /** * Does an HTTP POST and returns the completed response. * @param url The url to post to. * @param body The JSON body of the post. * @param headers The HTTP headers to include in the request. * @return A Promise that will succeed when the request finishes. */ Service.prototype.postJSON = function (url, body, headers) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __awaiter */])(this, void 0, void 0, function () { var response, e_1, json, e_2; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: headers['Content-Type'] = 'application/json'; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.fetchImpl(url, { method: 'POST', body: JSON.stringify(body), headers: headers })]; case 2: response = _a.sent(); return [3 /*break*/, 4]; case 3: e_1 = _a.sent(); // This could be an unhandled error on the backend, or it could be a // network error. There's no way to know, since an unhandled error on the // backend will fail to set the proper CORS header, and thus will be // treated as a network error by fetch. return [2 /*return*/, { status: 0, json: null }]; case 4: json = null; _a.label = 5; case 5: _a.trys.push([5, 7, , 8]); return [4 /*yield*/, response.json()]; case 6: json = _a.sent(); return [3 /*break*/, 8]; case 7: e_2 = _a.sent(); return [3 /*break*/, 8]; case 8: return [2 /*return*/, { status: response.status, json: json }]; } }); }); }; /** * Calls a callable function asynchronously and returns the result. * @param name The name of the callable trigger. * @param data The data to pass as params to the function.s */ Service.prototype.call = function (name, data, options) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __awaiter */])(this, void 0, void 0, function () { var url, body, headers, context, timeout, _a, timer, failAfterPromise, response, error, responseData, decodedData; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: url = this._url(name); // Encode any special types, such as dates, in the input data. data = this.serializer.encode(data); body = { data: data }; headers = {}; return [4 /*yield*/, this.contextProvider.getContext()]; case 1: context = _b.sent(); if (context.authToken) { headers['Authorization'] = 'Bearer ' + context.authToken; } if (context.instanceIdToken) { headers['Firebase-Instance-ID-Token'] = context.instanceIdToken; } timeout = options.timeout || 70000; _a = failAfter(timeout), timer = _a.timer, failAfterPromise = _a.promise; return [4 /*yield*/, Promise.race([ clearTimeoutWrapper(timer, this.postJSON(url, body, headers)), failAfterPromise, clearTimeoutWrapper(timer, this.cancelAllRequests) ])]; case 2: response = _b.sent(); // If service was deleted, interrupted response throws an error. if (!response) { throw new HttpsErrorImpl('cancelled', 'Firebase Functions instance was deleted.'); } error = _errorForResponse(response.status, response.json, this.serializer); if (error) { throw error; } if (!response.json) { throw new HttpsErrorImpl('internal', 'Response is not valid JSON object.'); } responseData = response.json.data; // TODO(klimt): For right now, allow "result" instead of "data", for // backwards compatibility. if (typeof responseData === 'undefined') { responseData = response.json.result; } if (typeof responseData === 'undefined') { // Consider the response malformed. throw new HttpsErrorImpl('internal', 'Response is missing data field.'); } decodedData = this.serializer.decode(responseData); return [2 /*return*/, { data: decodedData }]; } }); }); }; return Service; }()); function clearTimeoutWrapper(timer, promise) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __awaiter */])(this, void 0, void 0, function () { var result; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, promise]; case 1: result = _a.sent(); // eslint-disable-next-line @typescript-eslint/no-explicit-any clearTimeout(timer); return [2 /*return*/, result]; } }); }); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Type constant for Firebase Functions. */ var FUNCTIONS_TYPE = 'functions'; function registerFunctions(instance, fetchImpl) { var namespaceExports = { // no-inline Functions: Service }; function factory(container, _a) { var regionOrCustomDomain = _a.instanceIdentifier; // Dependencies var app = container.getProvider('app').getImmediate(); var authProvider = container.getProvider('auth-internal'); var messagingProvider = container.getProvider('messaging'); // eslint-disable-next-line @typescript-eslint/no-explicit-any return new Service(app, authProvider, messagingProvider, regionOrCustomDomain, fetchImpl); } instance.INTERNAL.registerComponent(new __WEBPACK_IMPORTED_MODULE_2__firebase_component__["a" /* Component */](FUNCTIONS_TYPE, factory, "PUBLIC" /* PUBLIC */) .setServiceProps(namespaceExports) .setMultipleInstances(true)); } var name = "@firebase/functions"; var version = "0.6.4"; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ registerFunctions(__WEBPACK_IMPORTED_MODULE_0__firebase_app__["a" /* default */], fetch.bind(self)); __WEBPACK_IMPORTED_MODULE_0__firebase_app__["a" /* default */].registerVersion(name, version); //# sourceMappingURL=index.esm.js.map /***/ }), /***/ 6147: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["b"] = __extends; /* unused harmony export __assign */ /* unused harmony export __rest */ /* unused harmony export __decorate */ /* unused harmony export __param */ /* unused harmony export __metadata */ /* harmony export (immutable) */ __webpack_exports__["a"] = __awaiter; /* harmony export (immutable) */ __webpack_exports__["c"] = __generator; /* unused harmony export __createBinding */ /* unused harmony export __exportStar */ /* unused harmony export __values */ /* unused harmony export __read */ /* unused harmony export __spread */ /* unused harmony export __spreadArrays */ /* unused harmony export __spreadArray */ /* unused harmony export __await */ /* unused harmony export __asyncGenerator */ /* unused harmony export __asyncDelegator */ /* unused harmony export __asyncValues */ /* unused harmony export __makeTemplateObject */ /* unused harmony export __importStar */ /* unused harmony export __importDefault */ /* unused harmony export __classPrivateFieldGet */ /* unused harmony export __classPrivateFieldSet */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; } return __assign.apply(this, arguments); } function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /***/ }), /***/ 6148: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__firebase_installations__ = __webpack_require__(198); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__firebase_component__ = __webpack_require__(74); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__firebase_util__ = __webpack_require__(56); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_tslib__ = __webpack_require__(6150); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_idb__ = __webpack_require__(1621); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_idb___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_idb__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__firebase_app__ = __webpack_require__(50); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var _a; var ERROR_MAP = (_a = {}, _a["missing-app-config-values" /* MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: "{$valueName}"', _a["only-available-in-window" /* AVAILABLE_IN_WINDOW */] = 'This method is available in a Window context.', _a["only-available-in-sw" /* AVAILABLE_IN_SW */] = 'This method is available in a service worker context.', _a["permission-default" /* PERMISSION_DEFAULT */] = 'The notification permission was not granted and dismissed instead.', _a["permission-blocked" /* PERMISSION_BLOCKED */] = 'The notification permission was not granted and blocked instead.', _a["unsupported-browser" /* UNSUPPORTED_BROWSER */] = "This browser doesn't support the API's required to use the firebase SDK.", _a["failed-service-worker-registration" /* FAILED_DEFAULT_REGISTRATION */] = 'We are unable to register the default service worker. {$browserErrorMessage}', _a["token-subscribe-failed" /* TOKEN_SUBSCRIBE_FAILED */] = 'A problem occurred while subscribing the user to FCM: {$errorInfo}', _a["token-subscribe-no-token" /* TOKEN_SUBSCRIBE_NO_TOKEN */] = 'FCM returned no token when subscribing the user to push.', _a["token-unsubscribe-failed" /* TOKEN_UNSUBSCRIBE_FAILED */] = 'A problem occurred while unsubscribing the ' + 'user from FCM: {$errorInfo}', _a["token-update-failed" /* TOKEN_UPDATE_FAILED */] = 'A problem occurred while updating the user from FCM: {$errorInfo}', _a["token-update-no-token" /* TOKEN_UPDATE_NO_TOKEN */] = 'FCM returned no token when updating the user to push.', _a["use-sw-after-get-token" /* USE_SW_AFTER_GET_TOKEN */] = 'The useServiceWorker() method may only be called once and must be ' + 'called before calling getToken() to ensure your service worker is used.', _a["invalid-sw-registration" /* INVALID_SW_REGISTRATION */] = 'The input to useServiceWorker() must be a ServiceWorkerRegistration.', _a["invalid-bg-handler" /* INVALID_BG_HANDLER */] = 'The input to setBackgroundMessageHandler() must be a function.', _a["invalid-vapid-key" /* INVALID_VAPID_KEY */] = 'The public VAPID key must be a string.', _a["use-vapid-key-after-get-token" /* USE_VAPID_KEY_AFTER_GET_TOKEN */] = 'The usePublicVapidKey() method may only be called once and must be ' + 'called before calling getToken() to ensure your VAPID key is used.', _a); var ERROR_FACTORY = new __WEBPACK_IMPORTED_MODULE_2__firebase_util__["b" /* ErrorFactory */]('messaging', 'Messaging', ERROR_MAP); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var DEFAULT_SW_PATH = '/firebase-messaging-sw.js'; var DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope'; var DEFAULT_VAPID_KEY = 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4'; var ENDPOINT = 'https://fcmregistrations.googleapis.com/v1'; // Key of FCM Payload in Notification's data field. var FCM_MSG = 'FCM_MSG'; var TAG = 'FirebaseMessaging: '; // Set to '1' if Analytics is enabled for the campaign var CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e'; var CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id'; var CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts'; var CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l'; // Due to the fact that onBackgroundMessage can't be awaited (to support rxjs), a silent push // warning might be shown by the browser if the callback fails to completes by the end of onPush. // Experiments were ran to determine the majority onBackground message clock time. This brief // blocking time would allow majority of the onBackgroundMessage callback to finish. var BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS = 1000; // Preparation time for client to initialize and set up the message handler. var FOREGROUND_HANDLE_PREPARATION_TIME_MS = 3000; /** * @license * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ var MessageType; (function (MessageType) { MessageType["PUSH_RECEIVED"] = "push-received"; MessageType["NOTIFICATION_CLICKED"] = "notification-clicked"; })(MessageType || (MessageType = {})); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function arrayToBase64(array) { var uint8Array = new Uint8Array(array); var base64String = btoa(String.fromCharCode.apply(String, Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["e" /* __spreadArray */])([], Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["d" /* __read */])(uint8Array)))); return base64String.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); } function base64ToArray(base64String) { var padding = '='.repeat((4 - (base64String.length % 4)) % 4); var base64 = (base64String + padding) .replace(/\-/g, '+') .replace(/_/g, '/'); var rawData = atob(base64); var outputArray = new Uint8Array(rawData.length); for (var i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var OLD_DB_NAME = 'fcm_token_details_db'; /** * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade * callback is called for all versions of the old DB. */ var OLD_DB_VERSION = 5; var OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store'; function migrateOldDatabase(senderId) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var databases, dbNames, tokenDetails, db; var _this = this; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!('databases' in indexedDB)) return [3 /*break*/, 2]; return [4 /*yield*/, indexedDB.databases()]; case 1: databases = _a.sent(); dbNames = databases.map(function (db) { return db.name; }); if (!dbNames.includes(OLD_DB_NAME)) { // old DB didn't exist, no need to open. return [2 /*return*/, null]; } _a.label = 2; case 2: tokenDetails = null; return [4 /*yield*/, Object(__WEBPACK_IMPORTED_MODULE_4_idb__["openDb"])(OLD_DB_NAME, OLD_DB_VERSION, function (db) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(_this, void 0, void 0, function () { var objectStore, value, oldDetails, oldDetails, oldDetails; var _a; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: if (db.oldVersion < 2) { // Database too old, skip migration. return [2 /*return*/]; } if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) { // Database did not exist. Nothing to do. return [2 /*return*/]; } objectStore = db.transaction.objectStore(OLD_OBJECT_STORE_NAME); return [4 /*yield*/, objectStore.index('fcmSenderId').get(senderId)]; case 1: value = _b.sent(); return [4 /*yield*/, objectStore.clear()]; case 2: _b.sent(); if (!value) { // No entry in the database, nothing to migrate. return [2 /*return*/]; } if (db.oldVersion === 2) { oldDetails = value; if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) { return [2 /*return*/]; } tokenDetails = { token: oldDetails.fcmToken, createTime: (_a = oldDetails.createTime) !== null && _a !== void 0 ? _a : Date.now(), subscriptionOptions: { auth: oldDetails.auth, p256dh: oldDetails.p256dh, endpoint: oldDetails.endpoint, swScope: oldDetails.swScope, vapidKey: typeof oldDetails.vapidKey === 'string' ? oldDetails.vapidKey : arrayToBase64(oldDetails.vapidKey) } }; } else if (db.oldVersion === 3) { oldDetails = value; tokenDetails = { token: oldDetails.fcmToken, createTime: oldDetails.createTime, subscriptionOptions: { auth: arrayToBase64(oldDetails.auth), p256dh: arrayToBase64(oldDetails.p256dh), endpoint: oldDetails.endpoint, swScope: oldDetails.swScope, vapidKey: arrayToBase64(oldDetails.vapidKey) } }; } else if (db.oldVersion === 4) { oldDetails = value; tokenDetails = { token: oldDetails.fcmToken, createTime: oldDetails.createTime, subscriptionOptions: { auth: arrayToBase64(oldDetails.auth), p256dh: arrayToBase64(oldDetails.p256dh), endpoint: oldDetails.endpoint, swScope: oldDetails.swScope, vapidKey: arrayToBase64(oldDetails.vapidKey) } }; } return [2 /*return*/]; } }); }); })]; case 3: db = _a.sent(); db.close(); // Delete all old databases. return [4 /*yield*/, Object(__WEBPACK_IMPORTED_MODULE_4_idb__["deleteDb"])(OLD_DB_NAME)]; case 4: // Delete all old databases. _a.sent(); return [4 /*yield*/, Object(__WEBPACK_IMPORTED_MODULE_4_idb__["deleteDb"])('fcm_vapid_details_db')]; case 5: _a.sent(); return [4 /*yield*/, Object(__WEBPACK_IMPORTED_MODULE_4_idb__["deleteDb"])('undefined')]; case 6: _a.sent(); return [2 /*return*/, checkTokenDetails(tokenDetails) ? tokenDetails : null]; } }); }); } function checkTokenDetails(tokenDetails) { if (!tokenDetails || !tokenDetails.subscriptionOptions) { return false; } var subscriptionOptions = tokenDetails.subscriptionOptions; return (typeof tokenDetails.createTime === 'number' && tokenDetails.createTime > 0 && typeof tokenDetails.token === 'string' && tokenDetails.token.length > 0 && typeof subscriptionOptions.auth === 'string' && subscriptionOptions.auth.length > 0 && typeof subscriptionOptions.p256dh === 'string' && subscriptionOptions.p256dh.length > 0 && typeof subscriptionOptions.endpoint === 'string' && subscriptionOptions.endpoint.length > 0 && typeof subscriptionOptions.swScope === 'string' && subscriptionOptions.swScope.length > 0 && typeof subscriptionOptions.vapidKey === 'string' && subscriptionOptions.vapidKey.length > 0); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Exported for tests. var DATABASE_NAME = 'firebase-messaging-database'; var DATABASE_VERSION = 1; var OBJECT_STORE_NAME = 'firebase-messaging-store'; var dbPromise = null; function getDbPromise() { if (!dbPromise) { dbPromise = Object(__WEBPACK_IMPORTED_MODULE_4_idb__["openDb"])(DATABASE_NAME, DATABASE_VERSION, function (upgradeDb) { // We don't use 'break' in this switch statement, the fall-through behavior is what we want, // because if there are multiple versions between the old version and the current version, we // want ALL the migrations that correspond to those versions to run, not only the last one. // eslint-disable-next-line default-case switch (upgradeDb.oldVersion) { case 0: upgradeDb.createObjectStore(OBJECT_STORE_NAME); } }); } return dbPromise; } /** Gets record(s) from the objectStore that match the given key. */ function dbGet(firebaseDependencies) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var key, db, tokenDetails, oldTokenDetails; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: key = getKey(firebaseDependencies); return [4 /*yield*/, getDbPromise()]; case 1: db = _a.sent(); return [4 /*yield*/, db .transaction(OBJECT_STORE_NAME) .objectStore(OBJECT_STORE_NAME) .get(key)]; case 2: tokenDetails = _a.sent(); if (!tokenDetails) return [3 /*break*/, 3]; return [2 /*return*/, tokenDetails]; case 3: return [4 /*yield*/, migrateOldDatabase(firebaseDependencies.appConfig.senderId)]; case 4: oldTokenDetails = _a.sent(); if (!oldTokenDetails) return [3 /*break*/, 6]; return [4 /*yield*/, dbSet(firebaseDependencies, oldTokenDetails)]; case 5: _a.sent(); return [2 /*return*/, oldTokenDetails]; case 6: return [2 /*return*/]; } }); }); } /** Assigns or overwrites the record for the given key with the given value. */ function dbSet(firebaseDependencies, tokenDetails) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var key, db, tx; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: key = getKey(firebaseDependencies); return [4 /*yield*/, getDbPromise()]; case 1: db = _a.sent(); tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key)]; case 2: _a.sent(); return [4 /*yield*/, tx.complete]; case 3: _a.sent(); return [2 /*return*/, tokenDetails]; } }); }); } /** Removes record(s) from the objectStore that match the given key. */ function dbRemove(firebaseDependencies) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var key, db, tx; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: key = getKey(firebaseDependencies); return [4 /*yield*/, getDbPromise()]; case 1: db = _a.sent(); tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)]; case 2: _a.sent(); return [4 /*yield*/, tx.complete]; case 3: _a.sent(); return [2 /*return*/]; } }); }); } function getKey(_a) { var appConfig = _a.appConfig; return appConfig.appId; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function requestGetToken(firebaseDependencies, subscriptionOptions) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var headers, body, subscribeOptions, responseData, response, err_1, message; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, getHeaders(firebaseDependencies)]; case 1: headers = _a.sent(); body = getBody(subscriptionOptions); subscribeOptions = { method: 'POST', headers: headers, body: JSON.stringify(body) }; _a.label = 2; case 2: _a.trys.push([2, 5, , 6]); return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig), subscribeOptions)]; case 3: response = _a.sent(); return [4 /*yield*/, response.json()]; case 4: responseData = _a.sent(); return [3 /*break*/, 6]; case 5: err_1 = _a.sent(); throw ERROR_FACTORY.create("token-subscribe-failed" /* TOKEN_SUBSCRIBE_FAILED */, { errorInfo: err_1 }); case 6: if (responseData.error) { message = responseData.error.message; throw ERROR_FACTORY.create("token-subscribe-failed" /* TOKEN_SUBSCRIBE_FAILED */, { errorInfo: message }); } if (!responseData.token) { throw ERROR_FACTORY.create("token-subscribe-no-token" /* TOKEN_SUBSCRIBE_NO_TOKEN */); } return [2 /*return*/, responseData.token]; } }); }); } function requestUpdateToken(firebaseDependencies, tokenDetails) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var headers, body, updateOptions, responseData, response, err_2, message; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, getHeaders(firebaseDependencies)]; case 1: headers = _a.sent(); body = getBody(tokenDetails.subscriptionOptions); updateOptions = { method: 'PATCH', headers: headers, body: JSON.stringify(body) }; _a.label = 2; case 2: _a.trys.push([2, 5, , 6]); return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig) + "/" + tokenDetails.token, updateOptions)]; case 3: response = _a.sent(); return [4 /*yield*/, response.json()]; case 4: responseData = _a.sent(); return [3 /*break*/, 6]; case 5: err_2 = _a.sent(); throw ERROR_FACTORY.create("token-update-failed" /* TOKEN_UPDATE_FAILED */, { errorInfo: err_2 }); case 6: if (responseData.error) { message = responseData.error.message; throw ERROR_FACTORY.create("token-update-failed" /* TOKEN_UPDATE_FAILED */, { errorInfo: message }); } if (!responseData.token) { throw ERROR_FACTORY.create("token-update-no-token" /* TOKEN_UPDATE_NO_TOKEN */); } return [2 /*return*/, responseData.token]; } }); }); } function requestDeleteToken(firebaseDependencies, token) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var headers, unsubscribeOptions, response, responseData, message, err_3; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, getHeaders(firebaseDependencies)]; case 1: headers = _a.sent(); unsubscribeOptions = { method: 'DELETE', headers: headers }; _a.label = 2; case 2: _a.trys.push([2, 5, , 6]); return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig) + "/" + token, unsubscribeOptions)]; case 3: response = _a.sent(); return [4 /*yield*/, response.json()]; case 4: responseData = _a.sent(); if (responseData.error) { message = responseData.error.message; throw ERROR_FACTORY.create("token-unsubscribe-failed" /* TOKEN_UNSUBSCRIBE_FAILED */, { errorInfo: message }); } return [3 /*break*/, 6]; case 5: err_3 = _a.sent(); throw ERROR_FACTORY.create("token-unsubscribe-failed" /* TOKEN_UNSUBSCRIBE_FAILED */, { errorInfo: err_3 }); case 6: return [2 /*return*/]; } }); }); } function getEndpoint(_a) { var projectId = _a.projectId; return ENDPOINT + "/projects/" + projectId + "/registrations"; } function getHeaders(_a) { var appConfig = _a.appConfig, installations = _a.installations; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var authToken; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, installations.getToken()]; case 1: authToken = _b.sent(); return [2 /*return*/, new Headers({ 'Content-Type': 'application/json', Accept: 'application/json', 'x-goog-api-key': appConfig.apiKey, 'x-goog-firebase-installations-auth': "FIS " + authToken })]; } }); }); } function getBody(_a) { var p256dh = _a.p256dh, auth = _a.auth, endpoint = _a.endpoint, vapidKey = _a.vapidKey; var body = { web: { endpoint: endpoint, auth: auth, p256dh: p256dh } }; if (vapidKey !== DEFAULT_VAPID_KEY) { body.web.applicationPubKey = vapidKey; } return body; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** UpdateRegistration will be called once every week. */ var TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days function getToken(firebaseDependencies, swRegistration, vapidKey) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var pushSubscription, tokenDetails, subscriptionOptions, e_1; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (Notification.permission !== 'granted') { throw ERROR_FACTORY.create("permission-blocked" /* PERMISSION_BLOCKED */); } return [4 /*yield*/, getPushSubscription(swRegistration, vapidKey)]; case 1: pushSubscription = _a.sent(); return [4 /*yield*/, dbGet(firebaseDependencies)]; case 2: tokenDetails = _a.sent(); subscriptionOptions = { vapidKey: vapidKey, swScope: swRegistration.scope, endpoint: pushSubscription.endpoint, auth: arrayToBase64(pushSubscription.getKey('auth')), p256dh: arrayToBase64(pushSubscription.getKey('p256dh')) }; if (!!tokenDetails) return [3 /*break*/, 3]; // No token, get a new one. return [2 /*return*/, getNewToken(firebaseDependencies, subscriptionOptions)]; case 3: if (!!isTokenValid(tokenDetails.subscriptionOptions, subscriptionOptions)) return [3 /*break*/, 8]; _a.label = 4; case 4: _a.trys.push([4, 6, , 7]); return [4 /*yield*/, requestDeleteToken(firebaseDependencies, tokenDetails.token)]; case 5: _a.sent(); return [3 /*break*/, 7]; case 6: e_1 = _a.sent(); // Suppress errors because of #2364 console.warn(e_1); return [3 /*break*/, 7]; case 7: return [2 /*return*/, getNewToken(firebaseDependencies, subscriptionOptions)]; case 8: if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) { // Weekly token refresh return [2 /*return*/, updateToken({ token: tokenDetails.token, createTime: Date.now(), subscriptionOptions: subscriptionOptions }, firebaseDependencies, swRegistration)]; } else { // Valid token, nothing to do. return [2 /*return*/, tokenDetails.token]; } case 9: return [2 /*return*/]; } }); }); } /** * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters * the push subscription if it exists. */ function deleteToken(firebaseDependencies, swRegistration) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var tokenDetails, pushSubscription; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, dbGet(firebaseDependencies)]; case 1: tokenDetails = _a.sent(); if (!tokenDetails) return [3 /*break*/, 4]; return [4 /*yield*/, requestDeleteToken(firebaseDependencies, tokenDetails.token)]; case 2: _a.sent(); return [4 /*yield*/, dbRemove(firebaseDependencies)]; case 3: _a.sent(); _a.label = 4; case 4: return [4 /*yield*/, swRegistration.pushManager.getSubscription()]; case 5: pushSubscription = _a.sent(); if (pushSubscription) { return [2 /*return*/, pushSubscription.unsubscribe()]; } // If there's no SW, consider it a success. return [2 /*return*/, true]; } }); }); } function updateToken(tokenDetails, firebaseDependencies, swRegistration) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var updatedToken, updatedTokenDetails, e_2; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, , 5]); return [4 /*yield*/, requestUpdateToken(firebaseDependencies, tokenDetails)]; case 1: updatedToken = _a.sent(); updatedTokenDetails = Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["a" /* __assign */])(Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["a" /* __assign */])({}, tokenDetails), { token: updatedToken, createTime: Date.now() }); return [4 /*yield*/, dbSet(firebaseDependencies, updatedTokenDetails)]; case 2: _a.sent(); return [2 /*return*/, updatedToken]; case 3: e_2 = _a.sent(); return [4 /*yield*/, deleteToken(firebaseDependencies, swRegistration)]; case 4: _a.sent(); throw e_2; case 5: return [2 /*return*/]; } }); }); } function getNewToken(firebaseDependencies, subscriptionOptions) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var token, tokenDetails; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, requestGetToken(firebaseDependencies, subscriptionOptions)]; case 1: token = _a.sent(); tokenDetails = { token: token, createTime: Date.now(), subscriptionOptions: subscriptionOptions }; return [4 /*yield*/, dbSet(firebaseDependencies, tokenDetails)]; case 2: _a.sent(); return [2 /*return*/, tokenDetails.token]; } }); }); } /** * Gets a PushSubscription for the current user. */ function getPushSubscription(swRegistration, vapidKey) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var subscription; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, swRegistration.pushManager.getSubscription()]; case 1: subscription = _a.sent(); if (subscription) { return [2 /*return*/, subscription]; } return [2 /*return*/, swRegistration.pushManager.subscribe({ userVisibleOnly: true, // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key // submitted to pushManager#subscribe must be of type Uint8Array. applicationServerKey: base64ToArray(vapidKey) })]; } }); }); } /** * Checks if the saved tokenDetails object matches the configuration provided. */ function isTokenValid(dbOptions, currentOptions) { var isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey; var isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint; var isAuthEqual = currentOptions.auth === dbOptions.auth; var isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh; return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual; } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function externalizePayload(internalPayload) { var payload = { from: internalPayload.from, // eslint-disable-next-line camelcase collapseKey: internalPayload.collapse_key }; propagateNotificationPayload(payload, internalPayload); propagateDataPayload(payload, internalPayload); propagateFcmOptions(payload, internalPayload); return payload; } function propagateNotificationPayload(payload, messagePayloadInternal) { if (!messagePayloadInternal.notification) { return; } payload.notification = {}; var title = messagePayloadInternal.notification.title; if (!!title) { payload.notification.title = title; } var body = messagePayloadInternal.notification.body; if (!!body) { payload.notification.body = body; } var image = messagePayloadInternal.notification.image; if (!!image) { payload.notification.image = image; } } function propagateDataPayload(payload, messagePayloadInternal) { if (!messagePayloadInternal.data) { return; } payload.data = messagePayloadInternal.data; } function propagateFcmOptions(payload, messagePayloadInternal) { if (!messagePayloadInternal.fcmOptions) { return; } payload.fcmOptions = {}; var link = messagePayloadInternal.fcmOptions.link; if (!!link) { payload.fcmOptions.link = link; } // eslint-disable-next-line camelcase var analyticsLabel = messagePayloadInternal.fcmOptions.analytics_label; if (!!analyticsLabel) { payload.fcmOptions.analyticsLabel = analyticsLabel; } } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function isConsoleMessage(data) { // This message has a campaign ID, meaning it was sent using the Firebase Console. return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** Returns a promise that resolves after given time passes. */ function sleep(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var SwController = /** @class */ (function () { function SwController(firebaseDependencies) { var _this = this; this.firebaseDependencies = firebaseDependencies; // A boolean flag to determine wether an app is using onBackgroundMessage or // setBackgroundMessageHandler. onBackgroundMessage will receive a MessagePayload regardless of if // a notification is displayed. Whereas, setBackgroundMessageHandler will swallow the // MessagePayload if a NotificationPayload is included. this.isOnBackgroundMessageUsed = null; this.vapidKey = null; this.bgMessageHandler = null; self.addEventListener('push', function (e) { e.waitUntil(_this.onPush(e)); }); self.addEventListener('pushsubscriptionchange', function (e) { e.waitUntil(_this.onSubChange(e)); }); self.addEventListener('notificationclick', function (e) { e.waitUntil(_this.onNotificationClick(e)); }); } Object.defineProperty(SwController.prototype, "app", { get: function () { return this.firebaseDependencies.app; }, enumerable: false, configurable: true }); /** * @deprecated. Use onBackgroundMessage(nextOrObserver: NextFn | Observer): * Unsubscribe instead. * * Calling setBackgroundMessageHandler will opt in to some specific behaviors. * * 1.) If a notification doesn't need to be shown due to a window already being visible, then push * messages will be sent to the page. 2.) If a notification needs to be shown, and the message * contains no notification data this method will be called and the promise it returns will be * passed to event.waitUntil. If you do not set this callback then all push messages will let and * the developer can handle them in a their own 'push' event callback * * @param callback The callback to be called when a push message is received and a notification * must be shown. The callback will be given the data from the push message. */ SwController.prototype.setBackgroundMessageHandler = function (callback) { this.isOnBackgroundMessageUsed = false; if (!callback || typeof callback !== 'function') { throw ERROR_FACTORY.create("invalid-bg-handler" /* INVALID_BG_HANDLER */); } this.bgMessageHandler = callback; }; SwController.prototype.onBackgroundMessage = function (nextOrObserver) { var _this = this; this.isOnBackgroundMessageUsed = true; this.bgMessageHandler = nextOrObserver; return function () { _this.bgMessageHandler = null; }; }; // TODO: Remove getToken from SW Controller. Calling this from an old SW can cause all kinds of // trouble. SwController.prototype.getToken = function () { var _a, _b; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var tokenDetails; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_c) { switch (_c.label) { case 0: if (!!this.vapidKey) return [3 /*break*/, 2]; return [4 /*yield*/, dbGet(this.firebaseDependencies)]; case 1: tokenDetails = _c.sent(); this.vapidKey = (_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY; _c.label = 2; case 2: return [2 /*return*/, getToken(this.firebaseDependencies, self.registration, this.vapidKey)]; } }); }); }; // TODO: Remove deleteToken from SW Controller. Calling this from an old SW can cause all kinds of // trouble. SwController.prototype.deleteToken = function () { return deleteToken(this.firebaseDependencies, self.registration); }; SwController.prototype.requestPermission = function () { throw ERROR_FACTORY.create("only-available-in-window" /* AVAILABLE_IN_WINDOW */); }; // TODO: Remove this together with getToken from SW Controller. SwController.prototype.usePublicVapidKey = function (vapidKey) { if (this.vapidKey !== null) { throw ERROR_FACTORY.create("use-vapid-key-after-get-token" /* USE_VAPID_KEY_AFTER_GET_TOKEN */); } if (typeof vapidKey !== 'string' || vapidKey.length === 0) { throw ERROR_FACTORY.create("invalid-vapid-key" /* INVALID_VAPID_KEY */); } this.vapidKey = vapidKey; }; SwController.prototype.useServiceWorker = function () { throw ERROR_FACTORY.create("only-available-in-window" /* AVAILABLE_IN_WINDOW */); }; SwController.prototype.onMessage = function () { throw ERROR_FACTORY.create("only-available-in-window" /* AVAILABLE_IN_WINDOW */); }; SwController.prototype.onTokenRefresh = function () { throw ERROR_FACTORY.create("only-available-in-window" /* AVAILABLE_IN_WINDOW */); }; /** * A handler for push events that shows notifications based on the content of the payload. * * The payload must be a JSON-encoded Object with a `notification` key. The value of the * `notification` property will be used as the NotificationOptions object passed to * showNotification. Additionally, the `title` property of the notification object will be used as * the title. * * If there is no notification data in the payload then no notification will be shown. */ SwController.prototype.onPush = function (event) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var internalPayload, clientList, isNotificationShown, payload; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: internalPayload = getMessagePayloadInternal(event); if (!internalPayload) { console.debug(TAG + 'failed to get parsed MessagePayload from the PushEvent. Skip handling the push.'); return [2 /*return*/]; } return [4 /*yield*/, getClientList()]; case 1: clientList = _a.sent(); if (hasVisibleClients(clientList)) { return [2 /*return*/, sendMessagePayloadInternalToWindows(clientList, internalPayload)]; } isNotificationShown = false; if (!!!internalPayload.notification) return [3 /*break*/, 3]; return [4 /*yield*/, showNotification(wrapInternalPayload(internalPayload))]; case 2: _a.sent(); isNotificationShown = true; _a.label = 3; case 3: // MessagePayload is only passed to `onBackgroundMessage`. Skip passing MessagePayload for // the legacy `setBackgroundMessageHandler` to preserve the SDK behaviors. if (isNotificationShown === true && this.isOnBackgroundMessageUsed === false) { return [2 /*return*/]; } if (!!this.bgMessageHandler) { payload = externalizePayload(internalPayload); if (typeof this.bgMessageHandler === 'function') { this.bgMessageHandler(payload); } else { this.bgMessageHandler.next(payload); } } // wait briefly to allow onBackgroundMessage to complete return [4 /*yield*/, sleep(BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS)]; case 4: // wait briefly to allow onBackgroundMessage to complete _a.sent(); return [2 /*return*/]; } }); }); }; SwController.prototype.onSubChange = function (event) { var _a, _b; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var newSubscription, tokenDetails; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_c) { switch (_c.label) { case 0: newSubscription = event.newSubscription; if (!!newSubscription) return [3 /*break*/, 2]; // Subscription revoked, delete token return [4 /*yield*/, deleteToken(this.firebaseDependencies, self.registration)]; case 1: // Subscription revoked, delete token _c.sent(); return [2 /*return*/]; case 2: return [4 /*yield*/, dbGet(this.firebaseDependencies)]; case 3: tokenDetails = _c.sent(); return [4 /*yield*/, deleteToken(this.firebaseDependencies, self.registration)]; case 4: _c.sent(); return [4 /*yield*/, getToken(this.firebaseDependencies, self.registration, (_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY)]; case 5: _c.sent(); return [2 /*return*/]; } }); }); }; SwController.prototype.onNotificationClick = function (event) { var _a, _b; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var internalPayload, link, url, originUrl, client; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_c) { switch (_c.label) { case 0: internalPayload = (_b = (_a = event.notification) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[FCM_MSG]; if (!internalPayload) { return [2 /*return*/]; } else if (event.action) { // User clicked on an action button. This will allow developers to act on action button clicks // by using a custom onNotificationClick listener that they define. return [2 /*return*/]; } // Prevent other listeners from receiving the event event.stopImmediatePropagation(); event.notification.close(); link = getLink(internalPayload); if (!link) { return [2 /*return*/]; } url = new URL(link, self.location.href); originUrl = new URL(self.location.origin); if (url.host !== originUrl.host) { return [2 /*return*/]; } return [4 /*yield*/, getWindowClient(url)]; case 1: client = _c.sent(); if (!!client) return [3 /*break*/, 4]; return [4 /*yield*/, self.clients.openWindow(link)]; case 2: client = _c.sent(); // Wait three seconds for the client to initialize and set up the message handler so that it // can receive the message. return [4 /*yield*/, sleep(FOREGROUND_HANDLE_PREPARATION_TIME_MS)]; case 3: // Wait three seconds for the client to initialize and set up the message handler so that it // can receive the message. _c.sent(); return [3 /*break*/, 6]; case 4: return [4 /*yield*/, client.focus()]; case 5: client = _c.sent(); _c.label = 6; case 6: if (!client) { // Window Client will not be returned if it's for a third party origin. return [2 /*return*/]; } internalPayload.messageType = MessageType.NOTIFICATION_CLICKED; internalPayload.isFirebaseMessaging = true; return [2 /*return*/, client.postMessage(internalPayload)]; } }); }); }; return SwController; }()); function wrapInternalPayload(internalPayload) { var _a; var wrappedInternalPayload = Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["a" /* __assign */])({}, internalPayload.notification); // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM // notification vs a notification from somewhere else (i.e. normal web push or developer generated // notification). wrappedInternalPayload.data = (_a = {}, _a[FCM_MSG] = internalPayload, _a); return wrappedInternalPayload; } function getMessagePayloadInternal(_a) { var data = _a.data; if (!data) { return null; } try { return data.json(); } catch (err) { // Not JSON so not an FCM message. return null; } } /** * @param url The URL to look for when focusing a client. * @return Returns an existing window client or a newly opened WindowClient. */ function getWindowClient(url) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var clientList, clientList_1, clientList_1_1, client, clientUrl; var e_1, _a; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, getClientList()]; case 1: clientList = _b.sent(); try { for (clientList_1 = Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["f" /* __values */])(clientList), clientList_1_1 = clientList_1.next(); !clientList_1_1.done; clientList_1_1 = clientList_1.next()) { client = clientList_1_1.value; clientUrl = new URL(client.url, self.location.href); if (url.host === clientUrl.host) { return [2 /*return*/, client]; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (clientList_1_1 && !clientList_1_1.done && (_a = clientList_1.return)) _a.call(clientList_1); } finally { if (e_1) throw e_1.error; } } return [2 /*return*/, null]; } }); }); } /** * @returns If there is currently a visible WindowClient, this method will resolve to true, * otherwise false. */ function hasVisibleClients(clientList) { return clientList.some(function (client) { return client.visibilityState === 'visible' && // Ignore chrome-extension clients as that matches the background pages of extensions, which // are always considered visible for some reason. !client.url.startsWith('chrome-extension://'); }); } function sendMessagePayloadInternalToWindows(clientList, internalPayload) { var e_2, _a; internalPayload.isFirebaseMessaging = true; internalPayload.messageType = MessageType.PUSH_RECEIVED; try { for (var clientList_2 = Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["f" /* __values */])(clientList), clientList_2_1 = clientList_2.next(); !clientList_2_1.done; clientList_2_1 = clientList_2.next()) { var client = clientList_2_1.value; client.postMessage(internalPayload); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (clientList_2_1 && !clientList_2_1.done && (_a = clientList_2.return)) _a.call(clientList_2); } finally { if (e_2) throw e_2.error; } } } function getClientList() { return self.clients.matchAll({ type: 'window', includeUncontrolled: true // TS doesn't know that "type: 'window'" means it'll return WindowClient[] }); } function showNotification(notificationPayloadInternal) { var _a; // Note: Firefox does not support the maxActions property. // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions var actions = notificationPayloadInternal.actions; var maxActions = Notification.maxActions; if (actions && maxActions && actions.length > maxActions) { console.warn("This browser only supports " + maxActions + " actions. The remaining actions will not be displayed."); } return self.registration.showNotification( /* title= */ (_a = notificationPayloadInternal.title) !== null && _a !== void 0 ? _a : '', notificationPayloadInternal); } function getLink(payload) { var _a, _b, _c; // eslint-disable-next-line camelcase var link = (_b = (_a = payload.fcmOptions) === null || _a === void 0 ? void 0 : _a.link) !== null && _b !== void 0 ? _b : (_c = payload.notification) === null || _c === void 0 ? void 0 : _c.click_action; if (link) { return link; } if (isConsoleMessage(payload.data)) { // Notification created in the Firebase Console. Redirect to origin. return self.location.origin; } else { return null; } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var WindowController = /** @class */ (function () { function WindowController(firebaseDependencies) { var _this = this; this.firebaseDependencies = firebaseDependencies; this.vapidKey = null; this.onMessageCallback = null; navigator.serviceWorker.addEventListener('message', function (e) { return _this.messageEventListener(e); }); } Object.defineProperty(WindowController.prototype, "app", { get: function () { return this.firebaseDependencies.app; }, enumerable: false, configurable: true }); WindowController.prototype.messageEventListener = function (event) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var internalPayload, dataPayload; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: internalPayload = event.data; if (!internalPayload.isFirebaseMessaging) { return [2 /*return*/]; } // onMessageCallback is either a function or observer/subscriber. // TODO: in the modularization release, have onMessage handle type MessagePayload as supposed to // the legacy payload where some fields are in snake cases. if (this.onMessageCallback && internalPayload.messageType === MessageType.PUSH_RECEIVED) { if (typeof this.onMessageCallback === 'function') { this.onMessageCallback(stripInternalFields(Object.assign({}, internalPayload))); } else { this.onMessageCallback.next(Object.assign({}, internalPayload)); } } dataPayload = internalPayload.data; if (!(isConsoleMessage(dataPayload) && dataPayload[CONSOLE_CAMPAIGN_ANALYTICS_ENABLED] === '1')) return [3 /*break*/, 2]; return [4 /*yield*/, this.logEvent(internalPayload.messageType, dataPayload)]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; WindowController.prototype.getVapidKey = function () { return this.vapidKey; }; WindowController.prototype.getSwReg = function () { return this.swRegistration; }; WindowController.prototype.getToken = function (options) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!(Notification.permission === 'default')) return [3 /*break*/, 2]; return [4 /*yield*/, Notification.requestPermission()]; case 1: _a.sent(); _a.label = 2; case 2: if (Notification.permission !== 'granted') { throw ERROR_FACTORY.create("permission-blocked" /* PERMISSION_BLOCKED */); } return [4 /*yield*/, this.updateVapidKey(options === null || options === void 0 ? void 0 : options.vapidKey)]; case 3: _a.sent(); return [4 /*yield*/, this.updateSwReg(options === null || options === void 0 ? void 0 : options.serviceWorkerRegistration)]; case 4: _a.sent(); return [2 /*return*/, getToken(this.firebaseDependencies, this.swRegistration, this.vapidKey)]; } }); }); }; WindowController.prototype.updateVapidKey = function (vapidKey) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { if (!!vapidKey) { this.vapidKey = vapidKey; } else if (!this.vapidKey) { this.vapidKey = DEFAULT_VAPID_KEY; } return [2 /*return*/]; }); }); }; WindowController.prototype.updateSwReg = function (swRegistration) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!(!swRegistration && !this.swRegistration)) return [3 /*break*/, 2]; return [4 /*yield*/, this.registerDefaultSw()]; case 1: _a.sent(); _a.label = 2; case 2: if (!swRegistration && !!this.swRegistration) { return [2 /*return*/]; } if (!(swRegistration instanceof ServiceWorkerRegistration)) { throw ERROR_FACTORY.create("invalid-sw-registration" /* INVALID_SW_REGISTRATION */); } this.swRegistration = swRegistration; return [2 /*return*/]; } }); }); }; WindowController.prototype.registerDefaultSw = function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var _a, e_1; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); _a = this; return [4 /*yield*/, navigator.serviceWorker.register(DEFAULT_SW_PATH, { scope: DEFAULT_SW_SCOPE })]; case 1: _a.swRegistration = _b.sent(); // The timing when browser updates sw when sw has an update is unreliable by my experiment. It // leads to version conflict when the SDK upgrades to a newer version in the main page, but sw // is stuck with the old version. For example, // https://github.com/firebase/firebase-js-sdk/issues/2590 The following line reliably updates // sw if there was an update. this.swRegistration.update().catch(function () { /* it is non blocking and we don't care if it failed */ }); return [3 /*break*/, 3]; case 2: e_1 = _b.sent(); throw ERROR_FACTORY.create("failed-service-worker-registration" /* FAILED_DEFAULT_REGISTRATION */, { browserErrorMessage: e_1.message }); case 3: return [2 /*return*/]; } }); }); }; WindowController.prototype.deleteToken = function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!!this.swRegistration) return [3 /*break*/, 2]; return [4 /*yield*/, this.registerDefaultSw()]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/, deleteToken(this.firebaseDependencies, this.swRegistration)]; } }); }); }; /** * Request permission if it is not currently granted. * * @return Resolves if the permission was granted, rejects otherwise. * * @deprecated Use Notification.requestPermission() instead. * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission */ WindowController.prototype.requestPermission = function () { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var permissionResult; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (Notification.permission === 'granted') { return [2 /*return*/]; } return [4 /*yield*/, Notification.requestPermission()]; case 1: permissionResult = _a.sent(); if (permissionResult === 'granted') { return [2 /*return*/]; } else if (permissionResult === 'denied') { throw ERROR_FACTORY.create("permission-blocked" /* PERMISSION_BLOCKED */); } else { throw ERROR_FACTORY.create("permission-default" /* PERMISSION_DEFAULT */); } } }); }); }; /** * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?: * ServiceWorkerRegistration;}): Promise instead. */ WindowController.prototype.usePublicVapidKey = function (vapidKey) { if (this.vapidKey !== null) { throw ERROR_FACTORY.create("use-vapid-key-after-get-token" /* USE_VAPID_KEY_AFTER_GET_TOKEN */); } if (typeof vapidKey !== 'string' || vapidKey.length === 0) { throw ERROR_FACTORY.create("invalid-vapid-key" /* INVALID_VAPID_KEY */); } this.vapidKey = vapidKey; }; /** * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?: * ServiceWorkerRegistration;}): Promise instead. */ WindowController.prototype.useServiceWorker = function (swRegistration) { if (!(swRegistration instanceof ServiceWorkerRegistration)) { throw ERROR_FACTORY.create("invalid-sw-registration" /* INVALID_SW_REGISTRATION */); } if (this.swRegistration) { throw ERROR_FACTORY.create("use-sw-after-get-token" /* USE_SW_AFTER_GET_TOKEN */); } this.swRegistration = swRegistration; }; /** * @param nextOrObserver An observer object or a function triggered on message. * * @return The unsubscribe function for the observer. */ WindowController.prototype.onMessage = function (nextOrObserver) { var _this = this; this.onMessageCallback = nextOrObserver; return function () { _this.onMessageCallback = null; }; }; WindowController.prototype.setBackgroundMessageHandler = function () { throw ERROR_FACTORY.create("only-available-in-sw" /* AVAILABLE_IN_SW */); }; WindowController.prototype.onBackgroundMessage = function () { throw ERROR_FACTORY.create("only-available-in-sw" /* AVAILABLE_IN_SW */); }; /** * @deprecated No-op. It was initially designed with token rotation requests from server in mind. * However, the plan to implement such feature was abandoned. */ WindowController.prototype.onTokenRefresh = function () { return function () { }; }; WindowController.prototype.logEvent = function (messageType, data) { return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var eventType, analytics; return Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: eventType = getEventType(messageType); return [4 /*yield*/, this.firebaseDependencies.analyticsProvider.get()]; case 1: analytics = _a.sent(); analytics.logEvent(eventType, { /* eslint-disable camelcase */ message_id: data[CONSOLE_CAMPAIGN_ID], message_name: data[CONSOLE_CAMPAIGN_NAME], message_time: data[CONSOLE_CAMPAIGN_TIME], message_device_time: Math.floor(Date.now() / 1000) /* eslint-enable camelcase */ }); return [2 /*return*/]; } }); }); }; return WindowController; }()); function getEventType(messageType) { switch (messageType) { case MessageType.NOTIFICATION_CLICKED: return 'notification_open'; case MessageType.PUSH_RECEIVED: return 'notification_foreground'; default: throw new Error(); } } function stripInternalFields(internalPayload) { delete internalPayload.messageType; delete internalPayload.isFirebaseMessaging; return internalPayload; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function extractAppConfig(app) { var e_1, _a; if (!app || !app.options) { throw getMissingValueError('App Configuration Object'); } if (!app.name) { throw getMissingValueError('App Name'); } // Required app config keys var configKeys = [ 'projectId', 'apiKey', 'appId', 'messagingSenderId' ]; var options = app.options; try { for (var configKeys_1 = Object(__WEBPACK_IMPORTED_MODULE_3_tslib__["f" /* __values */])(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) { var keyName = configKeys_1_1.value; if (!options[keyName]) { throw getMissingValueError(keyName); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1); } finally { if (e_1) throw e_1.error; } } return { appName: app.name, projectId: options.projectId, apiKey: options.apiKey, appId: options.appId, senderId: options.messagingSenderId }; } function getMissingValueError(valueName) { return ERROR_FACTORY.create("missing-app-config-values" /* MISSING_APP_CONFIG_VALUES */, { valueName: valueName }); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var MESSAGING_NAME = 'messaging'; function factoryMethod(container) { // Dependencies. var app = container.getProvider('app').getImmediate(); var appConfig = extractAppConfig(app); var installations = container.getProvider('installations').getImmediate(); var analyticsProvider = container.getProvider('analytics-internal'); var firebaseDependencies = { app: app, appConfig: appConfig, installations: installations, analyticsProvider: analyticsProvider }; if (!isSupported()) { throw ERROR_FACTORY.create("unsupported-browser" /* UNSUPPORTED_BROWSER */); } if (self && 'ServiceWorkerGlobalScope' in self) { // Running in ServiceWorker context return new SwController(firebaseDependencies); } else { // Assume we are in the window context. return new WindowController(firebaseDependencies); } } var NAMESPACE_EXPORTS = { isSupported: isSupported }; __WEBPACK_IMPORTED_MODULE_5__firebase_app__["a" /* default */].INTERNAL.registerComponent(new __WEBPACK_IMPORTED_MODULE_1__firebase_component__["a" /* Component */](MESSAGING_NAME, factoryMethod, "PUBLIC" /* PUBLIC */).setServiceProps(NAMESPACE_EXPORTS)); function isSupported() { if (self && 'ServiceWorkerGlobalScope' in self) { // Running in ServiceWorker context return isSWControllerSupported(); } else { // Assume we are in the window context. return isWindowControllerSupported(); } } /** * Checks to see if the required APIs exist. */ function isWindowControllerSupported() { return ('indexedDB' in window && indexedDB !== null && navigator.cookieEnabled && 'serviceWorker' in navigator && 'PushManager' in window && 'Notification' in window && 'fetch' in window && ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') && PushSubscription.prototype.hasOwnProperty('getKey')); } /** * Checks to see if the required APIs exist within SW Context. */ function isSWControllerSupported() { return ('indexedDB' in self && indexedDB !== null && 'PushManager' in self && 'Notification' in self && ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') && PushSubscription.prototype.hasOwnProperty('getKey')); } //# sourceMappingURL=index.esm.js.map /***/ }), /***/ 6149: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export __extends */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __assign; }); /* unused harmony export __rest */ /* unused harmony export __decorate */ /* unused harmony export __param */ /* unused harmony export __metadata */ /* harmony export (immutable) */ __webpack_exports__["b"] = __awaiter; /* harmony export (immutable) */ __webpack_exports__["c"] = __generator; /* unused harmony export __createBinding */ /* unused harmony export __exportStar */ /* harmony export (immutable) */ __webpack_exports__["f"] = __values; /* harmony export (immutable) */ __webpack_exports__["d"] = __read; /* unused harmony export __spread */ /* unused harmony export __spreadArrays */ /* harmony export (immutable) */ __webpack_exports__["e"] = __spreadArray; /* unused harmony export __await */ /* unused harmony export __asyncGenerator */ /* unused harmony export __asyncDelegator */ /* unused harmony export __asyncValues */ /* unused harmony export __makeTemplateObject */ /* unused harmony export __importStar */ /* unused harmony export __importDefault */ /* unused harmony export __classPrivateFieldGet */ /* unused harmony export __classPrivateFieldSet */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; } return __assign.apply(this, arguments); } function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /***/ }), /***/ 6150: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export __extends */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __assign; }); /* unused harmony export __rest */ /* unused harmony export __decorate */ /* unused harmony export __param */ /* unused harmony export __metadata */ /* harmony export (immutable) */ __webpack_exports__["b"] = __awaiter; /* harmony export (immutable) */ __webpack_exports__["c"] = __generator; /* unused harmony export __createBinding */ /* unused harmony export __exportStar */ /* harmony export (immutable) */ __webpack_exports__["f"] = __values; /* harmony export (immutable) */ __webpack_exports__["d"] = __read; /* unused harmony export __spread */ /* unused harmony export __spreadArrays */ /* harmony export (immutable) */ __webpack_exports__["e"] = __spreadArray; /* unused harmony export __await */ /* unused harmony export __asyncGenerator */ /* unused harmony export __asyncDelegator */ /* unused harmony export __asyncValues */ /* unused harmony export __makeTemplateObject */ /* unused harmony export __importStar */ /* unused harmony export __importDefault */ /* unused harmony export __classPrivateFieldGet */ /* unused harmony export __classPrivateFieldSet */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; } return __assign.apply(this, arguments); } function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /***/ }), /***/ 6151: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export registerStorage */ /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__firebase_app__ = __webpack_require__(50); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_tslib__ = __webpack_require__(6152); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__firebase_util__ = __webpack_require__(56); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__firebase_component__ = __webpack_require__(74); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview Constants used in the Firebase Storage library. */ /** * Domain name for firebase storage. */ var DEFAULT_HOST = 'firebasestorage.googleapis.com'; /** * The key in Firebase config json for the storage bucket. */ var CONFIG_STORAGE_BUCKET_KEY = 'storageBucket'; /** * 2 minutes * * The timeout for all operations except upload. */ var DEFAULT_MAX_OPERATION_RETRY_TIME = 2 * 60 * 1000; /** * 10 minutes * * The timeout for upload. */ var DEFAULT_MAX_UPLOAD_RETRY_TIME = 10 * 60 * 1000; /** * An error returned by the Firebase Storage SDK. * @public */ var FirebaseStorageError = /** @class */ (function (_super) { Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["c" /* __extends */])(FirebaseStorageError, _super); /** * @param code - A StorageErrorCode string to be prefixed with 'storage/' and * added to the end of the message. * @param message - Error message. */ function FirebaseStorageError(code, message) { var _this = _super.call(this, prependCode(code), "Firebase Storage: " + message + " (" + prependCode(code) + ")") || this; /** * Stores custom error data unque to FirebaseStorageError. */ _this.customData = { serverResponse: null }; // Without this, `instanceof FirebaseStorageError`, in tests for example, // returns false. Object.setPrototypeOf(_this, FirebaseStorageError.prototype); return _this; } /** * Compares a StorageErrorCode against this error's code, filtering out the prefix. */ FirebaseStorageError.prototype._codeEquals = function (code) { return prependCode(code) === this.code; }; Object.defineProperty(FirebaseStorageError.prototype, "message", { /** * Error message including serverResponse if available. */ get: function () { if (this.customData.serverResponse) { return this.message + "\n" + this.customData.serverResponse; } else { return this.message; } }, enumerable: false, configurable: true }); Object.defineProperty(FirebaseStorageError.prototype, "serverResponse", { /** * Optional response message that was added by the server. */ get: function () { return this.customData.serverResponse; }, set: function (serverResponse) { this.customData.serverResponse = serverResponse; }, enumerable: false, configurable: true }); return FirebaseStorageError; }(__WEBPACK_IMPORTED_MODULE_2__firebase_util__["c" /* FirebaseError */])); function prependCode(code) { return 'storage/' + code; } function unknown() { var message = 'An unknown error occurred, please check the error payload for ' + 'server response.'; return new FirebaseStorageError("unknown" /* UNKNOWN */, message); } function objectNotFound(path) { return new FirebaseStorageError("object-not-found" /* OBJECT_NOT_FOUND */, "Object '" + path + "' does not exist."); } function quotaExceeded(bucket) { return new FirebaseStorageError("quota-exceeded" /* QUOTA_EXCEEDED */, "Quota for bucket '" + bucket + "' exceeded, please view quota on " + 'https://firebase.google.com/pricing/.'); } function unauthenticated() { var message = 'User is not authenticated, please authenticate using Firebase ' + 'Authentication and try again.'; return new FirebaseStorageError("unauthenticated" /* UNAUTHENTICATED */, message); } function unauthorized(path) { return new FirebaseStorageError("unauthorized" /* UNAUTHORIZED */, "User does not have permission to access '" + path + "'."); } function retryLimitExceeded() { return new FirebaseStorageError("retry-limit-exceeded" /* RETRY_LIMIT_EXCEEDED */, 'Max retry time for operation exceeded, please try again.'); } function canceled() { return new FirebaseStorageError("canceled" /* CANCELED */, 'User canceled the upload/download.'); } function invalidUrl(url) { return new FirebaseStorageError("invalid-url" /* INVALID_URL */, "Invalid URL '" + url + "'."); } function invalidDefaultBucket(bucket) { return new FirebaseStorageError("invalid-default-bucket" /* INVALID_DEFAULT_BUCKET */, "Invalid default bucket '" + bucket + "'."); } function noDefaultBucket() { return new FirebaseStorageError("no-default-bucket" /* NO_DEFAULT_BUCKET */, 'No default bucket ' + "found. Did you set the '" + CONFIG_STORAGE_BUCKET_KEY + "' property when initializing the app?"); } function cannotSliceBlob() { return new FirebaseStorageError("cannot-slice-blob" /* CANNOT_SLICE_BLOB */, 'Cannot slice blob for upload. Please retry the upload.'); } function serverFileWrongSize() { return new FirebaseStorageError("server-file-wrong-size" /* SERVER_FILE_WRONG_SIZE */, 'Server recorded incorrect upload file size, please retry the upload.'); } function noDownloadURL() { return new FirebaseStorageError("no-download-url" /* NO_DOWNLOAD_URL */, 'The given file does not have any download URLs.'); } function invalidArgument(message) { return new FirebaseStorageError("invalid-argument" /* INVALID_ARGUMENT */, message); } function appDeleted() { return new FirebaseStorageError("app-deleted" /* APP_DELETED */, 'The Firebase app was deleted.'); } /** * @param name - The name of the operation that was invalid. */ function invalidRootOperation(name) { return new FirebaseStorageError("invalid-root-operation" /* INVALID_ROOT_OPERATION */, "The operation '" + name + "' cannot be performed on a root reference, create a non-root " + "reference using child, such as .child('file.png')."); } /** * @param format - The format that was not valid. * @param message - A message describing the format violation. */ function invalidFormat(format, message) { return new FirebaseStorageError("invalid-format" /* INVALID_FORMAT */, "String does not match format '" + format + "': " + message); } /** * @param message - A message describing the internal error. */ function internalError(message) { throw new FirebaseStorageError("internal-error" /* INTERNAL_ERROR */, 'Internal error: ' + message); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * An enumeration of the possible string formats for upload. * @public */ var StringFormat = { /** * Indicates the string should be interpreted "raw", that is, as normal text. * The string will be interpreted as UTF-16, then uploaded as a UTF-8 byte * sequence. * Example: The string 'Hello! \\ud83d\\ude0a' becomes the byte sequence * 48 65 6c 6c 6f 21 20 f0 9f 98 8a */ RAW: 'raw', /** * Indicates the string should be interpreted as base64-encoded data. * Padding characters (trailing '='s) are optional. * Example: The string 'rWmO++E6t7/rlw==' becomes the byte sequence * ad 69 8e fb e1 3a b7 bf eb 97 */ BASE64: 'base64', /** * Indicates the string should be interpreted as base64url-encoded data. * Padding characters (trailing '='s) are optional. * Example: The string 'rWmO--E6t7_rlw==' becomes the byte sequence * ad 69 8e fb e1 3a b7 bf eb 97 */ BASE64URL: 'base64url', /** * Indicates the string is a data URL, such as one obtained from * canvas.toDataURL(). * Example: the string 'data:application/octet-stream;base64,aaaa' * becomes the byte sequence * 69 a6 9a * (the content-type "application/octet-stream" is also applied, but can * be overridden in the metadata object). */ DATA_URL: 'data_url' }; var StringData = /** @class */ (function () { function StringData(data, contentType) { this.data = data; this.contentType = contentType || null; } return StringData; }()); function dataFromString(format, stringData) { switch (format) { case StringFormat.RAW: return new StringData(utf8Bytes_(stringData)); case StringFormat.BASE64: case StringFormat.BASE64URL: return new StringData(base64Bytes_(format, stringData)); case StringFormat.DATA_URL: return new StringData(dataURLBytes_(stringData), dataURLContentType_(stringData)); // do nothing } // assert(false); throw unknown(); } function utf8Bytes_(value) { var b = []; for (var i = 0; i < value.length; i++) { var c = value.charCodeAt(i); if (c <= 127) { b.push(c); } else { if (c <= 2047) { b.push(192 | (c >> 6), 128 | (c & 63)); } else { if ((c & 64512) === 55296) { // The start of a surrogate pair. var valid = i < value.length - 1 && (value.charCodeAt(i + 1) & 64512) === 56320; if (!valid) { // The second surrogate wasn't there. b.push(239, 191, 189); } else { var hi = c; var lo = value.charCodeAt(++i); c = 65536 | ((hi & 1023) << 10) | (lo & 1023); b.push(240 | (c >> 18), 128 | ((c >> 12) & 63), 128 | ((c >> 6) & 63), 128 | (c & 63)); } } else { if ((c & 64512) === 56320) { // Invalid low surrogate. b.push(239, 191, 189); } else { b.push(224 | (c >> 12), 128 | ((c >> 6) & 63), 128 | (c & 63)); } } } } } return new Uint8Array(b); } function percentEncodedBytes_(value) { var decoded; try { decoded = decodeURIComponent(value); } catch (e) { throw invalidFormat(StringFormat.DATA_URL, 'Malformed data URL.'); } return utf8Bytes_(decoded); } function base64Bytes_(format, value) { switch (format) { case StringFormat.BASE64: { var hasMinus = value.indexOf('-') !== -1; var hasUnder = value.indexOf('_') !== -1; if (hasMinus || hasUnder) { var invalidChar = hasMinus ? '-' : '_'; throw invalidFormat(format, "Invalid character '" + invalidChar + "' found: is it base64url encoded?"); } break; } case StringFormat.BASE64URL: { var hasPlus = value.indexOf('+') !== -1; var hasSlash = value.indexOf('/') !== -1; if (hasPlus || hasSlash) { var invalidChar = hasPlus ? '+' : '/'; throw invalidFormat(format, "Invalid character '" + invalidChar + "' found: is it base64 encoded?"); } value = value.replace(/-/g, '+').replace(/_/g, '/'); break; } // do nothing } var bytes; try { bytes = atob(value); } catch (e) { throw invalidFormat(format, 'Invalid character found'); } var array = new Uint8Array(bytes.length); for (var i = 0; i < bytes.length; i++) { array[i] = bytes.charCodeAt(i); } return array; } var DataURLParts = /** @class */ (function () { function DataURLParts(dataURL) { this.base64 = false; this.contentType = null; var matches = dataURL.match(/^data:([^,]+)?,/); if (matches === null) { throw invalidFormat(StringFormat.DATA_URL, "Must be formatted 'data:[][;base64],"); } var middle = matches[1] || null; if (middle != null) { this.base64 = endsWith(middle, ';base64'); this.contentType = this.base64 ? middle.substring(0, middle.length - ';base64'.length) : middle; } this.rest = dataURL.substring(dataURL.indexOf(',') + 1); } return DataURLParts; }()); function dataURLBytes_(dataUrl) { var parts = new DataURLParts(dataUrl); if (parts.base64) { return base64Bytes_(StringFormat.BASE64, parts.rest); } else { return percentEncodedBytes_(parts.rest); } } function dataURLContentType_(dataUrl) { var parts = new DataURLParts(dataUrl); return parts.contentType; } function endsWith(s, end) { var longEnough = s.length >= end.length; if (!longEnough) { return false; } return s.substring(s.length - end.length) === end; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * An event that is triggered on a task. */ var TaskEvent = { /** * For this event, *
    *
  • The `next` function is triggered on progress updates and when the * task is paused/resumed with an `UploadTaskSnapshot` as the first * argument.
  • *
  • The `error` function is triggered if the upload is canceled or fails * for another reason.
  • *
  • The `complete` function is triggered if the upload completes * successfully.
  • *
*/ STATE_CHANGED: 'state_changed' }; /** * Represents the current state of a running upload. */ var TaskState = { /** The task is currently transferring data. */ RUNNING: 'running', /** The task was paused by the user. */ PAUSED: 'paused', /** The task completed successfully. */ SUCCESS: 'success', /** The task was canceled. */ CANCELED: 'canceled', /** The task failed with an error. */ ERROR: 'error' }; function taskStateFromInternalTaskState(state) { switch (state) { case "running" /* RUNNING */: case "pausing" /* PAUSING */: case "canceling" /* CANCELING */: return TaskState.RUNNING; case "paused" /* PAUSED */: return TaskState.PAUSED; case "success" /* SUCCESS */: return TaskState.SUCCESS; case "canceled" /* CANCELED */: return TaskState.CANCELED; case "error" /* ERROR */: return TaskState.ERROR; default: // TODO(andysoto): assert(false); return TaskState.ERROR; } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Error codes for requests made by the the XhrIo wrapper. */ var ErrorCode; (function (ErrorCode) { ErrorCode[ErrorCode["NO_ERROR"] = 0] = "NO_ERROR"; ErrorCode[ErrorCode["NETWORK_ERROR"] = 1] = "NETWORK_ERROR"; ErrorCode[ErrorCode["ABORT"] = 2] = "ABORT"; })(ErrorCode || (ErrorCode = {})); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * We use this instead of goog.net.XhrIo because goog.net.XhrIo is hyuuuuge and * doesn't work in React Native on Android. */ var NetworkXhrIo = /** @class */ (function () { function NetworkXhrIo() { var _this = this; this.sent_ = false; this.xhr_ = new XMLHttpRequest(); this.errorCode_ = ErrorCode.NO_ERROR; this.sendPromise_ = new Promise(function (resolve) { _this.xhr_.addEventListener('abort', function () { _this.errorCode_ = ErrorCode.ABORT; resolve(_this); }); _this.xhr_.addEventListener('error', function () { _this.errorCode_ = ErrorCode.NETWORK_ERROR; resolve(_this); }); _this.xhr_.addEventListener('load', function () { resolve(_this); }); }); } /** * @override */ NetworkXhrIo.prototype.send = function (url, method, body, headers) { if (this.sent_) { throw internalError('cannot .send() more than once'); } this.sent_ = true; this.xhr_.open(method, url, true); if (headers !== undefined) { for (var key in headers) { if (headers.hasOwnProperty(key)) { this.xhr_.setRequestHeader(key, headers[key].toString()); } } } if (body !== undefined) { this.xhr_.send(body); } else { this.xhr_.send(); } return this.sendPromise_; }; /** * @override */ NetworkXhrIo.prototype.getErrorCode = function () { if (!this.sent_) { throw internalError('cannot .getErrorCode() before sending'); } return this.errorCode_; }; /** * @override */ NetworkXhrIo.prototype.getStatus = function () { if (!this.sent_) { throw internalError('cannot .getStatus() before sending'); } try { return this.xhr_.status; } catch (e) { return -1; } }; /** * @override */ NetworkXhrIo.prototype.getResponseText = function () { if (!this.sent_) { throw internalError('cannot .getResponseText() before sending'); } return this.xhr_.responseText; }; /** * Aborts the request. * @override */ NetworkXhrIo.prototype.abort = function () { this.xhr_.abort(); }; /** * @override */ NetworkXhrIo.prototype.getResponseHeader = function (header) { return this.xhr_.getResponseHeader(header); }; /** * @override */ NetworkXhrIo.prototype.addUploadProgressListener = function (listener) { if (this.xhr_.upload != null) { this.xhr_.upload.addEventListener('progress', listener); } }; /** * @override */ NetworkXhrIo.prototype.removeUploadProgressListener = function (listener) { if (this.xhr_.upload != null) { this.xhr_.upload.removeEventListener('progress', listener); } }; return NetworkXhrIo; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Factory-like class for creating XhrIo instances. */ var XhrIoPool = /** @class */ (function () { function XhrIoPool() { } XhrIoPool.prototype.createXhrIo = function () { return new NetworkXhrIo(); }; return XhrIoPool; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Firebase Storage location data. * * @internal */ var Location = /** @class */ (function () { function Location(bucket, path) { this.bucket = bucket; this.path_ = path; } Object.defineProperty(Location.prototype, "path", { get: function () { return this.path_; }, enumerable: false, configurable: true }); Object.defineProperty(Location.prototype, "isRoot", { get: function () { return this.path.length === 0; }, enumerable: false, configurable: true }); Location.prototype.fullServerUrl = function () { var encode = encodeURIComponent; return '/b/' + encode(this.bucket) + '/o/' + encode(this.path); }; Location.prototype.bucketOnlyServerUrl = function () { var encode = encodeURIComponent; return '/b/' + encode(this.bucket) + '/o'; }; Location.makeFromBucketSpec = function (bucketString) { var bucketLocation; try { bucketLocation = Location.makeFromUrl(bucketString); } catch (e) { // Not valid URL, use as-is. This lets you put bare bucket names in // config. return new Location(bucketString, ''); } if (bucketLocation.path === '') { return bucketLocation; } else { throw invalidDefaultBucket(bucketString); } }; Location.makeFromUrl = function (url) { var location = null; var bucketDomain = '([A-Za-z0-9.\\-_]+)'; function gsModify(loc) { if (loc.path.charAt(loc.path.length - 1) === '/') { loc.path_ = loc.path_.slice(0, -1); } } var gsPath = '(/(.*))?$'; var gsRegex = new RegExp('^gs://' + bucketDomain + gsPath, 'i'); var gsIndices = { bucket: 1, path: 3 }; function httpModify(loc) { loc.path_ = decodeURIComponent(loc.path); } var version = 'v[A-Za-z0-9_]+'; var firebaseStorageHost = DEFAULT_HOST.replace(/[.]/g, '\\.'); var firebaseStoragePath = '(/([^?#]*).*)?$'; var firebaseStorageRegExp = new RegExp("^https?://" + firebaseStorageHost + "/" + version + "/b/" + bucketDomain + "/o" + firebaseStoragePath, 'i'); var firebaseStorageIndices = { bucket: 1, path: 3 }; var cloudStorageHost = '(?:storage.googleapis.com|storage.cloud.google.com)'; var cloudStoragePath = '([^?#]*)'; var cloudStorageRegExp = new RegExp("^https?://" + cloudStorageHost + "/" + bucketDomain + "/" + cloudStoragePath, 'i'); var cloudStorageIndices = { bucket: 1, path: 2 }; var groups = [ { regex: gsRegex, indices: gsIndices, postModify: gsModify }, { regex: firebaseStorageRegExp, indices: firebaseStorageIndices, postModify: httpModify }, { regex: cloudStorageRegExp, indices: cloudStorageIndices, postModify: httpModify } ]; for (var i = 0; i < groups.length; i++) { var group = groups[i]; var captures = group.regex.exec(url); if (captures) { var bucketValue = captures[group.indices.bucket]; var pathValue = captures[group.indices.path]; if (!pathValue) { pathValue = ''; } location = new Location(bucketValue, pathValue); group.postModify(location); break; } } if (location == null) { throw invalidUrl(url); } return location; }; return Location; }()); /** * A request whose promise always fails. */ var FailRequest = /** @class */ (function () { function FailRequest(error) { this.promise_ = Promise.reject(error); } /** @inheritDoc */ FailRequest.prototype.getPromise = function () { return this.promise_; }; /** @inheritDoc */ FailRequest.prototype.cancel = function (_appDelete) { }; return FailRequest; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @param f May be invoked * before the function returns. * @param callback Get all the arguments passed to the function * passed to f, including the initial boolean. */ function start(f, // eslint-disable-next-line @typescript-eslint/no-explicit-any callback, timeout) { // TODO(andysoto): make this code cleaner (probably refactor into an actual // type instead of a bunch of functions with state shared in the closure) var waitSeconds = 1; // Would type this as "number" but that doesn't work for Node so ¯\_(ツ)_/¯ // TODO: find a way to exclude Node type definition for storage because storage only works in browser // eslint-disable-next-line @typescript-eslint/no-explicit-any var timeoutId = null; var hitTimeout = false; var cancelState = 0; function canceled() { return cancelState === 2; } var triggeredCallback = false; function triggerCallback() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!triggeredCallback) { triggeredCallback = true; callback.apply(null, args); } } function callWithDelay(millis) { timeoutId = setTimeout(function () { timeoutId = null; f(handler, canceled()); }, millis); } function handler(success) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (triggeredCallback) { return; } if (success) { triggerCallback.call.apply(triggerCallback, Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["e" /* __spreadArray */])([null, success], args)); return; } var mustStop = canceled() || hitTimeout; if (mustStop) { triggerCallback.call.apply(triggerCallback, Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["e" /* __spreadArray */])([null, success], args)); return; } if (waitSeconds < 64) { /* TODO(andysoto): don't back off so quickly if we know we're offline. */ waitSeconds *= 2; } var waitMillis; if (cancelState === 1) { cancelState = 2; waitMillis = 0; } else { waitMillis = (waitSeconds + Math.random()) * 1000; } callWithDelay(waitMillis); } var stopped = false; function stop(wasTimeout) { if (stopped) { return; } stopped = true; if (triggeredCallback) { return; } if (timeoutId !== null) { if (!wasTimeout) { cancelState = 2; } clearTimeout(timeoutId); callWithDelay(0); } else { if (!wasTimeout) { cancelState = 1; } } } callWithDelay(0); setTimeout(function () { hitTimeout = true; stop(true); }, timeout); return stop; } /** * Stops the retry loop from repeating. * If the function is currently "in between" retries, it is invoked immediately * with the second parameter as "true". Otherwise, it will be invoked once more * after the current invocation finishes iff the current invocation would have * triggered another retry. */ function stop(id) { id(false); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function isJustDef(p) { return p !== void 0; } // eslint-disable-next-line @typescript-eslint/ban-types function isFunction(p) { return typeof p === 'function'; } function isNonArrayObject(p) { return typeof p === 'object' && !Array.isArray(p); } function isString(p) { return typeof p === 'string' || p instanceof String; } function isNativeBlob(p) { return isNativeBlobDefined() && p instanceof Blob; } function isNativeBlobDefined() { return typeof Blob !== 'undefined'; } function validateNumber(argument, minValue, maxValue, value) { if (value < minValue) { throw invalidArgument("Invalid value for '" + argument + "'. Expected " + minValue + " or greater."); } if (value > maxValue) { throw invalidArgument("Invalid value for '" + argument + "'. Expected " + maxValue + " or less."); } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function makeUrl(urlPart) { return "https://" + DEFAULT_HOST + "/v0" + urlPart; } function makeQueryString(params) { var encode = encodeURIComponent; var queryPart = '?'; for (var key in params) { if (params.hasOwnProperty(key)) { var nextPart = encode(key) + '=' + encode(params[key]); queryPart = queryPart + nextPart + '&'; } } // Chop off the extra '&' or '?' on the end queryPart = queryPart.slice(0, -1); return queryPart; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var NetworkRequest = /** @class */ (function () { function NetworkRequest(url, method, headers, body, successCodes, additionalRetryCodes, callback, errorCallback, timeout, progressCallback, pool) { var _this = this; this.pendingXhr_ = null; this.backoffId_ = null; this.canceled_ = false; this.appDelete_ = false; this.url_ = url; this.method_ = method; this.headers_ = headers; this.body_ = body; this.successCodes_ = successCodes.slice(); this.additionalRetryCodes_ = additionalRetryCodes.slice(); this.callback_ = callback; this.errorCallback_ = errorCallback; this.progressCallback_ = progressCallback; this.timeout_ = timeout; this.pool_ = pool; this.promise_ = new Promise(function (resolve, reject) { _this.resolve_ = resolve; _this.reject_ = reject; _this.start_(); }); } /** * Actually starts the retry loop. */ NetworkRequest.prototype.start_ = function () { var self = this; function doTheRequest(backoffCallback, canceled) { if (canceled) { backoffCallback(false, new RequestEndStatus(false, null, true)); return; } var xhr = self.pool_.createXhrIo(); self.pendingXhr_ = xhr; function progressListener(progressEvent) { var loaded = progressEvent.loaded; var total = progressEvent.lengthComputable ? progressEvent.total : -1; if (self.progressCallback_ !== null) { self.progressCallback_(loaded, total); } } if (self.progressCallback_ !== null) { xhr.addUploadProgressListener(progressListener); } // eslint-disable-next-line @typescript-eslint/no-floating-promises xhr .send(self.url_, self.method_, self.body_, self.headers_) .then(function (xhr) { if (self.progressCallback_ !== null) { xhr.removeUploadProgressListener(progressListener); } self.pendingXhr_ = null; xhr = xhr; var hitServer = xhr.getErrorCode() === ErrorCode.NO_ERROR; var status = xhr.getStatus(); if (!hitServer || self.isRetryStatusCode_(status)) { var wasCanceled = xhr.getErrorCode() === ErrorCode.ABORT; backoffCallback(false, new RequestEndStatus(false, null, wasCanceled)); return; } var successCode = self.successCodes_.indexOf(status) !== -1; backoffCallback(true, new RequestEndStatus(successCode, xhr)); }); } /** * @param requestWentThrough - True if the request eventually went * through, false if it hit the retry limit or was canceled. */ function backoffDone(requestWentThrough, status) { var resolve = self.resolve_; var reject = self.reject_; var xhr = status.xhr; if (status.wasSuccessCode) { try { var result = self.callback_(xhr, xhr.getResponseText()); if (isJustDef(result)) { resolve(result); } else { resolve(); } } catch (e) { reject(e); } } else { if (xhr !== null) { var err = unknown(); err.serverResponse = xhr.getResponseText(); if (self.errorCallback_) { reject(self.errorCallback_(xhr, err)); } else { reject(err); } } else { if (status.canceled) { var err = self.appDelete_ ? appDeleted() : canceled(); reject(err); } else { var err = retryLimitExceeded(); reject(err); } } } } if (this.canceled_) { backoffDone(false, new RequestEndStatus(false, null, true)); } else { this.backoffId_ = start(doTheRequest, backoffDone, this.timeout_); } }; /** @inheritDoc */ NetworkRequest.prototype.getPromise = function () { return this.promise_; }; /** @inheritDoc */ NetworkRequest.prototype.cancel = function (appDelete) { this.canceled_ = true; this.appDelete_ = appDelete || false; if (this.backoffId_ !== null) { stop(this.backoffId_); } if (this.pendingXhr_ !== null) { this.pendingXhr_.abort(); } }; NetworkRequest.prototype.isRetryStatusCode_ = function (status) { // The codes for which to retry came from this page: // https://cloud.google.com/storage/docs/exponential-backoff var isFiveHundredCode = status >= 500 && status < 600; var extraRetryCodes = [ // Request Timeout: web server didn't receive full request in time. 408, // Too Many Requests: you're getting rate-limited, basically. 429 ]; var isExtraRetryCode = extraRetryCodes.indexOf(status) !== -1; var isRequestSpecificRetryCode = this.additionalRetryCodes_.indexOf(status) !== -1; return isFiveHundredCode || isExtraRetryCode || isRequestSpecificRetryCode; }; return NetworkRequest; }()); /** * A collection of information about the result of a network request. * @param opt_canceled - Defaults to false. */ var RequestEndStatus = /** @class */ (function () { function RequestEndStatus(wasSuccessCode, xhr, canceled) { this.wasSuccessCode = wasSuccessCode; this.xhr = xhr; this.canceled = !!canceled; } return RequestEndStatus; }()); function addAuthHeader_(headers, authToken) { if (authToken !== null && authToken.length > 0) { headers['Authorization'] = 'Firebase ' + authToken; } } function addVersionHeader_(headers, firebaseVersion) { headers['X-Firebase-Storage-Version'] = 'webjs/' + (firebaseVersion !== null && firebaseVersion !== void 0 ? firebaseVersion : 'AppManager'); } function addGmpidHeader_(headers, appId) { if (appId) { headers['X-Firebase-GMPID'] = appId; } } function makeRequest(requestInfo, appId, authToken, pool, firebaseVersion) { var queryPart = makeQueryString(requestInfo.urlParams); var url = requestInfo.url + queryPart; var headers = Object.assign({}, requestInfo.headers); addGmpidHeader_(headers, appId); addAuthHeader_(headers, authToken); addVersionHeader_(headers, firebaseVersion); return new NetworkRequest(url, requestInfo.method, headers, requestInfo.body, requestInfo.successCodes, requestInfo.additionalRetryCodes, requestInfo.handler, requestInfo.errorHandler, requestInfo.timeout, requestInfo.progressCallback, pool); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function getBlobBuilder() { if (typeof BlobBuilder !== 'undefined') { return BlobBuilder; } else if (typeof WebKitBlobBuilder !== 'undefined') { return WebKitBlobBuilder; } else { return undefined; } } /** * Concatenates one or more values together and converts them to a Blob. * * @param args The values that will make up the resulting blob. * @return The blob. */ function getBlob() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var BlobBuilder = getBlobBuilder(); if (BlobBuilder !== undefined) { var bb = new BlobBuilder(); for (var i = 0; i < args.length; i++) { bb.append(args[i]); } return bb.getBlob(); } else { if (isNativeBlobDefined()) { return new Blob(args); } else { throw new FirebaseStorageError("unsupported-environment" /* UNSUPPORTED_ENVIRONMENT */, "This browser doesn't seem to support creating Blobs"); } } } /** * Slices the blob. The returned blob contains data from the start byte * (inclusive) till the end byte (exclusive). Negative indices cannot be used. * * @param blob The blob to be sliced. * @param start Index of the starting byte. * @param end Index of the ending byte. * @return The blob slice or null if not supported. */ function sliceBlob(blob, start, end) { if (blob.webkitSlice) { return blob.webkitSlice(start, end); } else if (blob.mozSlice) { return blob.mozSlice(start, end); } else if (blob.slice) { return blob.slice(start, end); } return null; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @param opt_elideCopy - If true, doesn't copy mutable input data * (e.g. Uint8Arrays). Pass true only if you know the objects will not be * modified after this blob's construction. * * @internal */ var FbsBlob = /** @class */ (function () { function FbsBlob(data, elideCopy) { var size = 0; var blobType = ''; if (isNativeBlob(data)) { this.data_ = data; size = data.size; blobType = data.type; } else if (data instanceof ArrayBuffer) { if (elideCopy) { this.data_ = new Uint8Array(data); } else { this.data_ = new Uint8Array(data.byteLength); this.data_.set(new Uint8Array(data)); } size = this.data_.length; } else if (data instanceof Uint8Array) { if (elideCopy) { this.data_ = data; } else { this.data_ = new Uint8Array(data.length); this.data_.set(data); } size = data.length; } this.size_ = size; this.type_ = blobType; } FbsBlob.prototype.size = function () { return this.size_; }; FbsBlob.prototype.type = function () { return this.type_; }; FbsBlob.prototype.slice = function (startByte, endByte) { if (isNativeBlob(this.data_)) { var realBlob = this.data_; var sliced = sliceBlob(realBlob, startByte, endByte); if (sliced === null) { return null; } return new FbsBlob(sliced); } else { var slice = new Uint8Array(this.data_.buffer, startByte, endByte - startByte); return new FbsBlob(slice, true); } }; FbsBlob.getBlob = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (isNativeBlobDefined()) { var blobby = args.map(function (val) { if (val instanceof FbsBlob) { return val.data_; } else { return val; } }); return new FbsBlob(getBlob.apply(null, blobby)); } else { var uint8Arrays = args.map(function (val) { if (isString(val)) { return dataFromString(StringFormat.RAW, val).data; } else { // Blobs don't exist, so this has to be a Uint8Array. return val.data_; } }); var finalLength_1 = 0; uint8Arrays.forEach(function (array) { finalLength_1 += array.byteLength; }); var merged_1 = new Uint8Array(finalLength_1); var index_1 = 0; uint8Arrays.forEach(function (array) { for (var i = 0; i < array.length; i++) { merged_1[index_1++] = array[i]; } }); return new FbsBlob(merged_1, true); } }; FbsBlob.prototype.uploadData = function () { return this.data_; }; return FbsBlob; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Returns the Object resulting from parsing the given JSON, or null if the * given string does not represent a JSON object. */ function jsonObjectOrNull(s) { var obj; try { obj = JSON.parse(s); } catch (e) { return null; } if (isNonArrayObject(obj)) { return obj; } else { return null; } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview Contains helper methods for manipulating paths. */ /** * @return Null if the path is already at the root. */ function parent(path) { if (path.length === 0) { return null; } var index = path.lastIndexOf('/'); if (index === -1) { return ''; } var newPath = path.slice(0, index); return newPath; } function child(path, childPath) { var canonicalChildPath = childPath .split('/') .filter(function (component) { return component.length > 0; }) .join('/'); if (path.length === 0) { return canonicalChildPath; } else { return path + '/' + canonicalChildPath; } } /** * Returns the last component of a path. * '/foo/bar' -> 'bar' * '/foo/bar/baz/' -> 'baz/' * '/a' -> 'a' */ function lastComponent(path) { var index = path.lastIndexOf('/', path.length - 2); if (index === -1) { return path; } else { return path.slice(index + 1); } } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function noXform_(metadata, value) { return value; } var Mapping = /** @class */ (function () { function Mapping(server, local, writable, xform) { this.server = server; this.local = local || server; this.writable = !!writable; this.xform = xform || noXform_; } return Mapping; }()); var mappings_ = null; function xformPath(fullPath) { if (!isString(fullPath) || fullPath.length < 2) { return fullPath; } else { return lastComponent(fullPath); } } function getMappings() { if (mappings_) { return mappings_; } var mappings = []; mappings.push(new Mapping('bucket')); mappings.push(new Mapping('generation')); mappings.push(new Mapping('metageneration')); mappings.push(new Mapping('name', 'fullPath', true)); function mappingsXformPath(_metadata, fullPath) { return xformPath(fullPath); } var nameMapping = new Mapping('name'); nameMapping.xform = mappingsXformPath; mappings.push(nameMapping); /** * Coerces the second param to a number, if it is defined. */ function xformSize(_metadata, size) { if (size !== undefined) { return Number(size); } else { return size; } } var sizeMapping = new Mapping('size'); sizeMapping.xform = xformSize; mappings.push(sizeMapping); mappings.push(new Mapping('timeCreated')); mappings.push(new Mapping('updated')); mappings.push(new Mapping('md5Hash', null, true)); mappings.push(new Mapping('cacheControl', null, true)); mappings.push(new Mapping('contentDisposition', null, true)); mappings.push(new Mapping('contentEncoding', null, true)); mappings.push(new Mapping('contentLanguage', null, true)); mappings.push(new Mapping('contentType', null, true)); mappings.push(new Mapping('metadata', 'customMetadata', true)); mappings_ = mappings; return mappings_; } function addRef(metadata, service) { function generateRef() { var bucket = metadata['bucket']; var path = metadata['fullPath']; var loc = new Location(bucket, path); return service._makeStorageReference(loc); } Object.defineProperty(metadata, 'ref', { get: generateRef }); } function fromResource(service, resource, mappings) { var metadata = {}; metadata['type'] = 'file'; var len = mappings.length; for (var i = 0; i < len; i++) { var mapping = mappings[i]; metadata[mapping.local] = mapping.xform(metadata, resource[mapping.server]); } addRef(metadata, service); return metadata; } function fromResourceString(service, resourceString, mappings) { var obj = jsonObjectOrNull(resourceString); if (obj === null) { return null; } var resource = obj; return fromResource(service, resource, mappings); } function downloadUrlFromResourceString(metadata, resourceString) { var obj = jsonObjectOrNull(resourceString); if (obj === null) { return null; } if (!isString(obj['downloadTokens'])) { // This can happen if objects are uploaded through GCS and retrieved // through list, so we don't want to throw an Error. return null; } var tokens = obj['downloadTokens']; if (tokens.length === 0) { return null; } var encode = encodeURIComponent; var tokensList = tokens.split(','); var urls = tokensList.map(function (token) { var bucket = metadata['bucket']; var path = metadata['fullPath']; var urlPart = '/b/' + encode(bucket) + '/o/' + encode(path); var base = makeUrl(urlPart); var queryString = makeQueryString({ alt: 'media', token: token }); return base + queryString; }); return urls[0]; } function toResourceString(metadata, mappings) { var resource = {}; var len = mappings.length; for (var i = 0; i < len; i++) { var mapping = mappings[i]; if (mapping.writable) { resource[mapping.server] = metadata[mapping.local]; } } return JSON.stringify(resource); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var PREFIXES_KEY = 'prefixes'; var ITEMS_KEY = 'items'; function fromBackendResponse(service, bucket, resource) { var listResult = { prefixes: [], items: [], nextPageToken: resource['nextPageToken'] }; if (resource[PREFIXES_KEY]) { for (var _i = 0, _a = resource[PREFIXES_KEY]; _i < _a.length; _i++) { var path = _a[_i]; var pathWithoutTrailingSlash = path.replace(/\/$/, ''); var reference = service._makeStorageReference(new Location(bucket, pathWithoutTrailingSlash)); listResult.prefixes.push(reference); } } if (resource[ITEMS_KEY]) { for (var _b = 0, _c = resource[ITEMS_KEY]; _b < _c.length; _b++) { var item = _c[_b]; var reference = service._makeStorageReference(new Location(bucket, item['name'])); listResult.items.push(reference); } } return listResult; } function fromResponseString(service, bucket, resourceString) { var obj = jsonObjectOrNull(resourceString); if (obj === null) { return null; } var resource = obj; return fromBackendResponse(service, bucket, resource); } var RequestInfo = /** @class */ (function () { function RequestInfo(url, method, /** * Returns the value with which to resolve the request's promise. Only called * if the request is successful. Throw from this function to reject the * returned Request's promise with the thrown error. * Note: The XhrIo passed to this function may be reused after this callback * returns. Do not keep a reference to it in any way. */ handler, timeout) { this.url = url; this.method = method; this.handler = handler; this.timeout = timeout; this.urlParams = {}; this.headers = {}; this.body = null; this.errorHandler = null; /** * Called with the current number of bytes uploaded and total size (-1 if not * computable) of the request body (i.e. used to report upload progress). */ this.progressCallback = null; this.successCodes = [200]; this.additionalRetryCodes = []; } return RequestInfo; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Throws the UNKNOWN FirebaseStorageError if cndn is false. */ function handlerCheck(cndn) { if (!cndn) { throw unknown(); } } function metadataHandler(service, mappings) { function handler(xhr, text) { var metadata = fromResourceString(service, text, mappings); handlerCheck(metadata !== null); return metadata; } return handler; } function listHandler(service, bucket) { function handler(xhr, text) { var listResult = fromResponseString(service, bucket, text); handlerCheck(listResult !== null); return listResult; } return handler; } function downloadUrlHandler(service, mappings) { function handler(xhr, text) { var metadata = fromResourceString(service, text, mappings); handlerCheck(metadata !== null); return downloadUrlFromResourceString(metadata, text); } return handler; } function sharedErrorHandler(location) { function errorHandler(xhr, err) { var newErr; if (xhr.getStatus() === 401) { newErr = unauthenticated(); } else { if (xhr.getStatus() === 402) { newErr = quotaExceeded(location.bucket); } else { if (xhr.getStatus() === 403) { newErr = unauthorized(location.path); } else { newErr = err; } } } newErr.serverResponse = err.serverResponse; return newErr; } return errorHandler; } function objectErrorHandler(location) { var shared = sharedErrorHandler(location); function errorHandler(xhr, err) { var newErr = shared(xhr, err); if (xhr.getStatus() === 404) { newErr = objectNotFound(location.path); } newErr.serverResponse = err.serverResponse; return newErr; } return errorHandler; } function getMetadata(service, location, mappings) { var urlPart = location.fullServerUrl(); var url = makeUrl(urlPart); var method = 'GET'; var timeout = service.maxOperationRetryTime; var requestInfo = new RequestInfo(url, method, metadataHandler(service, mappings), timeout); requestInfo.errorHandler = objectErrorHandler(location); return requestInfo; } function list(service, location, delimiter, pageToken, maxResults) { var urlParams = {}; if (location.isRoot) { urlParams['prefix'] = ''; } else { urlParams['prefix'] = location.path + '/'; } if (delimiter && delimiter.length > 0) { urlParams['delimiter'] = delimiter; } if (pageToken) { urlParams['pageToken'] = pageToken; } if (maxResults) { urlParams['maxResults'] = maxResults; } var urlPart = location.bucketOnlyServerUrl(); var url = makeUrl(urlPart); var method = 'GET'; var timeout = service.maxOperationRetryTime; var requestInfo = new RequestInfo(url, method, listHandler(service, location.bucket), timeout); requestInfo.urlParams = urlParams; requestInfo.errorHandler = sharedErrorHandler(location); return requestInfo; } function getDownloadUrl(service, location, mappings) { var urlPart = location.fullServerUrl(); var url = makeUrl(urlPart); var method = 'GET'; var timeout = service.maxOperationRetryTime; var requestInfo = new RequestInfo(url, method, downloadUrlHandler(service, mappings), timeout); requestInfo.errorHandler = objectErrorHandler(location); return requestInfo; } function updateMetadata(service, location, metadata, mappings) { var urlPart = location.fullServerUrl(); var url = makeUrl(urlPart); var method = 'PATCH'; var body = toResourceString(metadata, mappings); var headers = { 'Content-Type': 'application/json; charset=utf-8' }; var timeout = service.maxOperationRetryTime; var requestInfo = new RequestInfo(url, method, metadataHandler(service, mappings), timeout); requestInfo.headers = headers; requestInfo.body = body; requestInfo.errorHandler = objectErrorHandler(location); return requestInfo; } function deleteObject(service, location) { var urlPart = location.fullServerUrl(); var url = makeUrl(urlPart); var method = 'DELETE'; var timeout = service.maxOperationRetryTime; function handler(_xhr, _text) { } var requestInfo = new RequestInfo(url, method, handler, timeout); requestInfo.successCodes = [200, 204]; requestInfo.errorHandler = objectErrorHandler(location); return requestInfo; } function determineContentType_(metadata, blob) { return ((metadata && metadata['contentType']) || (blob && blob.type()) || 'application/octet-stream'); } function metadataForUpload_(location, blob, metadata) { var metadataClone = Object.assign({}, metadata); metadataClone['fullPath'] = location.path; metadataClone['size'] = blob.size(); if (!metadataClone['contentType']) { metadataClone['contentType'] = determineContentType_(null, blob); } return metadataClone; } /** * Prepare RequestInfo for uploads as Content-Type: multipart. */ function multipartUpload(service, location, mappings, blob, metadata) { var urlPart = location.bucketOnlyServerUrl(); var headers = { 'X-Goog-Upload-Protocol': 'multipart' }; function genBoundary() { var str = ''; for (var i = 0; i < 2; i++) { str = str + Math.random().toString().slice(2); } return str; } var boundary = genBoundary(); headers['Content-Type'] = 'multipart/related; boundary=' + boundary; var metadata_ = metadataForUpload_(location, blob, metadata); var metadataString = toResourceString(metadata_, mappings); var preBlobPart = '--' + boundary + '\r\n' + 'Content-Type: application/json; charset=utf-8\r\n\r\n' + metadataString + '\r\n--' + boundary + '\r\n' + 'Content-Type: ' + metadata_['contentType'] + '\r\n\r\n'; var postBlobPart = '\r\n--' + boundary + '--'; var body = FbsBlob.getBlob(preBlobPart, blob, postBlobPart); if (body === null) { throw cannotSliceBlob(); } var urlParams = { name: metadata_['fullPath'] }; var url = makeUrl(urlPart); var method = 'POST'; var timeout = service.maxUploadRetryTime; var requestInfo = new RequestInfo(url, method, metadataHandler(service, mappings), timeout); requestInfo.urlParams = urlParams; requestInfo.headers = headers; requestInfo.body = body.uploadData(); requestInfo.errorHandler = sharedErrorHandler(location); return requestInfo; } /** * @param current The number of bytes that have been uploaded so far. * @param total The total number of bytes in the upload. * @param opt_finalized True if the server has finished the upload. * @param opt_metadata The upload metadata, should * only be passed if opt_finalized is true. */ var ResumableUploadStatus = /** @class */ (function () { function ResumableUploadStatus(current, total, finalized, metadata) { this.current = current; this.total = total; this.finalized = !!finalized; this.metadata = metadata || null; } return ResumableUploadStatus; }()); function checkResumeHeader_(xhr, allowed) { var status = null; try { status = xhr.getResponseHeader('X-Goog-Upload-Status'); } catch (e) { handlerCheck(false); } var allowedStatus = allowed || ['active']; handlerCheck(!!status && allowedStatus.indexOf(status) !== -1); return status; } function createResumableUpload(service, location, mappings, blob, metadata) { var urlPart = location.bucketOnlyServerUrl(); var metadataForUpload = metadataForUpload_(location, blob, metadata); var urlParams = { name: metadataForUpload['fullPath'] }; var url = makeUrl(urlPart); var method = 'POST'; var headers = { 'X-Goog-Upload-Protocol': 'resumable', 'X-Goog-Upload-Command': 'start', 'X-Goog-Upload-Header-Content-Length': blob.size(), 'X-Goog-Upload-Header-Content-Type': metadataForUpload['contentType'], 'Content-Type': 'application/json; charset=utf-8' }; var body = toResourceString(metadataForUpload, mappings); var timeout = service.maxUploadRetryTime; function handler(xhr) { checkResumeHeader_(xhr); var url; try { url = xhr.getResponseHeader('X-Goog-Upload-URL'); } catch (e) { handlerCheck(false); } handlerCheck(isString(url)); return url; } var requestInfo = new RequestInfo(url, method, handler, timeout); requestInfo.urlParams = urlParams; requestInfo.headers = headers; requestInfo.body = body; requestInfo.errorHandler = sharedErrorHandler(location); return requestInfo; } /** * @param url From a call to fbs.requests.createResumableUpload. */ function getResumableUploadStatus(service, location, url, blob) { var headers = { 'X-Goog-Upload-Command': 'query' }; function handler(xhr) { var status = checkResumeHeader_(xhr, ['active', 'final']); var sizeString = null; try { sizeString = xhr.getResponseHeader('X-Goog-Upload-Size-Received'); } catch (e) { handlerCheck(false); } if (!sizeString) { // null or empty string handlerCheck(false); } var size = Number(sizeString); handlerCheck(!isNaN(size)); return new ResumableUploadStatus(size, blob.size(), status === 'final'); } var method = 'POST'; var timeout = service.maxUploadRetryTime; var requestInfo = new RequestInfo(url, method, handler, timeout); requestInfo.headers = headers; requestInfo.errorHandler = sharedErrorHandler(location); return requestInfo; } /** * Any uploads via the resumable upload API must transfer a number of bytes * that is a multiple of this number. */ var RESUMABLE_UPLOAD_CHUNK_SIZE = 256 * 1024; /** * @param url From a call to fbs.requests.createResumableUpload. * @param chunkSize Number of bytes to upload. * @param status The previous status. * If not passed or null, we start from the beginning. * @throws fbs.Error If the upload is already complete, the passed in status * has a final size inconsistent with the blob, or the blob cannot be sliced * for upload. */ function continueResumableUpload(location, service, url, blob, chunkSize, mappings, status, progressCallback) { // TODO(andysoto): standardize on internal asserts // assert(!(opt_status && opt_status.finalized)); var status_ = new ResumableUploadStatus(0, 0); if (status) { status_.current = status.current; status_.total = status.total; } else { status_.current = 0; status_.total = blob.size(); } if (blob.size() !== status_.total) { throw serverFileWrongSize(); } var bytesLeft = status_.total - status_.current; var bytesToUpload = bytesLeft; if (chunkSize > 0) { bytesToUpload = Math.min(bytesToUpload, chunkSize); } var startByte = status_.current; var endByte = startByte + bytesToUpload; var uploadCommand = bytesToUpload === bytesLeft ? 'upload, finalize' : 'upload'; var headers = { 'X-Goog-Upload-Command': uploadCommand, 'X-Goog-Upload-Offset': status_.current }; var body = blob.slice(startByte, endByte); if (body === null) { throw cannotSliceBlob(); } function handler(xhr, text) { // TODO(andysoto): Verify the MD5 of each uploaded range: // the 'x-range-md5' header comes back with status code 308 responses. // We'll only be able to bail out though, because you can't re-upload a // range that you previously uploaded. var uploadStatus = checkResumeHeader_(xhr, ['active', 'final']); var newCurrent = status_.current + bytesToUpload; var size = blob.size(); var metadata; if (uploadStatus === 'final') { metadata = metadataHandler(service, mappings)(xhr, text); } else { metadata = null; } return new ResumableUploadStatus(newCurrent, size, uploadStatus === 'final', metadata); } var method = 'POST'; var timeout = service.maxUploadRetryTime; var requestInfo = new RequestInfo(url, method, handler, timeout); requestInfo.headers = headers; requestInfo.body = body.uploadData(); requestInfo.progressCallback = progressCallback || null; requestInfo.errorHandler = sharedErrorHandler(location); return requestInfo; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Observer = /** @class */ (function () { function Observer(nextOrObserver, error, complete) { var asFunctions = isFunction(nextOrObserver) || error != null || complete != null; if (asFunctions) { this.next = nextOrObserver; this.error = error; this.complete = complete; } else { var observer = nextOrObserver; this.next = observer.next; this.error = observer.error; this.complete = observer.complete; } } return Observer; }()); /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Returns a function that invokes f with its arguments asynchronously as a * microtask, i.e. as soon as possible after the current script returns back * into browser code. */ // eslint-disable-next-line @typescript-eslint/ban-types function async(f) { return function () { var argsToForward = []; for (var _i = 0; _i < arguments.length; _i++) { argsToForward[_i] = arguments[_i]; } // eslint-disable-next-line @typescript-eslint/no-floating-promises Promise.resolve().then(function () { return f.apply(void 0, argsToForward); }); }; } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Represents a blob being uploaded. Can be used to pause/resume/cancel the * upload and manage callbacks for various events. * @internal */ var UploadTask = /** @class */ (function () { /** * @param ref - The firebaseStorage.Reference object this task came * from, untyped to avoid cyclic dependencies. * @param blob - The blob to upload. */ function UploadTask(ref, blob, metadata) { var _this = this; if (metadata === void 0) { metadata = null; } /** * Number of bytes transferred so far. */ this._transferred = 0; this._needToFetchStatus = false; this._needToFetchMetadata = false; this._observers = []; this._error = undefined; this._uploadUrl = undefined; this._request = undefined; this._chunkMultiplier = 1; this._resolve = undefined; this._reject = undefined; this._ref = ref; this._blob = blob; this._metadata = metadata; this._mappings = getMappings(); this._resumable = this._shouldDoResumable(this._blob); this._state = "running" /* RUNNING */; this._errorHandler = function (error) { _this._request = undefined; _this._chunkMultiplier = 1; if (error._codeEquals("canceled" /* CANCELED */)) { _this._needToFetchStatus = true; _this.completeTransitions_(); } else { _this._error = error; _this._transition("error" /* ERROR */); } }; this._metadataErrorHandler = function (error) { _this._request = undefined; if (error._codeEquals("canceled" /* CANCELED */)) { _this.completeTransitions_(); } else { _this._error = error; _this._transition("error" /* ERROR */); } }; this._promise = new Promise(function (resolve, reject) { _this._resolve = resolve; _this._reject = reject; _this._start(); }); // Prevent uncaught rejections on the internal promise from bubbling out // to the top level with a dummy handler. this._promise.then(null, function () { }); } UploadTask.prototype._makeProgressCallback = function () { var _this = this; var sizeBefore = this._transferred; return function (loaded) { return _this._updateProgress(sizeBefore + loaded); }; }; UploadTask.prototype._shouldDoResumable = function (blob) { return blob.size() > 256 * 1024; }; UploadTask.prototype._start = function () { if (this._state !== "running" /* RUNNING */) { // This can happen if someone pauses us in a resume callback, for example. return; } if (this._request !== undefined) { return; } if (this._resumable) { if (this._uploadUrl === undefined) { this._createResumable(); } else { if (this._needToFetchStatus) { this._fetchStatus(); } else { if (this._needToFetchMetadata) { // Happens if we miss the metadata on upload completion. this._fetchMetadata(); } else { this._continueUpload(); } } } } else { this._oneShotUpload(); } }; UploadTask.prototype._resolveToken = function (callback) { var _this = this; // eslint-disable-next-line @typescript-eslint/no-floating-promises this._ref.storage._getAuthToken().then(function (authToken) { switch (_this._state) { case "running" /* RUNNING */: callback(authToken); break; case "canceling" /* CANCELING */: _this._transition("canceled" /* CANCELED */); break; case "pausing" /* PAUSING */: _this._transition("paused" /* PAUSED */); break; } }); }; // TODO(andysoto): assert false UploadTask.prototype._createResumable = function () { var _this = this; this._resolveToken(function (authToken) { var requestInfo = createResumableUpload(_this._ref.storage, _this._ref._location, _this._mappings, _this._blob, _this._metadata); var createRequest = _this._ref.storage._makeRequest(requestInfo, authToken); _this._request = createRequest; createRequest.getPromise().then(function (url) { _this._request = undefined; _this._uploadUrl = url; _this._needToFetchStatus = false; _this.completeTransitions_(); }, _this._errorHandler); }); }; UploadTask.prototype._fetchStatus = function () { var _this = this; // TODO(andysoto): assert(this.uploadUrl_ !== null); var url = this._uploadUrl; this._resolveToken(function (authToken) { var requestInfo = getResumableUploadStatus(_this._ref.storage, _this._ref._location, url, _this._blob); var statusRequest = _this._ref.storage._makeRequest(requestInfo, authToken); _this._request = statusRequest; statusRequest.getPromise().then(function (status) { status = status; _this._request = undefined; _this._updateProgress(status.current); _this._needToFetchStatus = false; if (status.finalized) { _this._needToFetchMetadata = true; } _this.completeTransitions_(); }, _this._errorHandler); }); }; UploadTask.prototype._continueUpload = function () { var _this = this; var chunkSize = RESUMABLE_UPLOAD_CHUNK_SIZE * this._chunkMultiplier; var status = new ResumableUploadStatus(this._transferred, this._blob.size()); // TODO(andysoto): assert(this.uploadUrl_ !== null); var url = this._uploadUrl; this._resolveToken(function (authToken) { var requestInfo; try { requestInfo = continueResumableUpload(_this._ref._location, _this._ref.storage, url, _this._blob, chunkSize, _this._mappings, status, _this._makeProgressCallback()); } catch (e) { _this._error = e; _this._transition("error" /* ERROR */); return; } var uploadRequest = _this._ref.storage._makeRequest(requestInfo, authToken); _this._request = uploadRequest; uploadRequest.getPromise().then(function (newStatus) { _this._increaseMultiplier(); _this._request = undefined; _this._updateProgress(newStatus.current); if (newStatus.finalized) { _this._metadata = newStatus.metadata; _this._transition("success" /* SUCCESS */); } else { _this.completeTransitions_(); } }, _this._errorHandler); }); }; UploadTask.prototype._increaseMultiplier = function () { var currentSize = RESUMABLE_UPLOAD_CHUNK_SIZE * this._chunkMultiplier; // Max chunk size is 32M. if (currentSize < 32 * 1024 * 1024) { this._chunkMultiplier *= 2; } }; UploadTask.prototype._fetchMetadata = function () { var _this = this; this._resolveToken(function (authToken) { var requestInfo = getMetadata(_this._ref.storage, _this._ref._location, _this._mappings); var metadataRequest = _this._ref.storage._makeRequest(requestInfo, authToken); _this._request = metadataRequest; metadataRequest.getPromise().then(function (metadata) { _this._request = undefined; _this._metadata = metadata; _this._transition("success" /* SUCCESS */); }, _this._metadataErrorHandler); }); }; UploadTask.prototype._oneShotUpload = function () { var _this = this; this._resolveToken(function (authToken) { var requestInfo = multipartUpload(_this._ref.storage, _this._ref._location, _this._mappings, _this._blob, _this._metadata); var multipartRequest = _this._ref.storage._makeRequest(requestInfo, authToken); _this._request = multipartRequest; multipartRequest.getPromise().then(function (metadata) { _this._request = undefined; _this._metadata = metadata; _this._updateProgress(_this._blob.size()); _this._transition("success" /* SUCCESS */); }, _this._errorHandler); }); }; UploadTask.prototype._updateProgress = function (transferred) { var old = this._transferred; this._transferred = transferred; // A progress update can make the "transferred" value smaller (e.g. a // partial upload not completed by server, after which the "transferred" // value may reset to the value at the beginning of the request). if (this._transferred !== old) { this._notifyObservers(); } }; UploadTask.prototype._transition = function (state) { if (this._state === state) { return; } switch (state) { case "canceling" /* CANCELING */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.RUNNING || // this.state_ === InternalTaskState.PAUSING); this._state = state; if (this._request !== undefined) { this._request.cancel(); } break; case "pausing" /* PAUSING */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.RUNNING); this._state = state; if (this._request !== undefined) { this._request.cancel(); } break; case "running" /* RUNNING */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.PAUSED || // this.state_ === InternalTaskState.PAUSING); var wasPaused = this._state === "paused" /* PAUSED */; this._state = state; if (wasPaused) { this._notifyObservers(); this._start(); } break; case "paused" /* PAUSED */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.PAUSING); this._state = state; this._notifyObservers(); break; case "canceled" /* CANCELED */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.PAUSED || // this.state_ === InternalTaskState.CANCELING); this._error = canceled(); this._state = state; this._notifyObservers(); break; case "error" /* ERROR */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.RUNNING || // this.state_ === InternalTaskState.PAUSING || // this.state_ === InternalTaskState.CANCELING); this._state = state; this._notifyObservers(); break; case "success" /* SUCCESS */: // TODO(andysoto): // assert(this.state_ === InternalTaskState.RUNNING || // this.state_ === InternalTaskState.PAUSING || // this.state_ === InternalTaskState.CANCELING); this._state = state; this._notifyObservers(); break; } }; UploadTask.prototype.completeTransitions_ = function () { switch (this._state) { case "pausing" /* PAUSING */: this._transition("paused" /* PAUSED */); break; case "canceling" /* CANCELING */: this._transition("canceled" /* CANCELED */); break; case "running" /* RUNNING */: this._start(); break; } }; Object.defineProperty(UploadTask.prototype, "snapshot", { /** * A snapshot of the current task state. */ get: function () { var externalState = taskStateFromInternalTaskState(this._state); return { bytesTransferred: this._transferred, totalBytes: this._blob.size(), state: externalState, metadata: this._metadata, task: this, ref: this._ref }; }, enumerable: false, configurable: true }); /** * Adds a callback for an event. * @param type - The type of event to listen for. * @param nextOrObserver - * The `next` function, which gets called for each item in * the event stream, or an observer object with some or all of these three * properties (`next`, `error`, `complete`). * @param error - A function that gets called with a `FirebaseStorageError` * if the event stream ends due to an error. * @param completed - A function that gets called if the * event stream ends normally. * @returns * If only the event argument is passed, returns a function you can use to * add callbacks (see the examples above). If more than just the event * argument is passed, returns a function you can call to unregister the * callbacks. */ UploadTask.prototype.on = function (type, nextOrObserver, error, completed) { var _this = this; var observer = new Observer(nextOrObserver, error, completed); this._addObserver(observer); return function () { _this._removeObserver(observer); }; }; /** * This object behaves like a Promise, and resolves with its snapshot data * when the upload completes. * @param onFulfilled - The fulfillment callback. Promise chaining works as normal. * @param onRejected - The rejection callback. */ UploadTask.prototype.then = function (onFulfilled, onRejected) { // These casts are needed so that TypeScript can infer the types of the // resulting Promise. return this._promise.then(onFulfilled, onRejected); }; /** * Equivalent to calling `then(null, onRejected)`. */ UploadTask.prototype.catch = function (onRejected) { return this.then(null, onRejected); }; /** * Adds the given observer. */ UploadTask.prototype._addObserver = function (observer) { this._observers.push(observer); this._notifyObserver(observer); }; /** * Removes the given observer. */ UploadTask.prototype._removeObserver = function (observer) { var i = this._observers.indexOf(observer); if (i !== -1) { this._observers.splice(i, 1); } }; UploadTask.prototype._notifyObservers = function () { var _this = this; this._finishPromise(); var observers = this._observers.slice(); observers.forEach(function (observer) { _this._notifyObserver(observer); }); }; UploadTask.prototype._finishPromise = function () { if (this._resolve !== undefined) { var triggered = true; switch (taskStateFromInternalTaskState(this._state)) { case TaskState.SUCCESS: async(this._resolve.bind(null, this.snapshot))(); break; case TaskState.CANCELED: case TaskState.ERROR: var toCall = this._reject; async(toCall.bind(null, this._error))(); break; default: triggered = false; break; } if (triggered) { this._resolve = undefined; this._reject = undefined; } } }; UploadTask.prototype._notifyObserver = function (observer) { var externalState = taskStateFromInternalTaskState(this._state); switch (externalState) { case TaskState.RUNNING: case TaskState.PAUSED: if (observer.next) { async(observer.next.bind(observer, this.snapshot))(); } break; case TaskState.SUCCESS: if (observer.complete) { async(observer.complete.bind(observer))(); } break; case TaskState.CANCELED: case TaskState.ERROR: if (observer.error) { async(observer.error.bind(observer, this._error))(); } break; default: // TODO(andysoto): assert(false); if (observer.error) { async(observer.error.bind(observer, this._error))(); } } }; /** * Resumes a paused task. Has no effect on a currently running or failed task. * @returns True if the operation took effect, false if ignored. */ UploadTask.prototype.resume = function () { var valid = this._state === "paused" /* PAUSED */ || this._state === "pausing" /* PAUSING */; if (valid) { this._transition("running" /* RUNNING */); } return valid; }; /** * Pauses a currently running task. Has no effect on a paused or failed task. * @returns True if the operation took effect, false if ignored. */ UploadTask.prototype.pause = function () { var valid = this._state === "running" /* RUNNING */; if (valid) { this._transition("pausing" /* PAUSING */); } return valid; }; /** * Cancels a currently running or paused task. Has no effect on a complete or * failed task. * @returns True if the operation took effect, false if ignored. */ UploadTask.prototype.cancel = function () { var valid = this._state === "running" /* RUNNING */ || this._state === "pausing" /* PAUSING */; if (valid) { this._transition("canceling" /* CANCELING */); } return valid; }; return UploadTask; }()); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Provides methods to interact with a bucket in the Firebase Storage service. * @internal * @param _location - An fbs.location, or the URL at * which to base this object, in one of the following forms: * gs:/// * http[s]://firebasestorage.googleapis.com/ * /b//o/ * Any query or fragment strings will be ignored in the http[s] * format. If no value is passed, the storage object will use a URL based on * the project ID of the base firebase.App instance. */ var Reference = /** @class */ (function () { function Reference(_service, location) { this._service = _service; if (location instanceof Location) { this._location = location; } else { this._location = Location.makeFromUrl(location); } } /** * Returns the URL for the bucket and path this object references, * in the form gs:/// * @override */ Reference.prototype.toString = function () { return 'gs://' + this._location.bucket + '/' + this._location.path; }; Reference.prototype._newRef = function (service, location) { return new Reference(service, location); }; Object.defineProperty(Reference.prototype, "root", { /** * A reference to the root of this object's bucket. */ get: function () { var location = new Location(this._location.bucket, ''); return this._newRef(this._service, location); }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "bucket", { /** * The name of the bucket containing this reference's object. */ get: function () { return this._location.bucket; }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "fullPath", { /** * The full path of this object. */ get: function () { return this._location.path; }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "name", { /** * The short name of this object, which is the last component of the full path. * For example, if fullPath is 'full/path/image.png', name is 'image.png'. */ get: function () { return lastComponent(this._location.path); }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "storage", { /** * The `StorageService` instance this `StorageReference` is associated with. */ get: function () { return this._service; }, enumerable: false, configurable: true }); Object.defineProperty(Reference.prototype, "parent", { /** * A `StorageReference` pointing to the parent location of this `StorageReference`, or null if * this reference is the root. */ get: function () { var newPath = parent(this._location.path); if (newPath === null) { return null; } var location = new Location(this._location.bucket, newPath); return new Reference(this._service, location); }, enumerable: false, configurable: true }); /** * Utility function to throw an error in methods that do not accept a root reference. */ Reference.prototype._throwIfRoot = function (name) { if (this._location.path === '') { throw invalidRootOperation(name); } }; return Reference; }()); /** * Uploads data to this object's location. * The upload can be paused and resumed, and exposes progress updates. * @public * @param ref - StorageReference where data should be uploaded. * @param data - The data to upload. * @param metadata - Metadata for the newly uploaded data. * @returns An UploadTask */ function uploadBytesResumable(ref, data, metadata) { ref._throwIfRoot('uploadBytesResumable'); return new UploadTask(ref, new FbsBlob(data), metadata); } /** * List all items (files) and prefixes (folders) under this storage reference. * * This is a helper method for calling list() repeatedly until there are * no more results. The default pagination size is 1000. * * Note: The results may not be consistent if objects are changed while this * operation is running. * * Warning: listAll may potentially consume too many resources if there are * too many results. * @public * @param ref - StorageReference to get list from. * * @returns A Promise that resolves with all the items and prefixes under * the current storage reference. `prefixes` contains references to * sub-directories and `items` contains references to objects in this * folder. `nextPageToken` is never returned. */ function listAll(ref) { var accumulator = { prefixes: [], items: [] }; return listAllHelper(ref, accumulator).then(function () { return accumulator; }); } /** * Separated from listAll because async functions can't use "arguments". * @param ref * @param accumulator * @param pageToken */ function listAllHelper(ref, accumulator, pageToken) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var opt, nextPage; var _a, _b; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_c) { switch (_c.label) { case 0: opt = { // maxResults is 1000 by default. pageToken: pageToken }; return [4 /*yield*/, list$1(ref, opt)]; case 1: nextPage = _c.sent(); (_a = accumulator.prefixes).push.apply(_a, nextPage.prefixes); (_b = accumulator.items).push.apply(_b, nextPage.items); if (!(nextPage.nextPageToken != null)) return [3 /*break*/, 3]; return [4 /*yield*/, listAllHelper(ref, accumulator, nextPage.nextPageToken)]; case 2: _c.sent(); _c.label = 3; case 3: return [2 /*return*/]; } }); }); } /** * List items (files) and prefixes (folders) under this storage reference. * * List API is only available for Firebase Rules Version 2. * * GCS is a key-blob store. Firebase Storage imposes the semantic of '/' * delimited folder structure. * Refer to GCS's List API if you want to learn more. * * To adhere to Firebase Rules's Semantics, Firebase Storage does not * support objects whose paths end with "/" or contain two consecutive * "/"s. Firebase Storage List API will filter these unsupported objects. * list() may fail if there are too many unsupported objects in the bucket. * @public * * @param ref - StorageReference to get list from. * @param options - See ListOptions for details. * @returns A Promise that resolves with the items and prefixes. * `prefixes` contains references to sub-folders and `items` * contains references to objects in this folder. `nextPageToken` * can be used to get the rest of the results. */ function list$1(ref, options) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var authToken, op, requestInfo; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (options != null) { if (typeof options.maxResults === 'number') { validateNumber('options.maxResults', /* minValue= */ 1, /* maxValue= */ 1000, options.maxResults); } } return [4 /*yield*/, ref.storage._getAuthToken()]; case 1: authToken = _a.sent(); op = options || {}; requestInfo = list(ref.storage, ref._location, /*delimiter= */ '/', op.pageToken, op.maxResults); return [2 /*return*/, ref.storage._makeRequest(requestInfo, authToken).getPromise()]; } }); }); } /** * A promise that resolves with the metadata for this object. If this * object doesn't exist or metadata cannot be retreived, the promise is * rejected. * @public * @param ref - StorageReference to get metadata from. */ function getMetadata$1(ref) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var authToken, requestInfo; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: ref._throwIfRoot('getMetadata'); return [4 /*yield*/, ref.storage._getAuthToken()]; case 1: authToken = _a.sent(); requestInfo = getMetadata(ref.storage, ref._location, getMappings()); return [2 /*return*/, ref.storage._makeRequest(requestInfo, authToken).getPromise()]; } }); }); } /** * Updates the metadata for this object. * @public * @param ref - StorageReference to update metadata for. * @param metadata - The new metadata for the object. * Only values that have been explicitly set will be changed. Explicitly * setting a value to null will remove the metadata. * @returns A promise that resolves * with the new metadata for this object. * See `firebaseStorage.Reference.prototype.getMetadata` */ function updateMetadata$1(ref, metadata) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var authToken, requestInfo; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: ref._throwIfRoot('updateMetadata'); return [4 /*yield*/, ref.storage._getAuthToken()]; case 1: authToken = _a.sent(); requestInfo = updateMetadata(ref.storage, ref._location, metadata, getMappings()); return [2 /*return*/, ref.storage._makeRequest(requestInfo, authToken).getPromise()]; } }); }); } /** * Returns the download URL for the given Reference. * @public * @returns A promise that resolves with the download * URL for this object. */ function getDownloadURL(ref) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var authToken, requestInfo; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: ref._throwIfRoot('getDownloadURL'); return [4 /*yield*/, ref.storage._getAuthToken()]; case 1: authToken = _a.sent(); requestInfo = getDownloadUrl(ref.storage, ref._location, getMappings()); return [2 /*return*/, ref.storage ._makeRequest(requestInfo, authToken) .getPromise() .then(function (url) { if (url === null) { throw noDownloadURL(); } return url; })]; } }); }); } /** * Deletes the object at this location. * @public * @param ref - StorageReference for object to delete. * @returns A promise that resolves if the deletion succeeds. */ function deleteObject$1(ref) { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var authToken, requestInfo; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: ref._throwIfRoot('deleteObject'); return [4 /*yield*/, ref.storage._getAuthToken()]; case 1: authToken = _a.sent(); requestInfo = deleteObject(ref.storage, ref._location); return [2 /*return*/, ref.storage._makeRequest(requestInfo, authToken).getPromise()]; } }); }); } /** * Returns reference for object obtained by appending `childPath` to `ref`. * * @param ref - StorageReference to get child of. * @param childPath - Child path from provided ref. * @returns A reference to the object obtained by * appending childPath, removing any duplicate, beginning, or trailing * slashes. * */ function _getChild(ref, childPath) { var newPath = child(ref._location.path, childPath); var location = new Location(ref._location.bucket, newPath); return new Reference(ref.storage, location); } /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function isUrl(path) { return /^[A-Za-z]+:\/\//.test(path); } /** * Returns a firebaseStorage.Reference for the given url. */ function refFromURL(service, url) { return new Reference(service, url); } /** * Returns a firebaseStorage.Reference for the given path in the default * bucket. */ function refFromPath(ref, path) { if (ref instanceof StorageService) { var service = ref; if (service._bucket == null) { throw noDefaultBucket(); } var reference = new Reference(service, service._bucket); if (path != null) { return refFromPath(reference, path); } else { return reference; } } else { // ref is a Reference if (path !== undefined) { if (path.includes('..')) { throw invalidArgument('`path` param cannot contain ".."'); } return _getChild(ref, path); } else { return ref; } } } function ref(serviceOrRef, pathOrUrl) { if (pathOrUrl && isUrl(pathOrUrl)) { if (serviceOrRef instanceof StorageService) { return refFromURL(serviceOrRef, pathOrUrl); } else { throw invalidArgument('To use ref(service, url), the first argument must be a Storage instance.'); } } else { return refFromPath(serviceOrRef, pathOrUrl); } } function extractBucket(config) { var bucketString = config === null || config === void 0 ? void 0 : config[CONFIG_STORAGE_BUCKET_KEY]; if (bucketString == null) { return null; } return Location.makeFromBucketSpec(bucketString); } /** * A service that provides Firebase Storage Reference instances. * @public * @param opt_url - gs:// url to a custom Storage Bucket */ var StorageService = /** @class */ (function () { function StorageService( /** * FirebaseApp associated with this StorageService instance. */ app, _authProvider, _pool, _url, _firebaseVersion) { this.app = app; this._authProvider = _authProvider; this._pool = _pool; this._url = _url; this._firebaseVersion = _firebaseVersion; this._bucket = null; this._appId = null; this._deleted = false; this._maxOperationRetryTime = DEFAULT_MAX_OPERATION_RETRY_TIME; this._maxUploadRetryTime = DEFAULT_MAX_UPLOAD_RETRY_TIME; this._requests = new Set(); if (_url != null) { this._bucket = Location.makeFromBucketSpec(_url); } else { this._bucket = extractBucket(this.app.options); } } Object.defineProperty(StorageService.prototype, "maxUploadRetryTime", { /** * The maximum time to retry uploads in milliseconds. */ get: function () { return this._maxUploadRetryTime; }, set: function (time) { validateNumber('time', /* minValue=*/ 0, /* maxValue= */ Number.POSITIVE_INFINITY, time); this._maxUploadRetryTime = time; }, enumerable: false, configurable: true }); Object.defineProperty(StorageService.prototype, "maxOperationRetryTime", { /** * The maximum time to retry operations other than uploads or downloads in * milliseconds. */ get: function () { return this._maxOperationRetryTime; }, set: function (time) { validateNumber('time', /* minValue=*/ 0, /* maxValue= */ Number.POSITIVE_INFINITY, time); this._maxOperationRetryTime = time; }, enumerable: false, configurable: true }); StorageService.prototype._getAuthToken = function () { return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var auth, tokenData; return Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["d" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: auth = this._authProvider.getImmediate({ optional: true }); if (!auth) return [3 /*break*/, 2]; return [4 /*yield*/, auth.getToken()]; case 1: tokenData = _a.sent(); if (tokenData !== null) { return [2 /*return*/, tokenData.accessToken]; } _a.label = 2; case 2: return [2 /*return*/, null]; } }); }); }; /** * Stop running requests and prevent more from being created. */ StorageService.prototype._delete = function () { this._deleted = true; this._requests.forEach(function (request) { return request.cancel(); }); this._requests.clear(); return Promise.resolve(); }; /** * Returns a new firebaseStorage.Reference object referencing this StorageService * at the given Location. */ StorageService.prototype._makeStorageReference = function (loc) { return new Reference(this, loc); }; /** * @param requestInfo - HTTP RequestInfo object * @param authToken - Firebase auth token */ StorageService.prototype._makeRequest = function (requestInfo, authToken) { var _this = this; if (!this._deleted) { var request_1 = makeRequest(requestInfo, this._appId, authToken, this._pool, this._firebaseVersion); this._requests.add(request_1); // Request removes itself from set when complete. request_1.getPromise().then(function () { return _this._requests.delete(request_1); }, function () { return _this._requests.delete(request_1); }); return request_1; } else { return new FailRequest(appDeleted()); } }; return StorageService; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Uploads data to this object's location. * The upload can be paused and resumed, and exposes progress updates. * @public * @param ref - StorageReference where data should be uploaded. * @param data - The data to upload. * @param metadata - Metadata for the data to upload. * @returns An UploadTask */ function uploadBytesResumable$1(ref, data, metadata) { return uploadBytesResumable(ref, data, metadata); } /** * A promise that resolves with the metadata for this object. If this * object doesn't exist or metadata cannot be retreived, the promise is * rejected. * @public * @param ref - StorageReference to get metadata from. */ function getMetadata$2(ref) { return getMetadata$1(ref); } /** * Updates the metadata for this object. * @public * @param ref - StorageReference to update metadata for. * @param metadata - The new metadata for the object. * Only values that have been explicitly set will be changed. Explicitly * setting a value to null will remove the metadata. * @returns A promise that resolves with the new metadata for this object. */ function updateMetadata$2(ref, metadata) { return updateMetadata$1(ref, metadata); } /** * List items (files) and prefixes (folders) under this storage reference. * * List API is only available for Firebase Rules Version 2. * * GCS is a key-blob store. Firebase Storage imposes the semantic of '/' * delimited folder structure. * Refer to GCS's List API if you want to learn more. * * To adhere to Firebase Rules's Semantics, Firebase Storage does not * support objects whose paths end with "/" or contain two consecutive * "/"s. Firebase Storage List API will filter these unsupported objects. * list() may fail if there are too many unsupported objects in the bucket. * @public * * @param ref - StorageReference to get list from. * @param options - See ListOptions for details. * @returns A Promise that resolves with the items and prefixes. * `prefixes` contains references to sub-folders and `items` * contains references to objects in this folder. `nextPageToken` * can be used to get the rest of the results. */ function list$2(ref, options) { return list$1(ref, options); } /** * List all items (files) and prefixes (folders) under this storage reference. * * This is a helper method for calling list() repeatedly until there are * no more results. The default pagination size is 1000. * * Note: The results may not be consistent if objects are changed while this * operation is running. * * Warning: listAll may potentially consume too many resources if there are * too many results. * @public * @param ref - StorageReference to get list from. * * @returns A Promise that resolves with all the items and prefixes under * the current storage reference. `prefixes` contains references to * sub-directories and `items` contains references to objects in this * folder. `nextPageToken` is never returned. */ function listAll$1(ref) { return listAll(ref); } /** * Returns the download URL for the given Reference. * @public * @returns A promise that resolves with the download * URL for this object. */ function getDownloadURL$1(ref) { return getDownloadURL(ref); } /** * Deletes the object at this location. * @public * @param ref - StorageReference for object to delete. * @returns A promise that resolves if the deletion succeeds. */ function deleteObject$2(ref) { return deleteObject$1(ref); } function ref$1(serviceOrRef, pathOrUrl) { return ref(serviceOrRef, pathOrUrl); } /** * @internal */ function _getChild$1(ref, childPath) { return _getChild(ref, childPath); } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var UploadTaskSnapshotCompat = /** @class */ (function () { function UploadTaskSnapshotCompat(_delegate, task, ref) { this._delegate = _delegate; this.task = task; this.ref = ref; } Object.defineProperty(UploadTaskSnapshotCompat.prototype, "bytesTransferred", { get: function () { return this._delegate.bytesTransferred; }, enumerable: false, configurable: true }); Object.defineProperty(UploadTaskSnapshotCompat.prototype, "metadata", { get: function () { return this._delegate.metadata; }, enumerable: false, configurable: true }); Object.defineProperty(UploadTaskSnapshotCompat.prototype, "state", { get: function () { return this._delegate.state; }, enumerable: false, configurable: true }); Object.defineProperty(UploadTaskSnapshotCompat.prototype, "totalBytes", { get: function () { return this._delegate.totalBytes; }, enumerable: false, configurable: true }); return UploadTaskSnapshotCompat; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var UploadTaskCompat = /** @class */ (function () { function UploadTaskCompat(_delegate, _ref) { this._delegate = _delegate; this._ref = _ref; this.cancel = this._delegate.cancel.bind(this._delegate); this.catch = this._delegate.catch.bind(this._delegate); this.pause = this._delegate.pause.bind(this._delegate); this.resume = this._delegate.resume.bind(this._delegate); } Object.defineProperty(UploadTaskCompat.prototype, "snapshot", { get: function () { return new UploadTaskSnapshotCompat(this._delegate.snapshot, this, this._ref); }, enumerable: false, configurable: true }); UploadTaskCompat.prototype.then = function (onFulfilled, onRejected) { var _this = this; return this._delegate.then(function (snapshot) { if (onFulfilled) { return onFulfilled(new UploadTaskSnapshotCompat(snapshot, _this, _this._ref)); } }, onRejected); }; UploadTaskCompat.prototype.on = function (type, nextOrObserver, error, completed) { var _this = this; var wrappedNextOrObserver = undefined; if (!!nextOrObserver) { if (typeof nextOrObserver === 'function') { wrappedNextOrObserver = function (taskSnapshot) { return nextOrObserver(new UploadTaskSnapshotCompat(taskSnapshot, _this, _this._ref)); }; } else { wrappedNextOrObserver = { next: !!nextOrObserver.next ? function (taskSnapshot) { return nextOrObserver.next(new UploadTaskSnapshotCompat(taskSnapshot, _this, _this._ref)); } : undefined, complete: nextOrObserver.complete || undefined, error: nextOrObserver.error || undefined }; } } return this._delegate.on(type, wrappedNextOrObserver, error || undefined, completed || undefined); }; return UploadTaskCompat; }()); var ListResultCompat = /** @class */ (function () { function ListResultCompat(_delegate, _service) { this._delegate = _delegate; this._service = _service; } Object.defineProperty(ListResultCompat.prototype, "prefixes", { get: function () { var _this = this; return this._delegate.prefixes.map(function (ref) { return new ReferenceCompat(ref, _this._service); }); }, enumerable: false, configurable: true }); Object.defineProperty(ListResultCompat.prototype, "items", { get: function () { var _this = this; return this._delegate.items.map(function (ref) { return new ReferenceCompat(ref, _this._service); }); }, enumerable: false, configurable: true }); Object.defineProperty(ListResultCompat.prototype, "nextPageToken", { get: function () { return this._delegate.nextPageToken || null; }, enumerable: false, configurable: true }); return ListResultCompat; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var ReferenceCompat = /** @class */ (function () { function ReferenceCompat(_delegate, storage) { this._delegate = _delegate; this.storage = storage; } Object.defineProperty(ReferenceCompat.prototype, "name", { get: function () { return this._delegate.name; }, enumerable: false, configurable: true }); Object.defineProperty(ReferenceCompat.prototype, "bucket", { get: function () { return this._delegate.bucket; }, enumerable: false, configurable: true }); Object.defineProperty(ReferenceCompat.prototype, "fullPath", { get: function () { return this._delegate.fullPath; }, enumerable: false, configurable: true }); ReferenceCompat.prototype.toString = function () { return this._delegate.toString(); }; /** * @returns A reference to the object obtained by * appending childPath, removing any duplicate, beginning, or trailing * slashes. */ ReferenceCompat.prototype.child = function (childPath) { var reference = _getChild$1(this._delegate, childPath); return new ReferenceCompat(reference, this.storage); }; Object.defineProperty(ReferenceCompat.prototype, "root", { get: function () { return new ReferenceCompat(this._delegate.root, this.storage); }, enumerable: false, configurable: true }); Object.defineProperty(ReferenceCompat.prototype, "parent", { /** * @returns A reference to the parent of the * current object, or null if the current object is the root. */ get: function () { var reference = this._delegate.parent; if (reference == null) { return null; } return new ReferenceCompat(reference, this.storage); }, enumerable: false, configurable: true }); /** * Uploads a blob to this object's location. * @param data - The blob to upload. * @returns An UploadTask that lets you control and * observe the upload. */ ReferenceCompat.prototype.put = function (data, metadata) { this._throwIfRoot('put'); return new UploadTaskCompat(uploadBytesResumable$1(this._delegate, data, metadata), this); }; /** * Uploads a string to this object's location. * @param value - The string to upload. * @param format - The format of the string to upload. * @returns An UploadTask that lets you control and * observe the upload. */ ReferenceCompat.prototype.putString = function (value, format, metadata) { if (format === void 0) { format = StringFormat.RAW; } this._throwIfRoot('putString'); var data = dataFromString(format, value); var metadataClone = Object(__WEBPACK_IMPORTED_MODULE_1_tslib__["a" /* __assign */])({}, metadata); if (metadataClone['contentType'] == null && data.contentType != null) { metadataClone['contentType'] = data.contentType; } return new UploadTaskCompat(new UploadTask(this._delegate, new FbsBlob(data.data, true), metadataClone), this); }; /** * List all items (files) and prefixes (folders) under this storage reference. * * This is a helper method for calling list() repeatedly until there are * no more results. The default pagination size is 1000. * * Note: The results may not be consistent if objects are changed while this * operation is running. * * Warning: listAll may potentially consume too many resources if there are * too many results. * * @returns A Promise that resolves with all the items and prefixes under * the current storage reference. `prefixes` contains references to * sub-directories and `items` contains references to objects in this * folder. `nextPageToken` is never returned. */ ReferenceCompat.prototype.listAll = function () { var _this = this; return listAll$1(this._delegate).then(function (r) { return new ListResultCompat(r, _this.storage); }); }; /** * List items (files) and prefixes (folders) under this storage reference. * * List API is only available for Firebase Rules Version 2. * * GCS is a key-blob store. Firebase Storage imposes the semantic of '/' * delimited folder structure. Refer to GCS's List API if you want to learn more. * * To adhere to Firebase Rules's Semantics, Firebase Storage does not * support objects whose paths end with "/" or contain two consecutive * "/"s. Firebase Storage List API will filter these unsupported objects. * list() may fail if there are too many unsupported objects in the bucket. * * @param options - See ListOptions for details. * @returns A Promise that resolves with the items and prefixes. * `prefixes` contains references to sub-folders and `items` * contains references to objects in this folder. `nextPageToken` * can be used to get the rest of the results. */ ReferenceCompat.prototype.list = function (options) { var _this = this; return list$2(this._delegate, options || undefined).then(function (r) { return new ListResultCompat(r, _this.storage); }); }; /** * A promise that resolves with the metadata for this object. If this * object doesn't exist or metadata cannot be retreived, the promise is * rejected. */ ReferenceCompat.prototype.getMetadata = function () { return getMetadata$2(this._delegate); }; /** * Updates the metadata for this object. * @param metadata - The new metadata for the object. * Only values that have been explicitly set will be changed. Explicitly * setting a value to null will remove the metadata. * @returns A promise that resolves * with the new metadata for this object. * @see firebaseStorage.Reference.prototype.getMetadata */ ReferenceCompat.prototype.updateMetadata = function (metadata) { return updateMetadata$2(this._delegate, metadata); }; /** * @returns A promise that resolves with the download * URL for this object. */ ReferenceCompat.prototype.getDownloadURL = function () { return getDownloadURL$1(this._delegate); }; /** * Deletes the object at this location. * @returns A promise that resolves if the deletion succeeds. */ ReferenceCompat.prototype.delete = function () { this._throwIfRoot('delete'); return deleteObject$2(this._delegate); }; ReferenceCompat.prototype._throwIfRoot = function (name) { if (this._delegate._location.path === '') { throw invalidRootOperation(name); } }; return ReferenceCompat; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * A service that provides firebaseStorage.Reference instances. * @param opt_url gs:// url to a custom Storage Bucket */ var StorageServiceCompat = /** @class */ (function () { function StorageServiceCompat(app, _delegate) { var _this = this; this.app = app; this._delegate = _delegate; this.INTERNAL = { /** * Called when the associated app is deleted. */ delete: function () { return _this._delegate._delete(); } }; } Object.defineProperty(StorageServiceCompat.prototype, "maxOperationRetryTime", { get: function () { return this._delegate.maxOperationRetryTime; }, enumerable: false, configurable: true }); Object.defineProperty(StorageServiceCompat.prototype, "maxUploadRetryTime", { get: function () { return this._delegate.maxUploadRetryTime; }, enumerable: false, configurable: true }); /** * Returns a firebaseStorage.Reference for the given path in the default * bucket. */ StorageServiceCompat.prototype.ref = function (path) { if (isUrl(path)) { throw invalidArgument('ref() expected a child path but got a URL, use refFromURL instead.'); } return new ReferenceCompat(ref$1(this._delegate, path), this); }; /** * Returns a firebaseStorage.Reference object for the given absolute URL, * which must be a gs:// or http[s]:// URL. */ StorageServiceCompat.prototype.refFromURL = function (url) { if (!isUrl(url)) { throw invalidArgument('refFromURL() expected a full URL but got a child path, use ref() instead.'); } try { Location.makeFromUrl(url); } catch (e) { throw invalidArgument('refFromUrl() expected a valid full URL but got an invalid one.'); } return new ReferenceCompat(ref$1(this._delegate, url), this); }; StorageServiceCompat.prototype.setMaxUploadRetryTime = function (time) { this._delegate.maxUploadRetryTime = time; }; StorageServiceCompat.prototype.setMaxOperationRetryTime = function (time) { this._delegate.maxOperationRetryTime = time; }; return StorageServiceCompat; }()); var name = "@firebase/storage"; var version = "0.4.5"; /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Type constant for Firebase Storage. */ var STORAGE_TYPE = 'storage'; function factory(container, _a) { var url = _a.instanceIdentifier; // Dependencies // TODO: This should eventually be 'app-compat' var app = container.getProvider('app').getImmediate(); var authProvider = container.getProvider('auth-internal'); // TODO: get StorageService instance from component framework instead // of creating a new one. var storageServiceCompat = new StorageServiceCompat(app, new StorageService(app, authProvider, new XhrIoPool(), url, __WEBPACK_IMPORTED_MODULE_0__firebase_app__["a" /* default */].SDK_VERSION)); return storageServiceCompat; } function registerStorage(instance) { var namespaceExports = { // no-inline TaskState: TaskState, TaskEvent: TaskEvent, StringFormat: StringFormat, Storage: StorageService, Reference: ReferenceCompat }; instance.INTERNAL.registerComponent(new __WEBPACK_IMPORTED_MODULE_3__firebase_component__["a" /* Component */](STORAGE_TYPE, factory, "PUBLIC" /* PUBLIC */) .setServiceProps(namespaceExports) .setMultipleInstances(true)); instance.registerVersion(name, version); } registerStorage(__WEBPACK_IMPORTED_MODULE_0__firebase_app__["a" /* default */]); //# sourceMappingURL=index.esm.js.map /***/ }), /***/ 6152: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["c"] = __extends; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __assign; }); /* unused harmony export __rest */ /* unused harmony export __decorate */ /* unused harmony export __param */ /* unused harmony export __metadata */ /* harmony export (immutable) */ __webpack_exports__["b"] = __awaiter; /* harmony export (immutable) */ __webpack_exports__["d"] = __generator; /* unused harmony export __createBinding */ /* unused harmony export __exportStar */ /* unused harmony export __values */ /* unused harmony export __read */ /* unused harmony export __spread */ /* unused harmony export __spreadArrays */ /* harmony export (immutable) */ __webpack_exports__["e"] = __spreadArray; /* unused harmony export __await */ /* unused harmony export __asyncGenerator */ /* unused harmony export __asyncDelegator */ /* unused harmony export __asyncValues */ /* unused harmony export __makeTemplateObject */ /* unused harmony export __importStar */ /* unused harmony export __importDefault */ /* unused harmony export __classPrivateFieldGet */ /* unused harmony export __classPrivateFieldSet */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; } return __assign.apply(this, arguments); } function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /***/ }), /***/ 6153: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export registerPerformance */ /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__firebase_app__ = __webpack_require__(50); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__firebase_installations__ = __webpack_require__(198); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_tslib__ = __webpack_require__(6154); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__firebase_util__ = __webpack_require__(56); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__firebase_logger__ = __webpack_require__(89); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__firebase_component__ = __webpack_require__(74); var name = "@firebase/performance"; var version = "0.4.8"; /** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var SDK_VERSION = version; /** The prefix for start User Timing marks used for creating Traces. */ var TRACE_START_MARK_PREFIX = 'FB-PERF-TRACE-START'; /** The prefix for stop User Timing marks used for creating Traces. */ var TRACE_STOP_MARK_PREFIX = 'FB-PERF-TRACE-STOP'; /** The prefix for User Timing measure used for creating Traces. */ var TRACE_MEASURE_PREFIX = 'FB-PERF-TRACE-MEASURE'; /** The prefix for out of the box page load Trace name. */ var OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_'; var FIRST_PAINT_COUNTER_NAME = '_fp'; var FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp'; var FIRST_INPUT_DELAY_COUNTER_NAME = '_fid'; var CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config'; var CONFIG_EXPIRY_LOCAL_STORAGE_KEY = '@firebase/performance/configexpire'; var SERVICE = 'performance'; var SERVICE_NAME = 'Performance'; /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var _a; var ERROR_DESCRIPTION_MAP = (_a = {}, _a["trace started" /* TRACE_STARTED_BEFORE */] = 'Trace {$traceName} was started before.', _a["trace stopped" /* TRACE_STOPPED_BEFORE */] = 'Trace {$traceName} is not running.', _a["nonpositive trace startTime" /* NONPOSITIVE_TRACE_START_TIME */] = 'Trace {$traceName} startTime should be positive.', _a["nonpositive trace duration" /* NONPOSITIVE_TRACE_DURATION */] = 'Trace {$traceName} duration should be positive.', _a["no window" /* NO_WINDOW */] = 'Window is not available.', _a["no app id" /* NO_APP_ID */] = 'App id is not available.', _a["no project id" /* NO_PROJECT_ID */] = 'Project id is not available.', _a["no api key" /* NO_API_KEY */] = 'Api key is not available.', _a["invalid cc log" /* INVALID_CC_LOG */] = 'Attempted to queue invalid cc event', _a["FB not default" /* FB_NOT_DEFAULT */] = 'Performance can only start when Firebase app instance is the default one.', _a["RC response not ok" /* RC_NOT_OK */] = 'RC response is not ok', _a["invalid attribute name" /* INVALID_ATTRIBUTE_NAME */] = 'Attribute name {$attributeName} is invalid.', _a["invalid attribute value" /* INVALID_ATTRIBUTE_VALUE */] = 'Attribute value {$attributeValue} is invalid.', _a["invalid custom metric name" /* INVALID_CUSTOM_METRIC_NAME */] = 'Custom metric name {$customMetricName} is invalid', _a["invalid String merger input" /* INVALID_STRING_MERGER_PARAMETER */] = 'Input for String merger is invalid, contact support team to resolve.', _a); var ERROR_FACTORY = new __WEBPACK_IMPORTED_MODULE_3__firebase_util__["b" /* ErrorFactory */](SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var consoleLogger = new __WEBPACK_IMPORTED_MODULE_4__firebase_logger__["b" /* Logger */](SERVICE_NAME); consoleLogger.logLevel = __WEBPACK_IMPORTED_MODULE_4__firebase_logger__["a" /* LogLevel */].INFO; /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var apiInstance; var windowInstance; /** * This class holds a reference to various browser related objects injected by * set methods. */ var Api = /** @class */ (function () { function Api(window) { this.window = window; if (!window) { throw ERROR_FACTORY.create("no window" /* NO_WINDOW */); } this.performance = window.performance; this.PerformanceObserver = window.PerformanceObserver; this.windowLocation = window.location; this.navigator = window.navigator; this.document = window.document; if (this.navigator && this.navigator.cookieEnabled) { // If user blocks cookies on the browser, accessing localStorage will // throw an exception. this.localStorage = window.localStorage; } if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) { this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay; } } Api.prototype.getUrl = function () { // Do not capture the string query part of url. return this.windowLocation.href.split('?')[0]; }; Api.prototype.mark = function (name) { if (!this.performance || !this.performance.mark) { return; } this.performance.mark(name); }; Api.prototype.measure = function (measureName, mark1, mark2) { if (!this.performance || !this.performance.measure) { return; } this.performance.measure(measureName, mark1, mark2); }; Api.prototype.getEntriesByType = function (type) { if (!this.performance || !this.performance.getEntriesByType) { return []; } return this.performance.getEntriesByType(type); }; Api.prototype.getEntriesByName = function (name) { if (!this.performance || !this.performance.getEntriesByName) { return []; } return this.performance.getEntriesByName(name); }; Api.prototype.getTimeOrigin = function () { // Polyfill the time origin with performance.timing.navigationStart. return (this.performance && (this.performance.timeOrigin || this.performance.timing.navigationStart)); }; Api.prototype.requiredApisAvailable = function () { if (!fetch || !Promise || !this.navigator || !this.navigator.cookieEnabled) { consoleLogger.info('Firebase Performance cannot start if browser does not support fetch and Promise or cookie is disabled.'); return false; } if (!Object(__WEBPACK_IMPORTED_MODULE_3__firebase_util__["w" /* isIndexedDBAvailable */])()) { consoleLogger.info('IndexedDB is not supported by current browswer'); return false; } return true; }; Api.prototype.setupObserver = function (entryType, callback) { if (!this.PerformanceObserver) { return; } var observer = new this.PerformanceObserver(function (list) { for (var _i = 0, _a = list.getEntries(); _i < _a.length; _i++) { var entry = _a[_i]; // `entry` is a PerformanceEntry instance. callback(entry); } }); // Start observing the entry types you care about. observer.observe({ entryTypes: [entryType] }); }; Api.getInstance = function () { if (apiInstance === undefined) { apiInstance = new Api(windowInstance); } return apiInstance; }; return Api; }()); function setupApi(window) { windowInstance = window; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function mergeStrings(part1, part2) { var sizeDiff = part1.length - part2.length; if (sizeDiff < 0 || sizeDiff > 1) { throw ERROR_FACTORY.create("invalid String merger input" /* INVALID_STRING_MERGER_PARAMETER */); } var resultArray = []; for (var i = 0; i < part1.length; i++) { resultArray.push(part1.charAt(i)); if (part2.length > i) { resultArray.push(part2.charAt(i)); } } return resultArray.join(''); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var settingsServiceInstance; var SettingsService = /** @class */ (function () { function SettingsService() { // The variable which controls logging of automatic traces and HTTP/S network monitoring. this.instrumentationEnabled = true; // The variable which controls logging of custom traces. this.dataCollectionEnabled = true; // Configuration flags set through remote config. this.loggingEnabled = false; // Sampling rate between 0 and 1. this.tracesSamplingRate = 1; this.networkRequestsSamplingRate = 1; // Address of logging service. this.logEndPointUrl = 'https://firebaselogging.googleapis.com/v0cc/log?format=json_proto'; // Performance event transport endpoint URL which should be compatible with proto3. // New Address for transport service, not configurable via Remote Config. this.flTransportEndpointUrl = mergeStrings('hts/frbslgigp.ogepscmv/ieo/eaylg', 'tp:/ieaeogn-agolai.o/1frlglgc/o'); this.transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV'); // Source type for performance event logs. this.logSource = 462; // Flags which control per session logging of traces and network requests. this.logTraceAfterSampling = false; this.logNetworkAfterSampling = false; // TTL of config retrieved from remote config in hours. this.configTimeToLive = 12; } SettingsService.prototype.getAppId = function () { var appId = this.firebaseAppInstance && this.firebaseAppInstance.options && this.firebaseAppInstance.options.appId; if (!appId) { throw ERROR_FACTORY.create("no app id" /* NO_APP_ID */); } return appId; }; SettingsService.prototype.getProjectId = function () { var projectId = this.firebaseAppInstance && this.firebaseAppInstance.options && this.firebaseAppInstance.options.projectId; if (!projectId) { throw ERROR_FACTORY.create("no project id" /* NO_PROJECT_ID */); } return projectId; }; SettingsService.prototype.getApiKey = function () { var apiKey = this.firebaseAppInstance && this.firebaseAppInstance.options && this.firebaseAppInstance.options.apiKey; if (!apiKey) { throw ERROR_FACTORY.create("no api key" /* NO_API_KEY */); } return apiKey; }; SettingsService.prototype.getFlTransportFullUrl = function () { return this.flTransportEndpointUrl.concat('?key=', this.transportKey); }; SettingsService.getInstance = function () { if (settingsServiceInstance === undefined) { settingsServiceInstance = new SettingsService(); } return settingsServiceInstance; }; return SettingsService; }()); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var iid; function getIidPromise() { var iidPromise = SettingsService.getInstance().installationsService.getId(); // eslint-disable-next-line @typescript-eslint/no-floating-promises iidPromise.then(function (iidVal) { iid = iidVal; }); return iidPromise; } // This method should be used after the iid is retrieved by getIidPromise method. function getIid() { return iid; } function getAuthTokenPromise() { var authTokenPromise = SettingsService.getInstance().installationsService.getToken(); // eslint-disable-next-line @typescript-eslint/no-floating-promises authTokenPromise.then(function (authTokenVal) { }); return authTokenPromise; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var VisibilityState; (function (VisibilityState) { VisibilityState[VisibilityState["UNKNOWN"] = 0] = "UNKNOWN"; VisibilityState[VisibilityState["VISIBLE"] = 1] = "VISIBLE"; VisibilityState[VisibilityState["HIDDEN"] = 2] = "HIDDEN"; })(VisibilityState || (VisibilityState = {})); var RESERVED_ATTRIBUTE_PREFIXES = ['firebase_', 'google_', 'ga_']; var ATTRIBUTE_FORMAT_REGEX = new RegExp('^[a-zA-Z]\\w*$'); var MAX_ATTRIBUTE_NAME_LENGTH = 40; var MAX_ATTRIBUTE_VALUE_LENGTH = 100; function getServiceWorkerStatus() { var navigator = Api.getInstance().navigator; if ('serviceWorker' in navigator) { if (navigator.serviceWorker.controller) { return 2 /* CONTROLLED */; } else { return 3 /* UNCONTROLLED */; } } else { return 1 /* UNSUPPORTED */; } } function getVisibilityState() { var document = Api.getInstance().document; var visibilityState = document.visibilityState; switch (visibilityState) { case 'visible': return VisibilityState.VISIBLE; case 'hidden': return VisibilityState.HIDDEN; default: return VisibilityState.UNKNOWN; } } function getEffectiveConnectionType() { var navigator = Api.getInstance().navigator; var navigatorConnection = navigator.connection; var effectiveType = navigatorConnection && navigatorConnection.effectiveType; switch (effectiveType) { case 'slow-2g': return 1 /* CONNECTION_SLOW_2G */; case '2g': return 2 /* CONNECTION_2G */; case '3g': return 3 /* CONNECTION_3G */; case '4g': return 4 /* CONNECTION_4G */; default: return 0 /* UNKNOWN */; } } function isValidCustomAttributeName(name) { if (name.length === 0 || name.length > MAX_ATTRIBUTE_NAME_LENGTH) { return false; } var matchesReservedPrefix = RESERVED_ATTRIBUTE_PREFIXES.some(function (prefix) { return name.startsWith(prefix); }); return !matchesReservedPrefix && !!name.match(ATTRIBUTE_FORMAT_REGEX); } function isValidCustomAttributeValue(value) { return value.length !== 0 && value.length <= MAX_ATTRIBUTE_VALUE_LENGTH; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var REMOTE_CONFIG_SDK_VERSION = '0.0.1'; // These values will be used if the remote config object is successfully // retrieved, but the template does not have these fields. var DEFAULT_CONFIGS = { loggingEnabled: true }; var FIS_AUTH_PREFIX = 'FIREBASE_INSTALLATIONS_AUTH'; function getConfig(iid) { var config = getStoredConfig(); if (config) { processConfig(config); return Promise.resolve(); } return getRemoteConfig(iid) .then(processConfig) .then(function (config) { return storeConfig(config); }, /** Do nothing for error, use defaults set in settings service. */ function () { }); } function getStoredConfig() { var localStorage = Api.getInstance().localStorage; if (!localStorage) { return; } var expiryString = localStorage.getItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY); if (!expiryString || !configValid(expiryString)) { return; } var configStringified = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY); if (!configStringified) { return; } try { var configResponse = JSON.parse(configStringified); return configResponse; } catch (_a) { return; } } function storeConfig(config) { var localStorage = Api.getInstance().localStorage; if (!config || !localStorage) { return; } localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config)); localStorage.setItem(CONFIG_EXPIRY_LOCAL_STORAGE_KEY, String(Date.now() + SettingsService.getInstance().configTimeToLive * 60 * 60 * 1000)); } var COULD_NOT_GET_CONFIG_MSG = 'Could not fetch config, will use default configs'; function getRemoteConfig(iid) { // Perf needs auth token only to retrieve remote config. return getAuthTokenPromise() .then(function (authToken) { var projectId = SettingsService.getInstance().getProjectId(); var configEndPoint = "https://firebaseremoteconfig.googleapis.com/v1/projects/" + projectId + "/namespaces/fireperf:fetch?key=" + SettingsService.getInstance().getApiKey(); var request = new Request(configEndPoint, { method: 'POST', headers: { Authorization: FIS_AUTH_PREFIX + " " + authToken }, /* eslint-disable camelcase */ body: JSON.stringify({ app_instance_id: iid, app_instance_id_token: authToken, app_id: SettingsService.getInstance().getAppId(), app_version: SDK_VERSION, sdk_version: REMOTE_CONFIG_SDK_VERSION }) /* eslint-enable camelcase */ }); return fetch(request).then(function (response) { if (response.ok) { return response.json(); } // In case response is not ok. This will be caught by catch. throw ERROR_FACTORY.create("RC response not ok" /* RC_NOT_OK */); }); }) .catch(function () { consoleLogger.info(COULD_NOT_GET_CONFIG_MSG); return undefined; }); } /** * Processes config coming either from calling RC or from local storage. * This method only runs if call is successful or config in storage * is valid. */ function processConfig(config) { if (!config) { return config; } var settingsServiceInstance = SettingsService.getInstance(); var entries = config.entries || {}; if (entries.fpr_enabled !== undefined) { // TODO: Change the assignment of loggingEnabled once the received type is // known. settingsServiceInstance.loggingEnabled = String(entries.fpr_enabled) === 'true'; } else { // Config retrieved successfully, but there is no fpr_enabled in template. // Use secondary configs value. settingsServiceInstance.loggingEnabled = DEFAULT_CONFIGS.loggingEnabled; } if (entries.fpr_log_source) { settingsServiceInstance.logSource = Number(entries.fpr_log_source); } if (entries.fpr_log_endpoint_url) { settingsServiceInstance.logEndPointUrl = entries.fpr_log_endpoint_url; } // Key from Remote Config has to be non-empty string, otherwsie use local value. if (entries.fpr_log_transport_key) { settingsServiceInstance.transportKey = entries.fpr_log_transport_key; } if (entries.fpr_vc_network_request_sampling_rate !== undefined) { settingsServiceInstance.networkRequestsSamplingRate = Number(entries.fpr_vc_network_request_sampling_rate); } if (entries.fpr_vc_trace_sampling_rate !== undefined) { settingsServiceInstance.tracesSamplingRate = Number(entries.fpr_vc_trace_sampling_rate); } // Set the per session trace and network logging flags. settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(settingsServiceInstance.tracesSamplingRate); settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(settingsServiceInstance.networkRequestsSamplingRate); return config; } function configValid(expiry) { return Number(expiry) > Date.now(); } function shouldLogAfterSampling(samplingRate) { return Math.random() <= samplingRate; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var initializationStatus = 1 /* notInitialized */; var initializationPromise; function getInitializationPromise() { initializationStatus = 2 /* initializationPending */; initializationPromise = initializationPromise || initializePerf(); return initializationPromise; } function isPerfInitialized() { return initializationStatus === 3 /* initialized */; } function initializePerf() { return getDocumentReadyComplete() .then(function () { return getIidPromise(); }) .then(function (iid) { return getConfig(iid); }) .then(function () { return changeInitializationStatus(); }, function () { return changeInitializationStatus(); }); } /** * Returns a promise which resolves whenever the document readystate is complete or * immediately if it is called after page load complete. */ function getDocumentReadyComplete() { var document = Api.getInstance().document; return new Promise(function (resolve) { if (document && document.readyState !== 'complete') { var handler_1 = function () { if (document.readyState === 'complete') { document.removeEventListener('readystatechange', handler_1); resolve(); } }; document.addEventListener('readystatechange', handler_1); } else { resolve(); } }); } function changeInitializationStatus() { initializationStatus = 3 /* initialized */; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var DEFAULT_SEND_INTERVAL_MS = 10 * 1000; var INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000; // If end point does not work, the call will be tried for these many times. var DEFAULT_REMAINING_TRIES = 3; var MAX_EVENT_COUNT_PER_REQUEST = 1000; var remainingTries = DEFAULT_REMAINING_TRIES; /* eslint-enable camelcase */ var queue = []; var isTransportSetup = false; function setupTransportService() { if (!isTransportSetup) { processQueue(INITIAL_SEND_TIME_DELAY_MS); isTransportSetup = true; } } function processQueue(timeOffset) { setTimeout(function () { // If there is no remainingTries left, stop retrying. if (remainingTries === 0) { return; } // If there are no events to process, wait for DEFAULT_SEND_INTERVAL_MS and try again. if (!queue.length) { return processQueue(DEFAULT_SEND_INTERVAL_MS); } dispatchQueueEvents(); }, timeOffset); } function dispatchQueueEvents() { // Extract events up to the maximum cap of single logRequest from top of "official queue". // The staged events will be used for current logRequest attempt, remaining events will be kept // for next attempt. var staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST); /* eslint-disable camelcase */ // We will pass the JSON serialized event to the backend. var log_event = staged.map(function (evt) { return ({ source_extension_json_proto3: evt.message, event_time_ms: String(evt.eventTime) }); }); var data = { request_time_ms: String(Date.now()), client_info: { client_type: 1, js_client_info: {} }, log_source: SettingsService.getInstance().logSource, log_event: log_event }; /* eslint-enable camelcase */ sendEventsToFl(data, staged).catch(function () { // If the request fails for some reason, add the events that were attempted // back to the primary queue to retry later. queue = Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["b" /* __spreadArray */])(Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["b" /* __spreadArray */])([], staged), queue); remainingTries--; consoleLogger.info("Tries left: " + remainingTries + "."); processQueue(DEFAULT_SEND_INTERVAL_MS); }); } function sendEventsToFl(data, staged) { return postToFlEndpoint(data) .then(function (res) { if (!res.ok) { consoleLogger.info('Call to Firebase backend failed.'); } return res.json(); }) .then(function (res) { // Find the next call wait time from the response. var transportWait = Number(res.nextRequestWaitMillis); var requestOffset = DEFAULT_SEND_INTERVAL_MS; if (!isNaN(transportWait)) { requestOffset = Math.max(transportWait, requestOffset); } // Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action. // Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER. var logResponseDetails = res.logResponseDetails; if (Array.isArray(logResponseDetails) && logResponseDetails.length > 0 && logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER') { queue = Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["b" /* __spreadArray */])(Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["b" /* __spreadArray */])([], staged), queue); consoleLogger.info("Retry transport request later."); } remainingTries = DEFAULT_REMAINING_TRIES; // Schedule the next process. processQueue(requestOffset); }); } function postToFlEndpoint(data) { var flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl(); return fetch(flTransportFullUrl, { method: 'POST', body: JSON.stringify(data) }); } function addToQueue(evt) { if (!evt.eventTime || !evt.message) { throw ERROR_FACTORY.create("invalid cc log" /* INVALID_CC_LOG */); } // Add the new event to the queue. queue = Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["b" /* __spreadArray */])(Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["b" /* __spreadArray */])([], queue), [evt]); } /** Log handler for cc service to send the performance logs to the server. */ function transportHandler( // eslint-disable-next-line @typescript-eslint/no-explicit-any serializer) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var message = serializer.apply(void 0, args); addToQueue({ message: message, eventTime: Date.now() }); }; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* eslint-enble camelcase */ var logger; // This method is not called before initialization. function sendLog(resource, resourceType) { if (!logger) { logger = transportHandler(serializer); } logger(resource, resourceType); } function logTrace(trace) { var settingsService = SettingsService.getInstance(); // Do not log if trace is auto generated and instrumentation is disabled. if (!settingsService.instrumentationEnabled && trace.isAuto) { return; } // Do not log if trace is custom and data collection is disabled. if (!settingsService.dataCollectionEnabled && !trace.isAuto) { return; } // Do not log if required apis are not available. if (!Api.getInstance().requiredApisAvailable()) { return; } // Only log the page load auto traces if page is visible. if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) { return; } if (isPerfInitialized()) { sendTraceLog(trace); } else { // Custom traces can be used before the initialization but logging // should wait until after. getInitializationPromise().then(function () { return sendTraceLog(trace); }, function () { return sendTraceLog(trace); }); } } function sendTraceLog(trace) { if (!getIid()) { return; } var settingsService = SettingsService.getInstance(); if (!settingsService.loggingEnabled || !settingsService.logTraceAfterSampling) { return; } setTimeout(function () { return sendLog(trace, 1 /* Trace */); }, 0); } function logNetworkRequest(networkRequest) { var settingsService = SettingsService.getInstance(); // Do not log network requests if instrumentation is disabled. if (!settingsService.instrumentationEnabled) { return; } // Do not log the js sdk's call to transport service domain to avoid unnecessary cycle. // Need to blacklist both old and new endpoints to avoid migration gap. var networkRequestUrl = networkRequest.url; // Blacklist old log endpoint and new transport endpoint. // Because Performance SDK doesn't instrument requests sent from SDK itself. var logEndpointUrl = settingsService.logEndPointUrl.split('?')[0]; var flEndpointUrl = settingsService.flTransportEndpointUrl.split('?')[0]; if (networkRequestUrl === logEndpointUrl || networkRequestUrl === flEndpointUrl) { return; } if (!settingsService.loggingEnabled || !settingsService.logNetworkAfterSampling) { return; } setTimeout(function () { return sendLog(networkRequest, 0 /* NetworkRequest */); }, 0); } function serializer(resource, resourceType) { if (resourceType === 0 /* NetworkRequest */) { return serializeNetworkRequest(resource); } return serializeTrace(resource); } function serializeNetworkRequest(networkRequest) { var networkRequestMetric = { url: networkRequest.url, http_method: networkRequest.httpMethod || 0, http_response_code: 200, response_payload_bytes: networkRequest.responsePayloadBytes, client_start_time_us: networkRequest.startTimeUs, time_to_response_initiated_us: networkRequest.timeToResponseInitiatedUs, time_to_response_completed_us: networkRequest.timeToResponseCompletedUs }; var perfMetric = { application_info: getApplicationInfo(), network_request_metric: networkRequestMetric }; return JSON.stringify(perfMetric); } function serializeTrace(trace) { var traceMetric = { name: trace.name, is_auto: trace.isAuto, client_start_time_us: trace.startTimeUs, duration_us: trace.durationUs }; if (Object.keys(trace.counters).length !== 0) { traceMetric.counters = trace.counters; } var customAttributes = trace.getAttributes(); if (Object.keys(customAttributes).length !== 0) { traceMetric.custom_attributes = customAttributes; } var perfMetric = { application_info: getApplicationInfo(), trace_metric: traceMetric }; return JSON.stringify(perfMetric); } function getApplicationInfo() { return { google_app_id: SettingsService.getInstance().getAppId(), app_instance_id: getIid(), web_app_info: { sdk_version: SDK_VERSION, page_url: Api.getInstance().getUrl(), service_worker_status: getServiceWorkerStatus(), visibility_state: getVisibilityState(), effective_connection_type: getEffectiveConnectionType() }, application_process_state: 0 }; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var MAX_METRIC_NAME_LENGTH = 100; var RESERVED_AUTO_PREFIX = '_'; var oobMetrics = [ FIRST_PAINT_COUNTER_NAME, FIRST_CONTENTFUL_PAINT_COUNTER_NAME, FIRST_INPUT_DELAY_COUNTER_NAME ]; /** * Returns true if the metric is custom and does not start with reserved prefix, or if * the metric is one of out of the box page load trace metrics. */ function isValidMetricName(name, traceName) { if (name.length === 0 || name.length > MAX_METRIC_NAME_LENGTH) { return false; } return ((traceName && traceName.startsWith(OOB_TRACE_PAGE_LOAD_PREFIX) && oobMetrics.indexOf(name) > -1) || !name.startsWith(RESERVED_AUTO_PREFIX)); } /** * Converts the provided value to an integer value to be used in case of a metric. * @param providedValue Provided number value of the metric that needs to be converted to an integer. * * @returns Converted integer number to be set for the metric. */ function convertMetricValueToInteger(providedValue) { var valueAsInteger = Math.floor(providedValue); if (valueAsInteger < providedValue) { consoleLogger.info("Metric value should be an Integer, setting the value as : " + valueAsInteger + "."); } return valueAsInteger; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Trace = /** @class */ (function () { /** * @param name The name of the trace. * @param isAuto If the trace is auto-instrumented. * @param traceMeasureName The name of the measure marker in user timing specification. This field * is only set when the trace is built for logging when the user directly uses the user timing * api (performance.mark and performance.measure). */ function Trace(name, isAuto, traceMeasureName) { if (isAuto === void 0) { isAuto = false; } this.name = name; this.isAuto = isAuto; this.state = 1 /* UNINITIALIZED */; this.customAttributes = {}; this.counters = {}; this.api = Api.getInstance(); this.randomId = Math.floor(Math.random() * 1000000); if (!this.isAuto) { this.traceStartMark = TRACE_START_MARK_PREFIX + "-" + this.randomId + "-" + this.name; this.traceStopMark = TRACE_STOP_MARK_PREFIX + "-" + this.randomId + "-" + this.name; this.traceMeasure = traceMeasureName || TRACE_MEASURE_PREFIX + "-" + this.randomId + "-" + this.name; if (traceMeasureName) { // For the case of direct user timing traces, no start stop will happen. The measure object // is already available. this.calculateTraceMetrics(); } } } /** * Starts a trace. The measurement of the duration starts at this point. */ Trace.prototype.start = function () { if (this.state !== 1 /* UNINITIALIZED */) { throw ERROR_FACTORY.create("trace started" /* TRACE_STARTED_BEFORE */, { traceName: this.name }); } this.api.mark(this.traceStartMark); this.state = 2 /* RUNNING */; }; /** * Stops the trace. The measurement of the duration of the trace stops at this point and trace * is logged. */ Trace.prototype.stop = function () { if (this.state !== 2 /* RUNNING */) { throw ERROR_FACTORY.create("trace stopped" /* TRACE_STOPPED_BEFORE */, { traceName: this.name }); } this.state = 3 /* TERMINATED */; this.api.mark(this.traceStopMark); this.api.measure(this.traceMeasure, this.traceStartMark, this.traceStopMark); this.calculateTraceMetrics(); logTrace(this); }; /** * Records a trace with predetermined values. If this method is used a trace is created and logged * directly. No need to use start and stop methods. * @param startTime Trace start time since epoch in millisec * @param duration The duraction of the trace in millisec * @param options An object which can optionally hold maps of custom metrics and custom attributes */ Trace.prototype.record = function (startTime, duration, options) { if (startTime <= 0) { throw ERROR_FACTORY.create("nonpositive trace startTime" /* NONPOSITIVE_TRACE_START_TIME */, { traceName: this.name }); } if (duration <= 0) { throw ERROR_FACTORY.create("nonpositive trace duration" /* NONPOSITIVE_TRACE_DURATION */, { traceName: this.name }); } this.durationUs = Math.floor(duration * 1000); this.startTimeUs = Math.floor(startTime * 1000); if (options && options.attributes) { this.customAttributes = Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["a" /* __assign */])({}, options.attributes); } if (options && options.metrics) { for (var _i = 0, _a = Object.keys(options.metrics); _i < _a.length; _i++) { var metric = _a[_i]; if (!isNaN(Number(options.metrics[metric]))) { this.counters[metric] = Number(Math.floor(options.metrics[metric])); } } } logTrace(this); }; /** * Increments a custom metric by a certain number or 1 if number not specified. Will create a new * custom metric if one with the given name does not exist. The value will be floored down to an * integer. * @param counter Name of the custom metric * @param numAsInteger Increment by value */ Trace.prototype.incrementMetric = function (counter, numAsInteger) { if (numAsInteger === void 0) { numAsInteger = 1; } if (this.counters[counter] === undefined) { this.putMetric(counter, numAsInteger); } else { this.putMetric(counter, this.counters[counter] + numAsInteger); } }; /** * Sets a custom metric to a specified value. Will create a new custom metric if one with the * given name does not exist. The value will be floored down to an integer. * @param counter Name of the custom metric * @param numAsInteger Set custom metric to this value */ Trace.prototype.putMetric = function (counter, numAsInteger) { if (isValidMetricName(counter, this.name)) { this.counters[counter] = convertMetricValueToInteger(numAsInteger); } else { throw ERROR_FACTORY.create("invalid custom metric name" /* INVALID_CUSTOM_METRIC_NAME */, { customMetricName: counter }); } }; /** * Returns the value of the custom metric by that name. If a custom metric with that name does * not exist will return zero. * @param counter */ Trace.prototype.getMetric = function (counter) { return this.counters[counter] || 0; }; /** * Sets a custom attribute of a trace to a certain value. * @param attr * @param value */ Trace.prototype.putAttribute = function (attr, value) { var isValidName = isValidCustomAttributeName(attr); var isValidValue = isValidCustomAttributeValue(value); if (isValidName && isValidValue) { this.customAttributes[attr] = value; return; } // Throw appropriate error when the attribute name or value is invalid. if (!isValidName) { throw ERROR_FACTORY.create("invalid attribute name" /* INVALID_ATTRIBUTE_NAME */, { attributeName: attr }); } if (!isValidValue) { throw ERROR_FACTORY.create("invalid attribute value" /* INVALID_ATTRIBUTE_VALUE */, { attributeValue: value }); } }; /** * Retrieves the value a custom attribute of a trace is set to. * @param attr */ Trace.prototype.getAttribute = function (attr) { return this.customAttributes[attr]; }; Trace.prototype.removeAttribute = function (attr) { if (this.customAttributes[attr] === undefined) { return; } delete this.customAttributes[attr]; }; Trace.prototype.getAttributes = function () { return Object(__WEBPACK_IMPORTED_MODULE_2_tslib__["a" /* __assign */])({}, this.customAttributes); }; Trace.prototype.setStartTime = function (startTime) { this.startTimeUs = startTime; }; Trace.prototype.setDuration = function (duration) { this.durationUs = duration; }; /** * Calculates and assigns the duration and start time of the trace using the measure performance * entry. */ Trace.prototype.calculateTraceMetrics = function () { var perfMeasureEntries = this.api.getEntriesByName(this.traceMeasure); var perfMeasureEntry = perfMeasureEntries && perfMeasureEntries[0]; if (perfMeasureEntry) { this.durationUs = Math.floor(perfMeasureEntry.duration * 1000); this.startTimeUs = Math.floor((perfMeasureEntry.startTime + this.api.getTimeOrigin()) * 1000); } }; /** * @param navigationTimings A single element array which contains the navigationTIming object of * the page load * @param paintTimings A array which contains paintTiming object of the page load * @param firstInputDelay First input delay in millisec */ Trace.createOobTrace = function (navigationTimings, paintTimings, firstInputDelay) { var route = Api.getInstance().getUrl(); if (!route) { return; } var trace = new Trace(OOB_TRACE_PAGE_LOAD_PREFIX + route, true); var timeOriginUs = Math.floor(Api.getInstance().getTimeOrigin() * 1000); trace.setStartTime(timeOriginUs); // navigationTimings includes only one element. if (navigationTimings && navigationTimings[0]) { trace.setDuration(Math.floor(navigationTimings[0].duration * 1000)); trace.putMetric('domInteractive', Math.floor(navigationTimings[0].domInteractive * 1000)); trace.putMetric('domContentLoadedEventEnd', Math.floor(navigationTimings[0].domContentLoadedEventEnd * 1000)); trace.putMetric('loadEventEnd', Math.floor(navigationTimings[0].loadEventEnd * 1000)); } var FIRST_PAINT = 'first-paint'; var FIRST_CONTENTFUL_PAINT = 'first-contentful-paint'; if (paintTimings) { var firstPaint = paintTimings.find(function (paintObject) { return paintObject.name === FIRST_PAINT; }); if (firstPaint && firstPaint.startTime) { trace.putMetric(FIRST_PAINT_COUNTER_NAME, Math.floor(firstPaint.startTime * 1000)); } var firstContentfulPaint = paintTimings.find(function (paintObject) { return paintObject.name === FIRST_CONTENTFUL_PAINT; }); if (firstContentfulPaint && firstContentfulPaint.startTime) { trace.putMetric(FIRST_CONTENTFUL_PAINT_COUNTER_NAME, Math.floor(firstContentfulPaint.startTime * 1000)); } if (firstInputDelay) { trace.putMetric(FIRST_INPUT_DELAY_COUNTER_NAME, Math.floor(firstInputDelay * 1000)); } } logTrace(trace); }; Trace.createUserTimingTrace = function (measureName) { var trace = new Trace(measureName, false, measureName); logTrace(trace); }; return Trace; }()); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function createNetworkRequestEntry(entry) { var performanceEntry = entry; if (!performanceEntry || performanceEntry.responseStart === undefined) { return; } var timeOrigin = Api.getInstance().getTimeOrigin(); var startTimeUs = Math.floor((performanceEntry.startTime + timeOrigin) * 1000); var timeToResponseInitiatedUs = performanceEntry.responseStart ? Math.floor((performanceEntry.responseStart - performanceEntry.startTime) * 1000) : undefined; var timeToResponseCompletedUs = Math.floor((performanceEntry.responseEnd - performanceEntry.startTime) * 1000); // Remove the query params from logged network request url. var url = performanceEntry.name && performanceEntry.name.split('?')[0]; var networkRequest = { url: url, responsePayloadBytes: performanceEntry.transferSize, startTimeUs: startTimeUs, timeToResponseInitiatedUs: timeToResponseInitiatedUs, timeToResponseCompletedUs: timeToResponseCompletedUs }; logNetworkRequest(networkRequest); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var FID_WAIT_TIME_MS = 5000; function setupOobResources() { // Do not initialize unless iid is available. if (!getIid()) { return; } // The load event might not have fired yet, and that means performance navigation timing // object has a duration of 0. The setup should run after all current tasks in js queue. setTimeout(function () { return setupOobTraces(); }, 0); setTimeout(function () { return setupNetworkRequests(); }, 0); setTimeout(function () { return setupUserTimingTraces(); }, 0); } function setupNetworkRequests() { var api = Api.getInstance(); var resources = api.getEntriesByType('resource'); for (var _i = 0, resources_1 = resources; _i < resources_1.length; _i++) { var resource = resources_1[_i]; createNetworkRequestEntry(resource); } api.setupObserver('resource', createNetworkRequestEntry); } function setupOobTraces() { var api = Api.getInstance(); var navigationTimings = api.getEntriesByType('navigation'); var paintTimings = api.getEntriesByType('paint'); // If First Input Desly polyfill is added to the page, report the fid value. // https://github.com/GoogleChromeLabs/first-input-delay if (api.onFirstInputDelay) { // If the fid call back is not called for certain time, continue without it. // eslint-disable-next-line @typescript-eslint/no-explicit-any var timeoutId_1 = setTimeout(function () { Trace.createOobTrace(navigationTimings, paintTimings); timeoutId_1 = undefined; }, FID_WAIT_TIME_MS); api.onFirstInputDelay(function (fid) { if (timeoutId_1) { clearTimeout(timeoutId_1); Trace.createOobTrace(navigationTimings, paintTimings, fid); } }); } else { Trace.createOobTrace(navigationTimings, paintTimings); } } function setupUserTimingTraces() { var api = Api.getInstance(); // Run through the measure performance entries collected up to this point. var measures = api.getEntriesByType('measure'); for (var _i = 0, measures_1 = measures; _i < measures_1.length; _i++) { var measure = measures_1[_i]; createUserTimingTrace(measure); } // Setup an observer to capture the measures from this point on. api.setupObserver('measure', createUserTimingTrace); } function createUserTimingTrace(measure) { var measureName = measure.name; // Do not create a trace, if the user timing marks and measures are created by the sdk itself. if (measureName.substring(0, TRACE_MEASURE_PREFIX.length) === TRACE_MEASURE_PREFIX) { return; } Trace.createUserTimingTrace(measureName); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var PerformanceController = /** @class */ (function () { function PerformanceController(app) { this.app = app; if (Api.getInstance().requiredApisAvailable()) { Object(__WEBPACK_IMPORTED_MODULE_3__firebase_util__["N" /* validateIndexedDBOpenable */])() .then(function (isAvailable) { if (isAvailable) { setupTransportService(); getInitializationPromise().then(setupOobResources, setupOobResources); } }) .catch(function (error) { consoleLogger.info("Environment doesn't support IndexedDB: " + error); }); } } PerformanceController.prototype.trace = function (name) { return new Trace(name); }; Object.defineProperty(PerformanceController.prototype, "instrumentationEnabled", { get: function () { return SettingsService.getInstance().instrumentationEnabled; }, set: function (val) { SettingsService.getInstance().instrumentationEnabled = val; }, enumerable: false, configurable: true }); Object.defineProperty(PerformanceController.prototype, "dataCollectionEnabled", { get: function () { return SettingsService.getInstance().dataCollectionEnabled; }, set: function (val) { SettingsService.getInstance().dataCollectionEnabled = val; }, enumerable: false, configurable: true }); return PerformanceController; }()); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var DEFAULT_ENTRY_NAME = '[DEFAULT]'; function registerPerformance(instance) { var factoryMethod = function (app, installations) { if (app.name !== DEFAULT_ENTRY_NAME) { throw ERROR_FACTORY.create("FB not default" /* FB_NOT_DEFAULT */); } if (typeof window === 'undefined') { throw ERROR_FACTORY.create("no window" /* NO_WINDOW */); } setupApi(window); SettingsService.getInstance().firebaseAppInstance = app; SettingsService.getInstance().installationsService = installations; return new PerformanceController(app); }; // Register performance with firebase-app. instance.INTERNAL.registerComponent(new __WEBPACK_IMPORTED_MODULE_5__firebase_component__["a" /* Component */]('performance', function (container) { /* Dependencies */ // getImmediate for FirebaseApp will always succeed var app = container.getProvider('app').getImmediate(); // The following call will always succeed because perf has `import '@firebase/installations'` var installations = container .getProvider('installations') .getImmediate(); return factoryMethod(app, installations); }, "PUBLIC" /* PUBLIC */)); instance.registerVersion(name, version); } registerPerformance(__WEBPACK_IMPORTED_MODULE_0__firebase_app__["a" /* default */]); //# sourceMappingURL=index.esm.js.map /***/ }), /***/ 6154: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export __extends */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __assign; }); /* unused harmony export __rest */ /* unused harmony export __decorate */ /* unused harmony export __param */ /* unused harmony export __metadata */ /* unused harmony export __awaiter */ /* unused harmony export __generator */ /* unused harmony export __createBinding */ /* unused harmony export __exportStar */ /* unused harmony export __values */ /* unused harmony export __read */ /* unused harmony export __spread */ /* unused harmony export __spreadArrays */ /* harmony export (immutable) */ __webpack_exports__["b"] = __spreadArray; /* unused harmony export __await */ /* unused harmony export __asyncGenerator */ /* unused harmony export __asyncDelegator */ /* unused harmony export __asyncValues */ /* unused harmony export __makeTemplateObject */ /* unused harmony export __importStar */ /* unused harmony export __importDefault */ /* unused harmony export __classPrivateFieldGet */ /* unused harmony export __classPrivateFieldSet */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; } return __assign.apply(this, arguments); } function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /***/ }), /***/ 6155: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export factory */ /* unused harmony export getGlobalVars */ /* unused harmony export registerAnalytics */ /* unused harmony export resetGlobalVars */ /* unused harmony export settings */ /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(6156); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__firebase_app__ = __webpack_require__(50); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__firebase_installations__ = __webpack_require__(198); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__firebase_logger__ = __webpack_require__(89); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__firebase_util__ = __webpack_require__(56); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__firebase_component__ = __webpack_require__(74); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Key to attach FID to in gtag params. var GA_FID_KEY = 'firebase_id'; var ORIGIN_KEY = 'origin'; var FETCH_TIMEOUT_MILLIS = 60 * 1000; var DYNAMIC_CONFIG_URL = 'https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig'; var GTAG_URL = 'https://www.googletagmanager.com/gtag/js'; var GtagCommand; (function (GtagCommand) { GtagCommand["EVENT"] = "event"; GtagCommand["SET"] = "set"; GtagCommand["CONFIG"] = "config"; })(GtagCommand || (GtagCommand = {})); /** * Officially recommended event names for gtag.js * Any other string is also allowed. * * @public */ var EventName; (function (EventName) { EventName["ADD_SHIPPING_INFO"] = "add_shipping_info"; EventName["ADD_PAYMENT_INFO"] = "add_payment_info"; EventName["ADD_TO_CART"] = "add_to_cart"; EventName["ADD_TO_WISHLIST"] = "add_to_wishlist"; EventName["BEGIN_CHECKOUT"] = "begin_checkout"; /** * @deprecated * This event name is deprecated and is unsupported in updated * Enhanced Ecommerce reports. */ EventName["CHECKOUT_PROGRESS"] = "checkout_progress"; EventName["EXCEPTION"] = "exception"; EventName["GENERATE_LEAD"] = "generate_lead"; EventName["LOGIN"] = "login"; EventName["PAGE_VIEW"] = "page_view"; EventName["PURCHASE"] = "purchase"; EventName["REFUND"] = "refund"; EventName["REMOVE_FROM_CART"] = "remove_from_cart"; EventName["SCREEN_VIEW"] = "screen_view"; EventName["SEARCH"] = "search"; EventName["SELECT_CONTENT"] = "select_content"; EventName["SELECT_ITEM"] = "select_item"; EventName["SELECT_PROMOTION"] = "select_promotion"; /** @deprecated */ EventName["SET_CHECKOUT_OPTION"] = "set_checkout_option"; EventName["SHARE"] = "share"; EventName["SIGN_UP"] = "sign_up"; EventName["TIMING_COMPLETE"] = "timing_complete"; EventName["VIEW_CART"] = "view_cart"; EventName["VIEW_ITEM"] = "view_item"; EventName["VIEW_ITEM_LIST"] = "view_item_list"; EventName["VIEW_PROMOTION"] = "view_promotion"; EventName["VIEW_SEARCH_RESULTS"] = "view_search_results"; })(EventName || (EventName = {})); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Logs an analytics event through the Firebase SDK. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param eventName Google Analytics event name, choose from standard list or use a custom string. * @param eventParams Analytics event parameters. */ function logEvent(gtagFunction, initializationPromise, eventName, eventParams, options) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var measurementId, params; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!(options && options.global)) return [3 /*break*/, 1]; gtagFunction(GtagCommand.EVENT, eventName, eventParams); return [2 /*return*/]; case 1: return [4 /*yield*/, initializationPromise]; case 2: measurementId = _a.sent(); params = Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __assign */])(Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __assign */])({}, eventParams), { 'send_to': measurementId }); gtagFunction(GtagCommand.EVENT, eventName, params); _a.label = 3; case 3: return [2 /*return*/]; } }); }); } /** * Set screen_name parameter for this Google Analytics ID. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param screenName Screen name string to set. */ function setCurrentScreen(gtagFunction, initializationPromise, screenName, options) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var measurementId; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!(options && options.global)) return [3 /*break*/, 1]; gtagFunction(GtagCommand.SET, { 'screen_name': screenName }); return [2 /*return*/, Promise.resolve()]; case 1: return [4 /*yield*/, initializationPromise]; case 2: measurementId = _a.sent(); gtagFunction(GtagCommand.CONFIG, measurementId, { update: true, 'screen_name': screenName }); _a.label = 3; case 3: return [2 /*return*/]; } }); }); } /** * Set user_id parameter for this Google Analytics ID. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param id User ID string to set */ function setUserId(gtagFunction, initializationPromise, id, options) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var measurementId; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!(options && options.global)) return [3 /*break*/, 1]; gtagFunction(GtagCommand.SET, { 'user_id': id }); return [2 /*return*/, Promise.resolve()]; case 1: return [4 /*yield*/, initializationPromise]; case 2: measurementId = _a.sent(); gtagFunction(GtagCommand.CONFIG, measurementId, { update: true, 'user_id': id }); _a.label = 3; case 3: return [2 /*return*/]; } }); }); } /** * Set all other user properties other than user_id and screen_name. * * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event * @param properties Map of user properties to set */ function setUserProperties(gtagFunction, initializationPromise, properties, options) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var flatProperties, _i, _a, key, measurementId; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: if (!(options && options.global)) return [3 /*break*/, 1]; flatProperties = {}; for (_i = 0, _a = Object.keys(properties); _i < _a.length; _i++) { key = _a[_i]; // use dot notation for merge behavior in gtag.js flatProperties["user_properties." + key] = properties[key]; } gtagFunction(GtagCommand.SET, flatProperties); return [2 /*return*/, Promise.resolve()]; case 1: return [4 /*yield*/, initializationPromise]; case 2: measurementId = _b.sent(); gtagFunction(GtagCommand.CONFIG, measurementId, { update: true, 'user_properties': properties }); _b.label = 3; case 3: return [2 /*return*/]; } }); }); } /** * Set whether collection is enabled for this ID. * * @param enabled If true, collection is enabled for this ID. */ function setAnalyticsCollectionEnabled(initializationPromise, enabled) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var measurementId; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, initializationPromise]; case 1: measurementId = _a.sent(); window["ga-disable-" + measurementId] = !enabled; return [2 /*return*/]; } }); }); } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var logger = new __WEBPACK_IMPORTED_MODULE_3__firebase_logger__["b" /* Logger */]('@firebase/analytics'); /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Inserts gtag script tag into the page to asynchronously download gtag. * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). */ function insertScriptTag(dataLayerName, measurementId) { var script = document.createElement('script'); script.src = GTAG_URL + "?l=" + dataLayerName + "&id=" + measurementId; script.async = true; document.head.appendChild(script); } /** * Get reference to, or create, global datalayer. * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). */ function getOrCreateDataLayer(dataLayerName) { // Check for existing dataLayer and create if needed. var dataLayer = []; if (Array.isArray(window[dataLayerName])) { dataLayer = window[dataLayerName]; } else { window[dataLayerName] = dataLayer; } return dataLayer; } /** * Wrapped gtag logic when gtag is called with 'config' command. * * @param gtagCore Basic gtag function that just appends to dataLayer. * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. * @param measurementId GA Measurement ID to set config for. * @param gtagParams Gtag config params to set. */ function gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var correspondingAppId, dynamicConfigResults, foundConfig, e_1; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: correspondingAppId = measurementIdToAppId[measurementId]; _a.label = 1; case 1: _a.trys.push([1, 7, , 8]); if (!correspondingAppId) return [3 /*break*/, 3]; return [4 /*yield*/, initializationPromisesMap[correspondingAppId]]; case 2: _a.sent(); return [3 /*break*/, 6]; case 3: return [4 /*yield*/, Promise.all(dynamicConfigPromisesList)]; case 4: dynamicConfigResults = _a.sent(); foundConfig = dynamicConfigResults.find(function (config) { return config.measurementId === measurementId; }); if (!foundConfig) return [3 /*break*/, 6]; return [4 /*yield*/, initializationPromisesMap[foundConfig.appId]]; case 5: _a.sent(); _a.label = 6; case 6: return [3 /*break*/, 8]; case 7: e_1 = _a.sent(); logger.error(e_1); return [3 /*break*/, 8]; case 8: gtagCore(GtagCommand.CONFIG, measurementId, gtagParams); return [2 /*return*/]; } }); }); } /** * Wrapped gtag logic when gtag is called with 'event' command. * * @param gtagCore Basic gtag function that just appends to dataLayer. * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementId GA Measurement ID to log event to. * @param gtagParams Params to log with this event. */ function gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var initializationPromisesToWaitFor, gaSendToList, dynamicConfigResults, _loop_1, _i, gaSendToList_1, sendToId, state_1, e_2; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 4, , 5]); initializationPromisesToWaitFor = []; if (!(gtagParams && gtagParams['send_to'])) return [3 /*break*/, 2]; gaSendToList = gtagParams['send_to']; // Make it an array if is isn't, so it can be dealt with the same way. if (!Array.isArray(gaSendToList)) { gaSendToList = [gaSendToList]; } return [4 /*yield*/, Promise.all(dynamicConfigPromisesList)]; case 1: dynamicConfigResults = _a.sent(); _loop_1 = function (sendToId) { // Any fetched dynamic measurement ID that matches this 'send_to' ID var foundConfig = dynamicConfigResults.find(function (config) { return config.measurementId === sendToId; }); var initializationPromise = foundConfig && initializationPromisesMap[foundConfig.appId]; if (initializationPromise) { initializationPromisesToWaitFor.push(initializationPromise); } else { // Found an item in 'send_to' that is not associated // directly with an FID, possibly a group. Empty this array, // exit the loop early, and let it get populated below. initializationPromisesToWaitFor = []; return "break"; } }; for (_i = 0, gaSendToList_1 = gaSendToList; _i < gaSendToList_1.length; _i++) { sendToId = gaSendToList_1[_i]; state_1 = _loop_1(sendToId); if (state_1 === "break") break; } _a.label = 2; case 2: // This will be unpopulated if there was no 'send_to' field , or // if not all entries in the 'send_to' field could be mapped to // a FID. In these cases, wait on all pending initialization promises. if (initializationPromisesToWaitFor.length === 0) { initializationPromisesToWaitFor = Object.values(initializationPromisesMap); } // Run core gtag function with args after all relevant initialization // promises have been resolved. return [4 /*yield*/, Promise.all(initializationPromisesToWaitFor)]; case 3: // Run core gtag function with args after all relevant initialization // promises have been resolved. _a.sent(); // Workaround for http://b/141370449 - third argument cannot be undefined. gtagCore(GtagCommand.EVENT, measurementId, gtagParams || {}); return [3 /*break*/, 5]; case 4: e_2 = _a.sent(); logger.error(e_2); return [3 /*break*/, 5]; case 5: return [2 /*return*/]; } }); }); } /** * Wraps a standard gtag function with extra code to wait for completion of * relevant initialization promises before sending requests. * * @param gtagCore Basic gtag function that just appends to dataLayer. * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. */ function wrapGtag(gtagCore, /** * Allows wrapped gtag calls to wait on whichever intialization promises are required, * depending on the contents of the gtag params' `send_to` field, if any. */ initializationPromisesMap, /** * Wrapped gtag calls sometimes require all dynamic config fetches to have returned * before determining what initialization promises (which include FIDs) to wait for. */ dynamicConfigPromisesList, /** * Wrapped gtag config calls can narrow down which initialization promise (with FID) * to wait for if the measurementId is already fetched, by getting the corresponding appId, * which is the key for the initialization promises map. */ measurementIdToAppId) { /** * Wrapper around gtag that ensures FID is sent with gtag calls. * @param command Gtag command type. * @param idOrNameOrParams Measurement ID if command is EVENT/CONFIG, params if command is SET. * @param gtagParams Params if event is EVENT/CONFIG. */ function gtagWrapper(command, idOrNameOrParams, gtagParams) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var e_3; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 6, , 7]); if (!(command === GtagCommand.EVENT)) return [3 /*break*/, 2]; // If EVENT, second arg must be measurementId. return [4 /*yield*/, gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, idOrNameOrParams, gtagParams)]; case 1: // If EVENT, second arg must be measurementId. _a.sent(); return [3 /*break*/, 5]; case 2: if (!(command === GtagCommand.CONFIG)) return [3 /*break*/, 4]; // If CONFIG, second arg must be measurementId. return [4 /*yield*/, gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, idOrNameOrParams, gtagParams)]; case 3: // If CONFIG, second arg must be measurementId. _a.sent(); return [3 /*break*/, 5]; case 4: // If SET, second arg must be params. gtagCore(GtagCommand.SET, idOrNameOrParams); _a.label = 5; case 5: return [3 /*break*/, 7]; case 6: e_3 = _a.sent(); logger.error(e_3); return [3 /*break*/, 7]; case 7: return [2 /*return*/]; } }); }); } return gtagWrapper; } /** * Creates global gtag function or wraps existing one if found. * This wrapped function attaches Firebase instance ID (FID) to gtag 'config' and * 'event' calls that belong to the GAID associated with this Firebase instance. * * @param initializationPromisesMap Map of appIds to their initialization promises. * @param dynamicConfigPromisesList Array of dynamic config fetch promises. * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. * @param dataLayerName Name of global GA datalayer array. * @param gtagFunctionName Name of global gtag function ("gtag" if not user-specified). */ function wrapOrCreateGtag(initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, dataLayerName, gtagFunctionName) { // Create a basic core gtag function var gtagCore = function () { var _args = []; for (var _i = 0; _i < arguments.length; _i++) { _args[_i] = arguments[_i]; } // Must push IArguments object, not an array. window[dataLayerName].push(arguments); }; // Replace it with existing one if found if (window[gtagFunctionName] && typeof window[gtagFunctionName] === 'function') { // @ts-ignore gtagCore = window[gtagFunctionName]; } window[gtagFunctionName] = wrapGtag(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId); return { gtagCore: gtagCore, wrappedGtag: window[gtagFunctionName] }; } /** * Returns first script tag in DOM matching our gtag url pattern. */ function findGtagScriptOnPage() { var scriptTags = window.document.getElementsByTagName('script'); for (var _i = 0, _a = Object.values(scriptTags); _i < _a.length; _i++) { var tag = _a[_i]; if (tag.src && tag.src.includes(GTAG_URL)) { return tag; } } return null; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var _a; var ERRORS = (_a = {}, _a["already-exists" /* ALREADY_EXISTS */] = 'A Firebase Analytics instance with the appId {$id} ' + ' already exists. ' + 'Only one Firebase Analytics instance can be created for each appId.', _a["already-initialized" /* ALREADY_INITIALIZED */] = 'Firebase Analytics has already been initialized.' + 'settings() must be called before initializing any Analytics instance' + 'or it will have no effect.', _a["interop-component-reg-failed" /* INTEROP_COMPONENT_REG_FAILED */] = 'Firebase Analytics Interop Component failed to instantiate: {$reason}', _a["invalid-analytics-context" /* INVALID_ANALYTICS_CONTEXT */] = 'Firebase Analytics is not supported in this environment. ' + 'Wrap initialization of analytics in analytics.isSupported() ' + 'to prevent initialization in unsupported environments. Details: {$errorInfo}', _a["indexeddb-unavailable" /* INDEXEDDB_UNAVAILABLE */] = 'IndexedDB unavailable or restricted in this environment. ' + 'Wrap initialization of analytics in analytics.isSupported() ' + 'to prevent initialization in unsupported environments. Details: {$errorInfo}', _a["fetch-throttle" /* FETCH_THROTTLE */] = 'The config fetch request timed out while in an exponential backoff state.' + ' Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.', _a["config-fetch-failed" /* CONFIG_FETCH_FAILED */] = 'Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}', _a["no-api-key" /* NO_API_KEY */] = 'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field to' + 'contain a valid API key.', _a["no-app-id" /* NO_APP_ID */] = 'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field to' + 'contain a valid app ID.', _a); var ERROR_FACTORY = new __WEBPACK_IMPORTED_MODULE_4__firebase_util__["b" /* ErrorFactory */]('analytics', 'Analytics', ERRORS); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Backoff factor for 503 errors, which we want to be conservative about * to avoid overloading servers. Each retry interval will be * BASE_INTERVAL_MILLIS * LONG_RETRY_FACTOR ^ retryCount, so the second one * will be ~30 seconds (with fuzzing). */ var LONG_RETRY_FACTOR = 30; /** * Base wait interval to multiplied by backoffFactor^backoffCount. */ var BASE_INTERVAL_MILLIS = 1000; /** * Stubbable retry data storage class. */ var RetryData = /** @class */ (function () { function RetryData(throttleMetadata, intervalMillis) { if (throttleMetadata === void 0) { throttleMetadata = {}; } if (intervalMillis === void 0) { intervalMillis = BASE_INTERVAL_MILLIS; } this.throttleMetadata = throttleMetadata; this.intervalMillis = intervalMillis; } RetryData.prototype.getThrottleMetadata = function (appId) { return this.throttleMetadata[appId]; }; RetryData.prototype.setThrottleMetadata = function (appId, metadata) { this.throttleMetadata[appId] = metadata; }; RetryData.prototype.deleteThrottleMetadata = function (appId) { delete this.throttleMetadata[appId]; }; return RetryData; }()); var defaultRetryData = new RetryData(); /** * Set GET request headers. * @param apiKey App API key. */ function getHeaders(apiKey) { return new Headers({ Accept: 'application/json', 'x-goog-api-key': apiKey }); } /** * Fetches dynamic config from backend. * @param app Firebase app to fetch config for. */ function fetchDynamicConfig(appFields) { var _a; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var appId, apiKey, request, appUrl, response, errorMessage, jsonResponse, _ignored_1; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: appId = appFields.appId, apiKey = appFields.apiKey; request = { method: 'GET', headers: getHeaders(apiKey) }; appUrl = DYNAMIC_CONFIG_URL.replace('{app-id}', appId); return [4 /*yield*/, fetch(appUrl, request)]; case 1: response = _b.sent(); if (!(response.status !== 200 && response.status !== 304)) return [3 /*break*/, 6]; errorMessage = ''; _b.label = 2; case 2: _b.trys.push([2, 4, , 5]); return [4 /*yield*/, response.json()]; case 3: jsonResponse = (_b.sent()); if ((_a = jsonResponse.error) === null || _a === void 0 ? void 0 : _a.message) { errorMessage = jsonResponse.error.message; } return [3 /*break*/, 5]; case 4: _ignored_1 = _b.sent(); return [3 /*break*/, 5]; case 5: throw ERROR_FACTORY.create("config-fetch-failed" /* CONFIG_FETCH_FAILED */, { httpStatus: response.status, responseMessage: errorMessage }); case 6: return [2 /*return*/, response.json()]; } }); }); } /** * Fetches dynamic config from backend, retrying if failed. * @param app Firebase app to fetch config for. */ function fetchDynamicConfigWithRetry(app, // retryData and timeoutMillis are parameterized to allow passing a different value for testing. retryData, timeoutMillis) { if (retryData === void 0) { retryData = defaultRetryData; } return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var _a, appId, apiKey, measurementId, throttleMetadata, signal; var _this = this; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_b) { _a = app.options, appId = _a.appId, apiKey = _a.apiKey, measurementId = _a.measurementId; if (!appId) { throw ERROR_FACTORY.create("no-app-id" /* NO_APP_ID */); } if (!apiKey) { if (measurementId) { return [2 /*return*/, { measurementId: measurementId, appId: appId }]; } throw ERROR_FACTORY.create("no-api-key" /* NO_API_KEY */); } throttleMetadata = retryData.getThrottleMetadata(appId) || { backoffCount: 0, throttleEndTimeMillis: Date.now() }; signal = new AnalyticsAbortSignal(); setTimeout(function () { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(_this, void 0, void 0, function () { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { // Note a very low delay, eg < 10ms, can elapse before listeners are initialized. signal.abort(); return [2 /*return*/]; }); }); }, timeoutMillis !== undefined ? timeoutMillis : FETCH_TIMEOUT_MILLIS); return [2 /*return*/, attemptFetchDynamicConfigWithRetry({ appId: appId, apiKey: apiKey, measurementId: measurementId }, throttleMetadata, signal, retryData)]; }); }); } /** * Runs one retry attempt. * @param appFields Necessary app config fields. * @param throttleMetadata Ongoing metadata to determine throttling times. * @param signal Abort signal. */ function attemptFetchDynamicConfigWithRetry(appFields, _a, signal, retryData // for testing ) { var throttleEndTimeMillis = _a.throttleEndTimeMillis, backoffCount = _a.backoffCount; if (retryData === void 0) { retryData = defaultRetryData; } return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var appId, measurementId, e_1, response, e_2, backoffMillis, throttleMetadata; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_b) { switch (_b.label) { case 0: appId = appFields.appId, measurementId = appFields.measurementId; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, setAbortableTimeout(signal, throttleEndTimeMillis)]; case 2: _b.sent(); return [3 /*break*/, 4]; case 3: e_1 = _b.sent(); if (measurementId) { logger.warn("Timed out fetching this Firebase app's measurement ID from the server." + (" Falling back to the measurement ID " + measurementId) + (" provided in the \"measurementId\" field in the local Firebase config. [" + e_1.message + "]")); return [2 /*return*/, { appId: appId, measurementId: measurementId }]; } throw e_1; case 4: _b.trys.push([4, 6, , 7]); return [4 /*yield*/, fetchDynamicConfig(appFields)]; case 5: response = _b.sent(); // Note the SDK only clears throttle state if response is success or non-retriable. retryData.deleteThrottleMetadata(appId); return [2 /*return*/, response]; case 6: e_2 = _b.sent(); if (!isRetriableError(e_2)) { retryData.deleteThrottleMetadata(appId); if (measurementId) { logger.warn("Failed to fetch this Firebase app's measurement ID from the server." + (" Falling back to the measurement ID " + measurementId) + (" provided in the \"measurementId\" field in the local Firebase config. [" + e_2.message + "]")); return [2 /*return*/, { appId: appId, measurementId: measurementId }]; } else { throw e_2; } } backoffMillis = Number(e_2.customData.httpStatus) === 503 ? Object(__WEBPACK_IMPORTED_MODULE_4__firebase_util__["j" /* calculateBackoffMillis */])(backoffCount, retryData.intervalMillis, LONG_RETRY_FACTOR) : Object(__WEBPACK_IMPORTED_MODULE_4__firebase_util__["j" /* calculateBackoffMillis */])(backoffCount, retryData.intervalMillis); throttleMetadata = { throttleEndTimeMillis: Date.now() + backoffMillis, backoffCount: backoffCount + 1 }; // Persists state. retryData.setThrottleMetadata(appId, throttleMetadata); logger.debug("Calling attemptFetch again in " + backoffMillis + " millis"); return [2 /*return*/, attemptFetchDynamicConfigWithRetry(appFields, throttleMetadata, signal, retryData)]; case 7: return [2 /*return*/]; } }); }); } /** * Supports waiting on a backoff by: * *
    *
  • Promisifying setTimeout, so we can set a timeout in our Promise chain
  • *
  • Listening on a signal bus for abort events, just like the Fetch API
  • *
  • Failing in the same way the Fetch API fails, so timing out a live request and a throttled * request appear the same.
  • *
* *

Visible for testing. */ function setAbortableTimeout(signal, throttleEndTimeMillis) { return new Promise(function (resolve, reject) { // Derives backoff from given end time, normalizing negative numbers to zero. var backoffMillis = Math.max(throttleEndTimeMillis - Date.now(), 0); var timeout = setTimeout(resolve, backoffMillis); // Adds listener, rather than sets onabort, because signal is a shared object. signal.addEventListener(function () { clearTimeout(timeout); // If the request completes before this timeout, the rejection has no effect. reject(ERROR_FACTORY.create("fetch-throttle" /* FETCH_THROTTLE */, { throttleEndTimeMillis: throttleEndTimeMillis })); }); }); } /** * Returns true if the {@link Error} indicates a fetch request may succeed later. */ function isRetriableError(e) { if (!(e instanceof __WEBPACK_IMPORTED_MODULE_4__firebase_util__["c" /* FirebaseError */]) || !e.customData) { return false; } // Uses string index defined by ErrorData, which FirebaseError implements. var httpStatus = Number(e.customData['httpStatus']); return (httpStatus === 429 || httpStatus === 500 || httpStatus === 503 || httpStatus === 504); } /** * Shims a minimal AbortSignal (copied from Remote Config). * *

AbortController's AbortSignal conveniently decouples fetch timeout logic from other aspects * of networking, such as retries. Firebase doesn't use AbortController enough to justify a * polyfill recommendation, like we do with the Fetch API, but this minimal shim can easily be * swapped out if/when we do. */ var AnalyticsAbortSignal = /** @class */ (function () { function AnalyticsAbortSignal() { this.listeners = []; } AnalyticsAbortSignal.prototype.addEventListener = function (listener) { this.listeners.push(listener); }; AnalyticsAbortSignal.prototype.abort = function () { this.listeners.forEach(function (listener) { return listener(); }); }; return AnalyticsAbortSignal; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function validateIndexedDB() { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var e_1; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_a) { switch (_a.label) { case 0: if (!!Object(__WEBPACK_IMPORTED_MODULE_4__firebase_util__["w" /* isIndexedDBAvailable */])()) return [3 /*break*/, 1]; logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* INDEXEDDB_UNAVAILABLE */, { errorInfo: 'IndexedDB is not available in this environment.' }).message); return [2 /*return*/, false]; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, Object(__WEBPACK_IMPORTED_MODULE_4__firebase_util__["N" /* validateIndexedDBOpenable */])()]; case 2: _a.sent(); return [3 /*break*/, 4]; case 3: e_1 = _a.sent(); logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* INDEXEDDB_UNAVAILABLE */, { errorInfo: e_1 }).message); return [2 /*return*/, false]; case 4: return [2 /*return*/, true]; } }); }); } /** * Initialize the analytics instance in gtag.js by calling config command with fid. * * NOTE: We combine analytics initialization and setting fid together because we want fid to be * part of the `page_view` event that's sent during the initialization * @param app Firebase app * @param gtagCore The gtag function that's not wrapped. * @param dynamicConfigPromisesList Array of all dynamic config promises. * @param measurementIdToAppId Maps measurementID to appID. * @param installations FirebaseInstallations instance. * * @returns Measurement ID. */ function initializeIds(app, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCore, dataLayerName) { return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["b" /* __awaiter */])(this, void 0, void 0, function () { var dynamicConfigPromise, fidPromise, _a, dynamicConfig, fid, configProperties; var _b; return Object(__WEBPACK_IMPORTED_MODULE_0_tslib__["c" /* __generator */])(this, function (_c) { switch (_c.label) { case 0: dynamicConfigPromise = fetchDynamicConfigWithRetry(app); // Once fetched, map measurementIds to appId, for ease of lookup in wrapped gtag function. dynamicConfigPromise .then(function (config) { measurementIdToAppId[config.measurementId] = config.appId; if (app.options.measurementId && config.measurementId !== app.options.measurementId) { logger.warn("The measurement ID in the local Firebase config (" + app.options.measurementId + ")" + (" does not match the measurement ID fetched from the server (" + config.measurementId + ").") + " To ensure analytics events are always sent to the correct Analytics property," + " update the" + " measurement ID field in the local config or remove it from the local config."); } }) .catch(function (e) { return logger.error(e); }); // Add to list to track state of all dynamic config promises. dynamicConfigPromisesList.push(dynamicConfigPromise); fidPromise = validateIndexedDB().then(function (envIsValid) { if (envIsValid) { return installations.getId(); } else { return undefined; } }); return [4 /*yield*/, Promise.all([ dynamicConfigPromise, fidPromise ])]; case 1: _a = _c.sent(), dynamicConfig = _a[0], fid = _a[1]; // Detect if user has already put the gtag