favesalon-embed 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/custom-elements/index.d.ts +42 -0
  2. package/dist/{cjs/_commonjsHelpers-5cfcba41.js → favesalon-embed/_commonjsHelpers-a4f66ccd.js} +14 -6
  3. package/dist/favesalon-embed/activate-form.entry.js +70 -0
  4. package/dist/favesalon-embed/app-globals-74127f4b.js +7 -0
  5. package/dist/favesalon-embed/app-globals-f954a22f.js +7 -0
  6. package/dist/favesalon-embed/change-password-form.entry.js +81 -0
  7. package/dist/favesalon-embed/chat-box.entry.js +55 -0
  8. package/dist/{esm → favesalon-embed}/chat-button.entry.js +36 -13
  9. package/dist/favesalon-embed/chat-form.entry.js +39 -0
  10. package/dist/favesalon-embed/chat-messages.entry.js +71 -0
  11. package/dist/favesalon-embed/chat-rooms.entry.js +111 -0
  12. package/dist/favesalon-embed/css-shim-b7d3d95f.js +4 -0
  13. package/dist/favesalon-embed/dom-64053c71.js +73 -0
  14. package/dist/favesalon-embed/favesalon-embed.css +114 -1
  15. package/dist/favesalon-embed/favesalon-embed.esm.js +148 -1
  16. package/dist/{esm → favesalon-embed}/google-map.entry.js +1 -1
  17. package/dist/{esm/index-a1c7583c.js → favesalon-embed/index-00b83e1c.js} +425 -15
  18. package/dist/favesalon-embed/index-888e99e3.js +3371 -0
  19. package/dist/favesalon-embed/index-a229b3b5.js +3371 -0
  20. package/dist/favesalon-embed/index.esm.js +1 -0
  21. package/dist/{esm/chat-box_5.entry.js → favesalon-embed/lodash-d5526b38.js} +27 -243
  22. package/dist/favesalon-embed/login-form.entry.js +67 -0
  23. package/dist/{cjs/chat-button.cjs.entry.js → favesalon-embed/notify-sounds.entry.js} +20 -44
  24. package/dist/favesalon-embed/register-form.entry.js +88 -0
  25. package/dist/favesalon-embed/relativeTime-268e64b0.js +7 -0
  26. package/dist/favesalon-embed/reset-password-form.entry.js +47 -0
  27. package/dist/{esm → favesalon-embed}/salon-booking-modal.entry.js +1 -1
  28. package/dist/{esm → favesalon-embed}/salon-booking.entry.js +4 -4
  29. package/dist/{esm → favesalon-embed}/salon-gift-card-modal.entry.js +1 -1
  30. package/dist/{esm → favesalon-embed}/salon-gift-card.entry.js +4 -4
  31. package/dist/{esm → favesalon-embed}/salon-info.entry.js +3 -3
  32. package/dist/{esm → favesalon-embed}/salon-latest-reviews.entry.js +22 -6
  33. package/dist/{collection/components/salon-latest-styles/index.js → favesalon-embed/salon-latest-styles.entry.js} +27 -105
  34. package/dist/{collection/components/salon-locations/index.js → favesalon-embed/salon-locations.entry.js} +15 -95
  35. package/dist/{esm → favesalon-embed}/salon-lookbook.entry.js +18 -6
  36. package/dist/{esm → favesalon-embed}/salon-ranking.entry.js +1 -1
  37. package/dist/{esm → favesalon-embed}/salon-reviews.entry.js +20 -6
  38. package/dist/{collection/components/salon-schedules/index.js → favesalon-embed/salon-schedules.entry.js} +14 -95
  39. package/dist/{esm → favesalon-embed}/salon-services.entry.js +25 -13
  40. package/dist/{esm → favesalon-embed}/salon-stylists.entry.js +3 -3
  41. package/dist/{esm/services-257442e2.js → favesalon-embed/services-5a4c43a6.js} +2608 -188
  42. package/dist/{cjs/services-d1bdf299.js → favesalon-embed/services-d71be591.js} +2616 -191
  43. package/dist/favesalon-embed/shadow-css-98135883.js +387 -0
  44. package/dist/{esm → favesalon-embed}/style-detail.entry.js +29 -11
  45. package/dist/favesalon-embed/user-avatar.entry.js +52 -0
  46. package/dist/favesalon-embed/user-form.entry.js +44 -0
  47. package/dist/{collection/utils/utils.js → favesalon-embed/utils-fd30fb29.js} +14 -5
  48. package/dist/types/components/activate-form/activate-form.d.ts +12 -0
  49. package/dist/types/components/activate-form/test/activate-form.spec.d.ts +1 -0
  50. package/dist/types/components/change-password-form/change-password-form.d.ts +12 -0
  51. package/dist/types/components/chat-box/index.d.ts +1 -0
  52. package/dist/types/components/chat-button/index.d.ts +6 -2
  53. package/dist/types/components/chat-button/notify-sounds.d.ts +5 -0
  54. package/dist/types/components/chat-rooms/index.d.ts +6 -0
  55. package/dist/types/components/login-form/login-form.d.ts +10 -0
  56. package/dist/types/components/register-form/register-form.d.ts +13 -0
  57. package/dist/types/components/reset-password-form/reset-password-form.d.ts +9 -0
  58. package/dist/types/components/user-form/user-form.d.ts +7 -0
  59. package/dist/types/components.d.ts +127 -2
  60. package/dist/types/services/services.d.ts +17 -0
  61. package/dist/types/types/chat.d.ts +1 -0
  62. package/dist/types/types/user.d.ts +16 -0
  63. package/dist/types/utils/utils.d.ts +1 -0
  64. package/dist/types/utils/utils.spec.d.ts +1 -0
  65. package/package.json +1 -1
  66. package/dist/cjs/chat-box_5.cjs.entry.js +0 -17439
  67. package/dist/cjs/colors-38421769.js +0 -69
  68. package/dist/cjs/favesalon-embed.cjs.js +0 -23
  69. package/dist/cjs/google-map.cjs.entry.js +0 -52
  70. package/dist/cjs/index-7f190886.js +0 -4396
  71. package/dist/cjs/index-dd8176c4.js +0 -1531
  72. package/dist/cjs/index.cjs.js +0 -2
  73. package/dist/cjs/loader.cjs.js +0 -22
  74. package/dist/cjs/relativeTime-3721080d.js +0 -9
  75. package/dist/cjs/salon-booking-modal.cjs.entry.js +0 -30
  76. package/dist/cjs/salon-booking.cjs.entry.js +0 -51
  77. package/dist/cjs/salon-gift-card-modal.cjs.entry.js +0 -29
  78. package/dist/cjs/salon-gift-card.cjs.entry.js +0 -51
  79. package/dist/cjs/salon-info.cjs.entry.js +0 -33
  80. package/dist/cjs/salon-latest-reviews.cjs.entry.js +0 -97
  81. package/dist/cjs/salon-latest-styles_3.cjs.entry.js +0 -241
  82. package/dist/cjs/salon-lookbook.cjs.entry.js +0 -222
  83. package/dist/cjs/salon-ranking.cjs.entry.js +0 -60
  84. package/dist/cjs/salon-reviews.cjs.entry.js +0 -193
  85. package/dist/cjs/salon-services.cjs.entry.js +0 -81
  86. package/dist/cjs/salon-stylists.cjs.entry.js +0 -118
  87. package/dist/cjs/style-detail.cjs.entry.js +0 -312
  88. package/dist/cjs/utils-c5a33b3c.js +0 -23
  89. package/dist/collection/collection-manifest.json +0 -33
  90. package/dist/collection/components/chat-box/index.css +0 -105
  91. package/dist/collection/components/chat-box/index.js +0 -138
  92. package/dist/collection/components/chat-button/index.css +0 -101
  93. package/dist/collection/components/chat-button/index.js +0 -155
  94. package/dist/collection/components/chat-form/index.css +0 -40
  95. package/dist/collection/components/chat-form/index.js +0 -79
  96. package/dist/collection/components/chat-messages/index.css +0 -48
  97. package/dist/collection/components/chat-messages/index.js +0 -142
  98. package/dist/collection/components/chat-rooms/index.css +0 -102
  99. package/dist/collection/components/chat-rooms/index.js +0 -157
  100. package/dist/collection/components/google-map/assets/map--placeholder.jpeg +0 -0
  101. package/dist/collection/components/google-map/index.css +0 -5
  102. package/dist/collection/components/google-map/index.js +0 -90
  103. package/dist/collection/components/salon-booking/index.css +0 -30
  104. package/dist/collection/components/salon-booking/index.js +0 -126
  105. package/dist/collection/components/salon-booking/salon-booking-modal.js +0 -92
  106. package/dist/collection/components/salon-gift-card/index.css +0 -30
  107. package/dist/collection/components/salon-gift-card/index.js +0 -126
  108. package/dist/collection/components/salon-gift-card/salon-gift-card-modal.js +0 -73
  109. package/dist/collection/components/salon-info/index.css +0 -1
  110. package/dist/collection/components/salon-info/index.js +0 -77
  111. package/dist/collection/components/salon-latest-reviews/index.css +0 -11
  112. package/dist/collection/components/salon-latest-reviews/index.js +0 -163
  113. package/dist/collection/components/salon-latest-styles/index.css +0 -12
  114. package/dist/collection/components/salon-locations/index.css +0 -24
  115. package/dist/collection/components/salon-lookbook/index.css +0 -15
  116. package/dist/collection/components/salon-lookbook/index.js +0 -368
  117. package/dist/collection/components/salon-ranking/index.css +0 -3
  118. package/dist/collection/components/salon-ranking/index.js +0 -117
  119. package/dist/collection/components/salon-reviews/index.css +0 -18
  120. package/dist/collection/components/salon-reviews/index.js +0 -249
  121. package/dist/collection/components/salon-schedules/index.css +0 -18
  122. package/dist/collection/components/salon-services/index.css +0 -1
  123. package/dist/collection/components/salon-services/index.js +0 -146
  124. package/dist/collection/components/salon-stylists/index.css +0 -43
  125. package/dist/collection/components/salon-stylists/index.js +0 -184
  126. package/dist/collection/components/style-detail/index.css +0 -76
  127. package/dist/collection/components/style-detail/index.js +0 -386
  128. package/dist/collection/components/user-avatar/index.css +0 -0
  129. package/dist/collection/components/user-avatar/index.js +0 -159
  130. package/dist/collection/constants/colors.js +0 -65
  131. package/dist/collection/global/global.js +0 -0
  132. package/dist/collection/mocks/users.js +0 -10
  133. package/dist/collection/services/services.js +0 -295
  134. package/dist/collection/types/chat.js +0 -23
  135. package/dist/collection/types/common.js +0 -11
  136. package/dist/collection/types/review.js +0 -39
  137. package/dist/collection/types/salon.js +0 -58
  138. package/dist/collection/types/service.js +0 -24
  139. package/dist/collection/types/style.js +0 -128
  140. package/dist/collection/types/stylist.js +0 -30
  141. package/dist/collection/types/user.js +0 -10
  142. package/dist/custom-elements/index.js +0 -44974
  143. package/dist/esm/_commonjsHelpers-66ac50f5.js +0 -32
  144. package/dist/esm/favesalon-embed.js +0 -18
  145. package/dist/esm/index-0494771f.js +0 -1504
  146. package/dist/esm/index.js +0 -1
  147. package/dist/esm/loader.js +0 -18
  148. package/dist/esm/polyfills/core-js.js +0 -11
  149. package/dist/esm/polyfills/css-shim.js +0 -1
  150. package/dist/esm/polyfills/dom.js +0 -79
  151. package/dist/esm/polyfills/es5-html-element.js +0 -1
  152. package/dist/esm/polyfills/index.js +0 -34
  153. package/dist/esm/polyfills/system.js +0 -6
  154. package/dist/esm/relativeTime-baa50aa2.js +0 -7
  155. package/dist/esm/salon-latest-styles_3.entry.js +0 -235
  156. package/dist/esm/utils-e97485e0.js +0 -19
  157. package/dist/favesalon-embed/p-05a1c88a.entry.js +0 -1
  158. package/dist/favesalon-embed/p-0acf0447.entry.js +0 -1
  159. package/dist/favesalon-embed/p-0bc4f624.js +0 -1
  160. package/dist/favesalon-embed/p-1af1515f.entry.js +0 -1
  161. package/dist/favesalon-embed/p-1cba5fc9.entry.js +0 -1
  162. package/dist/favesalon-embed/p-39a4ef15.entry.js +0 -1
  163. package/dist/favesalon-embed/p-3e2cb05b.entry.js +0 -1
  164. package/dist/favesalon-embed/p-47e646f8.js +0 -1
  165. package/dist/favesalon-embed/p-487b311f.entry.js +0 -1
  166. package/dist/favesalon-embed/p-55387c2f.entry.js +0 -1
  167. package/dist/favesalon-embed/p-566f05b4.entry.js +0 -1
  168. package/dist/favesalon-embed/p-862a0de0.entry.js +0 -1
  169. package/dist/favesalon-embed/p-9fe0cbeb.js +0 -2
  170. package/dist/favesalon-embed/p-a33331cc.js +0 -1
  171. package/dist/favesalon-embed/p-aeeb7b5f.entry.js +0 -1
  172. package/dist/favesalon-embed/p-b08e5b54.js +0 -6
  173. package/dist/favesalon-embed/p-b5cca5fc.entry.js +0 -1
  174. package/dist/favesalon-embed/p-c7fb7af5.js +0 -1580
  175. package/dist/favesalon-embed/p-ccab56d8.js +0 -1
  176. package/dist/favesalon-embed/p-d6e13053.entry.js +0 -1
  177. package/dist/favesalon-embed/p-dee42d34.entry.js +0 -1
  178. package/dist/favesalon-embed/p-e661ca1d.entry.js +0 -1
  179. package/dist/favesalon-embed/p-eeceab9c.entry.js +0 -1
  180. package/dist/index.cjs.js +0 -1
  181. package/dist/index.js +0 -1
  182. /package/dist/{esm → favesalon-embed}/colors-ea36347a.js +0 -0
  183. /package/dist/{collection/index.js → types/components/activate-form/test/activate-form.e2e.d.ts} +0 -0
@@ -1,7 +1,5 @@
1
- 'use strict';
2
-
3
- const _commonjsHelpers = require('./_commonjsHelpers-5cfcba41.js');
4
- const colors = require('./colors-38421769.js');
1
+ import { c as commonjsGlobal, a as createCommonjsModule } from './_commonjsHelpers-a4f66ccd.js';
2
+ import { C as Colors } from './colors-ea36347a.js';
5
3
 
6
4
  /**
7
5
  * Checks if `value` is classified as an `Array` object.
@@ -31,7 +29,7 @@ var isArray$1 = Array.isArray;
31
29
  var isArray_1 = isArray$1;
32
30
 
33
31
  /** Detect free variable `global` from Node.js. */
34
- var freeGlobal = typeof _commonjsHelpers.commonjsGlobal == 'object' && _commonjsHelpers.commonjsGlobal && _commonjsHelpers.commonjsGlobal.Object === Object && _commonjsHelpers.commonjsGlobal;
32
+ var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
35
33
 
36
34
  var _freeGlobal = freeGlobal;
37
35
 
@@ -1183,12 +1181,12 @@ var _baseGet = baseGet;
1183
1181
  * _.get(object, 'a.b.c', 'default');
1184
1182
  * // => 'default'
1185
1183
  */
1186
- function get(object, path, defaultValue) {
1184
+ function get$1(object, path, defaultValue) {
1187
1185
  var result = object == null ? undefined : _baseGet(object, path);
1188
1186
  return result === undefined ? defaultValue : result;
1189
1187
  }
1190
1188
 
1191
- var get_1 = get;
1189
+ var get_1 = get$1;
1192
1190
 
1193
1191
  /**
1194
1192
  * A specialized version of `_.forEach` for arrays without support for
@@ -1344,9 +1342,9 @@ function stubFalse() {
1344
1342
 
1345
1343
  var stubFalse_1 = stubFalse;
1346
1344
 
1347
- var isBuffer_1 = _commonjsHelpers.createCommonjsModule(function (module, exports) {
1345
+ var isBuffer_1 = createCommonjsModule(function (module, exports) {
1348
1346
  /** Detect free variable `exports`. */
1349
- var freeExports = exports && !exports.nodeType && exports;
1347
+ var freeExports = 'object' == 'object' && exports && !exports.nodeType && exports;
1350
1348
 
1351
1349
  /** Detect free variable `module`. */
1352
1350
  var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
@@ -1516,9 +1514,9 @@ function baseUnary(func) {
1516
1514
 
1517
1515
  var _baseUnary = baseUnary;
1518
1516
 
1519
- var _nodeUtil = _commonjsHelpers.createCommonjsModule(function (module, exports) {
1517
+ var _nodeUtil = createCommonjsModule(function (module, exports) {
1520
1518
  /** Detect free variable `exports`. */
1521
- var freeExports = exports && !exports.nodeType && exports;
1519
+ var freeExports = 'object' == 'object' && exports && !exports.nodeType && exports;
1522
1520
 
1523
1521
  /** Detect free variable `module`. */
1524
1522
  var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
@@ -3501,6 +3499,8 @@ var sortBy = _baseRest(function(collection, iteratees) {
3501
3499
 
3502
3500
  var sortBy_1 = sortBy;
3503
3501
 
3502
+ 'use strict';
3503
+
3504
3504
  var bind = function bind(fn, thisArg) {
3505
3505
  return function wrap() {
3506
3506
  var args = new Array(arguments.length);
@@ -3511,6 +3511,10 @@ var bind = function bind(fn, thisArg) {
3511
3511
  };
3512
3512
  };
3513
3513
 
3514
+ 'use strict';
3515
+
3516
+
3517
+
3514
3518
  // utils is a library of generic helper functions non-specific to axios
3515
3519
 
3516
3520
  var toString = Object.prototype.toString;
@@ -3857,6 +3861,10 @@ var utils = {
3857
3861
  stripBOM: stripBOM
3858
3862
  };
3859
3863
 
3864
+ 'use strict';
3865
+
3866
+
3867
+
3860
3868
  function encode(val) {
3861
3869
  return encodeURIComponent(val).
3862
3870
  replace(/%3A/gi, ':').
@@ -3924,6 +3932,10 @@ var buildURL = function buildURL(url, params, paramsSerializer) {
3924
3932
  return url;
3925
3933
  };
3926
3934
 
3935
+ 'use strict';
3936
+
3937
+
3938
+
3927
3939
  function InterceptorManager() {
3928
3940
  this.handlers = [];
3929
3941
  }
@@ -3975,6 +3987,10 @@ InterceptorManager.prototype.forEach = function forEach(fn) {
3975
3987
 
3976
3988
  var InterceptorManager_1 = InterceptorManager;
3977
3989
 
3990
+ 'use strict';
3991
+
3992
+
3993
+
3978
3994
  var normalizeHeaderName = function normalizeHeaderName(headers, normalizedName) {
3979
3995
  utils.forEach(headers, function processHeader(value, name) {
3980
3996
  if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
@@ -3984,6 +4000,8 @@ var normalizeHeaderName = function normalizeHeaderName(headers, normalizedName)
3984
4000
  });
3985
4001
  };
3986
4002
 
4003
+ 'use strict';
4004
+
3987
4005
  /**
3988
4006
  * Update an Error with the specified config, error code, and response.
3989
4007
  *
@@ -4026,6 +4044,10 @@ var enhanceError = function enhanceError(error, config, code, request, response)
4026
4044
  return error;
4027
4045
  };
4028
4046
 
4047
+ 'use strict';
4048
+
4049
+
4050
+
4029
4051
  /**
4030
4052
  * Create an Error with the specified message, config, error code, request and response.
4031
4053
  *
@@ -4041,6 +4063,10 @@ var createError = function createError(message, config, code, request, response)
4041
4063
  return enhanceError(error, config, code, request, response);
4042
4064
  };
4043
4065
 
4066
+ 'use strict';
4067
+
4068
+
4069
+
4044
4070
  /**
4045
4071
  * Resolve or reject a Promise based on response status.
4046
4072
  *
@@ -4063,6 +4089,10 @@ var settle = function settle(resolve, reject, response) {
4063
4089
  }
4064
4090
  };
4065
4091
 
4092
+ 'use strict';
4093
+
4094
+
4095
+
4066
4096
  var cookies = (
4067
4097
  utils.isStandardBrowserEnv() ?
4068
4098
 
@@ -4113,6 +4143,8 @@ var cookies = (
4113
4143
  })()
4114
4144
  );
4115
4145
 
4146
+ 'use strict';
4147
+
4116
4148
  /**
4117
4149
  * Determines whether the specified URL is absolute
4118
4150
  *
@@ -4126,6 +4158,8 @@ var isAbsoluteURL = function isAbsoluteURL(url) {
4126
4158
  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
4127
4159
  };
4128
4160
 
4161
+ 'use strict';
4162
+
4129
4163
  /**
4130
4164
  * Creates a new URL by combining the specified URLs
4131
4165
  *
@@ -4139,6 +4173,11 @@ var combineURLs = function combineURLs(baseURL, relativeURL) {
4139
4173
  : baseURL;
4140
4174
  };
4141
4175
 
4176
+ 'use strict';
4177
+
4178
+
4179
+
4180
+
4142
4181
  /**
4143
4182
  * Creates a new URL by combining the baseURL with the requestedURL,
4144
4183
  * only when the requestedURL is not already an absolute URL.
@@ -4155,6 +4194,10 @@ var buildFullPath = function buildFullPath(baseURL, requestedURL) {
4155
4194
  return requestedURL;
4156
4195
  };
4157
4196
 
4197
+ 'use strict';
4198
+
4199
+
4200
+
4158
4201
  // Headers whose duplicates are ignored by node
4159
4202
  // c.f. https://nodejs.org/api/http.html#http_message_headers
4160
4203
  var ignoreDuplicateOf = [
@@ -4205,6 +4248,10 @@ var parseHeaders = function parseHeaders(headers) {
4205
4248
  return parsed;
4206
4249
  };
4207
4250
 
4251
+ 'use strict';
4252
+
4253
+
4254
+
4208
4255
  var isURLSameOrigin = (
4209
4256
  utils.isStandardBrowserEnv() ?
4210
4257
 
@@ -4270,6 +4317,8 @@ var isURLSameOrigin = (
4270
4317
  })()
4271
4318
  );
4272
4319
 
4320
+ 'use strict';
4321
+
4273
4322
  /**
4274
4323
  * A `Cancel` is an object that is thrown when an operation is canceled.
4275
4324
  *
@@ -4288,6 +4337,19 @@ Cancel.prototype.__CANCEL__ = true;
4288
4337
 
4289
4338
  var Cancel_1 = Cancel;
4290
4339
 
4340
+ 'use strict';
4341
+
4342
+
4343
+
4344
+
4345
+
4346
+
4347
+
4348
+
4349
+
4350
+
4351
+
4352
+
4291
4353
  var xhr = function xhrAdapter(config) {
4292
4354
  return new Promise(function dispatchXhrRequest(resolve, reject) {
4293
4355
  var requestData = config.data;
@@ -4488,6 +4550,12 @@ var xhr = function xhrAdapter(config) {
4488
4550
  });
4489
4551
  };
4490
4552
 
4553
+ 'use strict';
4554
+
4555
+
4556
+
4557
+
4558
+
4491
4559
  var DEFAULT_CONTENT_TYPE = {
4492
4560
  'Content-Type': 'application/x-www-form-urlencoded'
4493
4561
  };
@@ -4617,6 +4685,11 @@ utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
4617
4685
 
4618
4686
  var defaults_1 = defaults;
4619
4687
 
4688
+ 'use strict';
4689
+
4690
+
4691
+
4692
+
4620
4693
  /**
4621
4694
  * Transform the data for a request or a response
4622
4695
  *
@@ -4635,10 +4708,20 @@ var transformData = function transformData(data, headers, fns) {
4635
4708
  return data;
4636
4709
  };
4637
4710
 
4711
+ 'use strict';
4712
+
4638
4713
  var isCancel = function isCancel(value) {
4639
4714
  return !!(value && value.__CANCEL__);
4640
4715
  };
4641
4716
 
4717
+ 'use strict';
4718
+
4719
+
4720
+
4721
+
4722
+
4723
+
4724
+
4642
4725
  /**
4643
4726
  * Throws a `Cancel` if cancellation has been requested.
4644
4727
  */
@@ -4719,6 +4802,10 @@ var dispatchRequest = function dispatchRequest(config) {
4719
4802
  });
4720
4803
  };
4721
4804
 
4805
+ 'use strict';
4806
+
4807
+
4808
+
4722
4809
  /**
4723
4810
  * Config-specific merge-function which creates a new config-object
4724
4811
  * by merging two configuration objects together.
@@ -4819,6 +4906,8 @@ var data = {
4819
4906
  "version": "0.22.0"
4820
4907
  };
4821
4908
 
4909
+ 'use strict';
4910
+
4822
4911
  var VERSION = data.version;
4823
4912
 
4824
4913
  var validators$1 = {};
@@ -4900,6 +4989,15 @@ var validator = {
4900
4989
  validators: validators$1
4901
4990
  };
4902
4991
 
4992
+ 'use strict';
4993
+
4994
+
4995
+
4996
+
4997
+
4998
+
4999
+
5000
+
4903
5001
  var validators = validator.validators;
4904
5002
  /**
4905
5003
  * Create a new instance of Axios
@@ -5040,6 +5138,10 @@ utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
5040
5138
 
5041
5139
  var Axios_1 = Axios;
5042
5140
 
5141
+ 'use strict';
5142
+
5143
+
5144
+
5043
5145
  /**
5044
5146
  * A `CancelToken` is an object that can be used to request cancellation of an operation.
5045
5147
  *
@@ -5156,6 +5258,8 @@ CancelToken.source = function source() {
5156
5258
 
5157
5259
  var CancelToken_1 = CancelToken;
5158
5260
 
5261
+ 'use strict';
5262
+
5159
5263
  /**
5160
5264
  * Syntactic sugar for invoking a function and expanding an array for arguments.
5161
5265
  *
@@ -5182,6 +5286,8 @@ var spread = function spread(callback) {
5182
5286
  };
5183
5287
  };
5184
5288
 
5289
+ 'use strict';
5290
+
5185
5291
  /**
5186
5292
  * Determines whether the payload is an error thrown by Axios
5187
5293
  *
@@ -5192,6 +5298,14 @@ var isAxiosError = function isAxiosError(payload) {
5192
5298
  return (typeof payload === 'object') && (payload.isAxiosError === true);
5193
5299
  };
5194
5300
 
5301
+ 'use strict';
5302
+
5303
+
5304
+
5305
+
5306
+
5307
+
5308
+
5195
5309
  /**
5196
5310
  * Create an instance of Axios
5197
5311
  *
@@ -5245,18 +5359,24 @@ axios_1.default = _default;
5245
5359
 
5246
5360
  var axios = axios_1;
5247
5361
 
5362
+ const timeFormat = 'HH:mm:ss';
5363
+ const timeFormatAmPm = 'hh:mm A';
5364
+ const dateName = 'dddd';
5248
5365
  const dateFormat = 'YYYY-MM-DD';
5249
5366
  const dateTimeFormat = 'YYYY-MM-DD HH:mm:ss';
5367
+ const dateTimeFormatAmPm = 'YYYY-MM-DD hh:mm A';
5368
+ const shortDateFormat = 'ddd, MMM DD';
5250
5369
  const shortDateYearFormat = 'ddd, MMM DD YYYY';
5251
5370
  const apiV1Prefix = 'api';
5371
+ const apiV2Prefix$1 = 'api-ver2';
5252
5372
  const defaultImage = 'https://res.cloudinary.com/reckon-mini-sites/image/upload/v1636477599/FaveSalon%20Social%20Website/default/default--picture_w3jvfh.png';
5253
5373
 
5254
- exports.BusinessHourStatus = void 0;
5374
+ var BusinessHourStatus;
5255
5375
  (function (BusinessHourStatus) {
5256
5376
  BusinessHourStatus[BusinessHourStatus["Open"] = 0] = "Open";
5257
5377
  BusinessHourStatus[BusinessHourStatus["Close"] = 1] = "Close";
5258
5378
  BusinessHourStatus[BusinessHourStatus["ByAppointment"] = 2] = "ByAppointment";
5259
- })(exports.BusinessHourStatus || (exports.BusinessHourStatus = {}));
5379
+ })(BusinessHourStatus || (BusinessHourStatus = {}));
5260
5380
  function createSalon(blob) {
5261
5381
  const geoLocations = blob.salon_geolocation || [];
5262
5382
  let salonImages = [];
@@ -5294,7 +5414,7 @@ function createSalon(blob) {
5294
5414
  };
5295
5415
  }),
5296
5416
  rating: Number(blob.rating_point),
5297
- primaryColor: blob.primary_color || colors.Colors.Primary,
5417
+ primaryColor: blob.primary_color || Colors.Primary,
5298
5418
  salonImages,
5299
5419
  };
5300
5420
  }
@@ -5911,6 +6031,12 @@ const getDefaultEmulatorHostnameAndPort = (productName) => {
5911
6031
  * @public
5912
6032
  */
5913
6033
  const getDefaultAppConfig = () => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.config; };
6034
+ /**
6035
+ * Returns an experimental setting on the __FIREBASE_DEFAULTS__ object (properties
6036
+ * prefixed by "_")
6037
+ * @public
6038
+ */
6039
+ const getExperimentalSetting = (name) => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a[`_${name}`]; };
5914
6040
 
5915
6041
  /**
5916
6042
  * @license
@@ -6056,6 +6182,42 @@ function isMobileCordova() {
6056
6182
  !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&
6057
6183
  /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()));
6058
6184
  }
6185
+ /**
6186
+ * Detect Node.js.
6187
+ *
6188
+ * @return true if Node.js environment is detected or specified.
6189
+ */
6190
+ // Node detection logic from: https://github.com/iliakan/detect-node/
6191
+ function isNode() {
6192
+ var _a;
6193
+ const forceEnvironment = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.forceEnvironment;
6194
+ if (forceEnvironment === 'node') {
6195
+ return true;
6196
+ }
6197
+ else if (forceEnvironment === 'browser') {
6198
+ return false;
6199
+ }
6200
+ try {
6201
+ return (Object.prototype.toString.call(global.process) === '[object process]');
6202
+ }
6203
+ catch (e) {
6204
+ return false;
6205
+ }
6206
+ }
6207
+ /**
6208
+ * Detect Browser Environment
6209
+ */
6210
+ function isBrowser() {
6211
+ return typeof self === 'object' && self.self === self;
6212
+ }
6213
+ function isBrowserExtension() {
6214
+ const runtime = typeof chrome === 'object'
6215
+ ? chrome.runtime
6216
+ : typeof browser === 'object'
6217
+ ? browser.runtime
6218
+ : undefined;
6219
+ return typeof runtime === 'object' && runtime.id !== undefined;
6220
+ }
6059
6221
  /**
6060
6222
  * Detect React Native.
6061
6223
  *
@@ -6064,13 +6226,32 @@ function isMobileCordova() {
6064
6226
  function isReactNative() {
6065
6227
  return (typeof navigator === 'object' && navigator['product'] === 'ReactNative');
6066
6228
  }
6229
+ /** Detects Electron apps. */
6230
+ function isElectron() {
6231
+ return getUA().indexOf('Electron/') >= 0;
6232
+ }
6233
+ /** Detects Internet Explorer. */
6234
+ function isIE() {
6235
+ const ua = getUA();
6236
+ return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
6237
+ }
6238
+ /** Detects Universal Windows Platform apps. */
6239
+ function isUWP() {
6240
+ return getUA().indexOf('MSAppHost/') >= 0;
6241
+ }
6067
6242
  /**
6068
6243
  * Detect whether the current SDK build is the Node version.
6069
6244
  *
6070
6245
  * @return true if it's the Node SDK build.
6071
6246
  */
6072
6247
  function isNodeSdk() {
6073
- return CONSTANTS.NODE_ADMIN === true;
6248
+ return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;
6249
+ }
6250
+ /** Returns true if we are running in Safari. */
6251
+ function isSafari() {
6252
+ return (!isNode() &&
6253
+ navigator.userAgent.includes('Safari') &&
6254
+ !navigator.userAgent.includes('Chrome'));
6074
6255
  }
6075
6256
  /**
6076
6257
  * This method checks if indexedDB is supported by current browser/service worker context
@@ -6118,6 +6299,17 @@ function validateIndexedDBOpenable() {
6118
6299
  }
6119
6300
  });
6120
6301
  }
6302
+ /**
6303
+ *
6304
+ * This method checks whether cookie is enabled within current browser
6305
+ * @return true if cookie is enabled within current browser
6306
+ */
6307
+ function areCookiesEnabled() {
6308
+ if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {
6309
+ return false;
6310
+ }
6311
+ return true;
6312
+ }
6121
6313
 
6122
6314
  /**
6123
6315
  * @license
@@ -6299,6 +6491,53 @@ const decode = function (token) {
6299
6491
  signature
6300
6492
  };
6301
6493
  };
6494
+ /**
6495
+ * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the
6496
+ * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.
6497
+ *
6498
+ * Notes:
6499
+ * - May return a false negative if there's no native base64 decoding support.
6500
+ * - Doesn't check if the token is actually valid.
6501
+ */
6502
+ const isValidTimestamp = function (token) {
6503
+ const claims = decode(token).claims;
6504
+ const now = Math.floor(new Date().getTime() / 1000);
6505
+ let validSince = 0, validUntil = 0;
6506
+ if (typeof claims === 'object') {
6507
+ if (claims.hasOwnProperty('nbf')) {
6508
+ validSince = claims['nbf'];
6509
+ }
6510
+ else if (claims.hasOwnProperty('iat')) {
6511
+ validSince = claims['iat'];
6512
+ }
6513
+ if (claims.hasOwnProperty('exp')) {
6514
+ validUntil = claims['exp'];
6515
+ }
6516
+ else {
6517
+ // token will expire after 24h by default
6518
+ validUntil = validSince + 86400;
6519
+ }
6520
+ }
6521
+ return (!!now &&
6522
+ !!validSince &&
6523
+ !!validUntil &&
6524
+ now >= validSince &&
6525
+ now <= validUntil);
6526
+ };
6527
+ /**
6528
+ * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.
6529
+ *
6530
+ * Notes:
6531
+ * - May return null if there's no native base64 decoding support.
6532
+ * - Doesn't check if the token is actually valid.
6533
+ */
6534
+ const issuedAtTime = function (token) {
6535
+ const claims = decode(token).claims;
6536
+ if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {
6537
+ return claims['iat'];
6538
+ }
6539
+ return null;
6540
+ };
6302
6541
  /**
6303
6542
  * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.
6304
6543
  *
@@ -6401,6 +6640,33 @@ function isObject(thing) {
6401
6640
  return thing !== null && typeof thing === 'object';
6402
6641
  }
6403
6642
 
6643
+ /**
6644
+ * @license
6645
+ * Copyright 2022 Google LLC
6646
+ *
6647
+ * Licensed under the Apache License, Version 2.0 (the "License");
6648
+ * you may not use this file except in compliance with the License.
6649
+ * You may obtain a copy of the License at
6650
+ *
6651
+ * http://www.apache.org/licenses/LICENSE-2.0
6652
+ *
6653
+ * Unless required by applicable law or agreed to in writing, software
6654
+ * distributed under the License is distributed on an "AS IS" BASIS,
6655
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6656
+ * See the License for the specific language governing permissions and
6657
+ * limitations under the License.
6658
+ */
6659
+ /**
6660
+ * Rejects if the given promise doesn't resolve in timeInMS milliseconds.
6661
+ * @internal
6662
+ */
6663
+ function promiseWithTimeout(promise, timeInMS = 2000) {
6664
+ const deferredPromise = new Deferred();
6665
+ setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);
6666
+ promise.then(deferredPromise.resolve, deferredPromise.reject);
6667
+ return deferredPromise.promise;
6668
+ }
6669
+
6404
6670
  /**
6405
6671
  * @license
6406
6672
  * Copyright 2017 Google LLC
@@ -6436,6 +6702,32 @@ function querystring(querystringParams) {
6436
6702
  }
6437
6703
  return params.length ? '&' + params.join('&') : '';
6438
6704
  }
6705
+ /**
6706
+ * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object
6707
+ * (e.g. {arg: 'val', arg2: 'val2'})
6708
+ */
6709
+ function querystringDecode(querystring) {
6710
+ const obj = {};
6711
+ const tokens = querystring.replace(/^\?/, '').split('&');
6712
+ tokens.forEach(token => {
6713
+ if (token) {
6714
+ const [key, value] = token.split('=');
6715
+ obj[decodeURIComponent(key)] = decodeURIComponent(value);
6716
+ }
6717
+ });
6718
+ return obj;
6719
+ }
6720
+ /**
6721
+ * Extract the query string part of a URL, including the leading question mark (if present).
6722
+ */
6723
+ function extractQuerystring(url) {
6724
+ const queryStart = url.indexOf('?');
6725
+ if (!queryStart) {
6726
+ return '';
6727
+ }
6728
+ const fragmentStart = url.indexOf('#', queryStart);
6729
+ return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : undefined);
6730
+ }
6439
6731
 
6440
6732
  /**
6441
6733
  * @license
@@ -6692,61 +6984,352 @@ class Sha1 {
6692
6984
  return digest;
6693
6985
  }
6694
6986
  }
6695
- /**
6696
- * Generates a string to prefix an error message about failed argument validation
6697
- *
6698
- * @param fnName The function name
6699
- * @param argName The name of the argument
6700
- * @return The prefix to add to the error thrown for validation.
6701
- */
6702
- function errorPrefix(fnName, argName) {
6703
- return `${fnName} failed: ${argName} argument `;
6704
- }
6705
6987
 
6706
6988
  /**
6707
- * @license
6708
- * Copyright 2017 Google LLC
6709
- *
6710
- * Licensed under the Apache License, Version 2.0 (the "License");
6711
- * you may not use this file except in compliance with the License.
6712
- * You may obtain a copy of the License at
6713
- *
6714
- * http://www.apache.org/licenses/LICENSE-2.0
6989
+ * Helper to make a Subscribe function (just like Promise helps make a
6990
+ * Thenable).
6715
6991
  *
6716
- * Unless required by applicable law or agreed to in writing, software
6717
- * distributed under the License is distributed on an "AS IS" BASIS,
6718
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6719
- * See the License for the specific language governing permissions and
6720
- * limitations under the License.
6992
+ * @param executor Function which can make calls to a single Observer
6993
+ * as a proxy.
6994
+ * @param onNoObservers Callback when count of Observers goes to zero.
6721
6995
  */
6722
- // Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they
6723
- // automatically replaced '\r\n' with '\n', and they didn't handle surrogate pairs,
6724
- // so it's been modified.
6725
- // Note that not all Unicode characters appear as single characters in JavaScript strings.
6726
- // fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters
6727
- // use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first
6728
- // character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate
6729
- // pair).
6730
- // See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3
6996
+ function createSubscribe(executor, onNoObservers) {
6997
+ const proxy = new ObserverProxy(executor, onNoObservers);
6998
+ return proxy.subscribe.bind(proxy);
6999
+ }
6731
7000
  /**
6732
- * @param {string} str
6733
- * @return {Array}
7001
+ * Implement fan-out for any number of Observers attached via a subscribe
7002
+ * function.
6734
7003
  */
6735
- const stringToByteArray = function (str) {
6736
- const out = [];
6737
- let p = 0;
6738
- for (let i = 0; i < str.length; i++) {
6739
- let c = str.charCodeAt(i);
6740
- // Is this the lead surrogate in a surrogate pair?
6741
- if (c >= 0xd800 && c <= 0xdbff) {
6742
- const high = c - 0xd800; // the high 10 bits.
6743
- i++;
6744
- assert(i < str.length, 'Surrogate pair missing trail surrogate.');
6745
- const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.
6746
- c = 0x10000 + (high << 10) + low;
6747
- }
6748
- if (c < 128) {
6749
- out[p++] = c;
7004
+ class ObserverProxy {
7005
+ /**
7006
+ * @param executor Function which can make calls to a single Observer
7007
+ * as a proxy.
7008
+ * @param onNoObservers Callback when count of Observers goes to zero.
7009
+ */
7010
+ constructor(executor, onNoObservers) {
7011
+ this.observers = [];
7012
+ this.unsubscribes = [];
7013
+ this.observerCount = 0;
7014
+ // Micro-task scheduling by calling task.then().
7015
+ this.task = Promise.resolve();
7016
+ this.finalized = false;
7017
+ this.onNoObservers = onNoObservers;
7018
+ // Call the executor asynchronously so subscribers that are called
7019
+ // synchronously after the creation of the subscribe function
7020
+ // can still receive the very first value generated in the executor.
7021
+ this.task
7022
+ .then(() => {
7023
+ executor(this);
7024
+ })
7025
+ .catch(e => {
7026
+ this.error(e);
7027
+ });
7028
+ }
7029
+ next(value) {
7030
+ this.forEachObserver((observer) => {
7031
+ observer.next(value);
7032
+ });
7033
+ }
7034
+ error(error) {
7035
+ this.forEachObserver((observer) => {
7036
+ observer.error(error);
7037
+ });
7038
+ this.close(error);
7039
+ }
7040
+ complete() {
7041
+ this.forEachObserver((observer) => {
7042
+ observer.complete();
7043
+ });
7044
+ this.close();
7045
+ }
7046
+ /**
7047
+ * Subscribe function that can be used to add an Observer to the fan-out list.
7048
+ *
7049
+ * - We require that no event is sent to a subscriber sychronously to their
7050
+ * call to subscribe().
7051
+ */
7052
+ subscribe(nextOrObserver, error, complete) {
7053
+ let observer;
7054
+ if (nextOrObserver === undefined &&
7055
+ error === undefined &&
7056
+ complete === undefined) {
7057
+ throw new Error('Missing Observer.');
7058
+ }
7059
+ // Assemble an Observer object when passed as callback functions.
7060
+ if (implementsAnyMethods(nextOrObserver, [
7061
+ 'next',
7062
+ 'error',
7063
+ 'complete'
7064
+ ])) {
7065
+ observer = nextOrObserver;
7066
+ }
7067
+ else {
7068
+ observer = {
7069
+ next: nextOrObserver,
7070
+ error,
7071
+ complete
7072
+ };
7073
+ }
7074
+ if (observer.next === undefined) {
7075
+ observer.next = noop;
7076
+ }
7077
+ if (observer.error === undefined) {
7078
+ observer.error = noop;
7079
+ }
7080
+ if (observer.complete === undefined) {
7081
+ observer.complete = noop;
7082
+ }
7083
+ const unsub = this.unsubscribeOne.bind(this, this.observers.length);
7084
+ // Attempt to subscribe to a terminated Observable - we
7085
+ // just respond to the Observer with the final error or complete
7086
+ // event.
7087
+ if (this.finalized) {
7088
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
7089
+ this.task.then(() => {
7090
+ try {
7091
+ if (this.finalError) {
7092
+ observer.error(this.finalError);
7093
+ }
7094
+ else {
7095
+ observer.complete();
7096
+ }
7097
+ }
7098
+ catch (e) {
7099
+ // nothing
7100
+ }
7101
+ return;
7102
+ });
7103
+ }
7104
+ this.observers.push(observer);
7105
+ return unsub;
7106
+ }
7107
+ // Unsubscribe is synchronous - we guarantee that no events are sent to
7108
+ // any unsubscribed Observer.
7109
+ unsubscribeOne(i) {
7110
+ if (this.observers === undefined || this.observers[i] === undefined) {
7111
+ return;
7112
+ }
7113
+ delete this.observers[i];
7114
+ this.observerCount -= 1;
7115
+ if (this.observerCount === 0 && this.onNoObservers !== undefined) {
7116
+ this.onNoObservers(this);
7117
+ }
7118
+ }
7119
+ forEachObserver(fn) {
7120
+ if (this.finalized) {
7121
+ // Already closed by previous event....just eat the additional values.
7122
+ return;
7123
+ }
7124
+ // Since sendOne calls asynchronously - there is no chance that
7125
+ // this.observers will become undefined.
7126
+ for (let i = 0; i < this.observers.length; i++) {
7127
+ this.sendOne(i, fn);
7128
+ }
7129
+ }
7130
+ // Call the Observer via one of it's callback function. We are careful to
7131
+ // confirm that the observe has not been unsubscribed since this asynchronous
7132
+ // function had been queued.
7133
+ sendOne(i, fn) {
7134
+ // Execute the callback asynchronously
7135
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
7136
+ this.task.then(() => {
7137
+ if (this.observers !== undefined && this.observers[i] !== undefined) {
7138
+ try {
7139
+ fn(this.observers[i]);
7140
+ }
7141
+ catch (e) {
7142
+ // Ignore exceptions raised in Observers or missing methods of an
7143
+ // Observer.
7144
+ // Log error to console. b/31404806
7145
+ if (typeof console !== 'undefined' && console.error) {
7146
+ console.error(e);
7147
+ }
7148
+ }
7149
+ }
7150
+ });
7151
+ }
7152
+ close(err) {
7153
+ if (this.finalized) {
7154
+ return;
7155
+ }
7156
+ this.finalized = true;
7157
+ if (err !== undefined) {
7158
+ this.finalError = err;
7159
+ }
7160
+ // Proxy is no longer needed - garbage collect references
7161
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
7162
+ this.task.then(() => {
7163
+ this.observers = undefined;
7164
+ this.onNoObservers = undefined;
7165
+ });
7166
+ }
7167
+ }
7168
+ /** Turn synchronous function into one called asynchronously. */
7169
+ // eslint-disable-next-line @typescript-eslint/ban-types
7170
+ function async(fn, onError) {
7171
+ return (...args) => {
7172
+ Promise.resolve(true)
7173
+ .then(() => {
7174
+ fn(...args);
7175
+ })
7176
+ .catch((error) => {
7177
+ if (onError) {
7178
+ onError(error);
7179
+ }
7180
+ });
7181
+ };
7182
+ }
7183
+ /**
7184
+ * Return true if the object passed in implements any of the named methods.
7185
+ */
7186
+ function implementsAnyMethods(obj, methods) {
7187
+ if (typeof obj !== 'object' || obj === null) {
7188
+ return false;
7189
+ }
7190
+ for (const method of methods) {
7191
+ if (method in obj && typeof obj[method] === 'function') {
7192
+ return true;
7193
+ }
7194
+ }
7195
+ return false;
7196
+ }
7197
+ function noop() {
7198
+ // do nothing
7199
+ }
7200
+
7201
+ /**
7202
+ * @license
7203
+ * Copyright 2017 Google LLC
7204
+ *
7205
+ * Licensed under the Apache License, Version 2.0 (the "License");
7206
+ * you may not use this file except in compliance with the License.
7207
+ * You may obtain a copy of the License at
7208
+ *
7209
+ * http://www.apache.org/licenses/LICENSE-2.0
7210
+ *
7211
+ * Unless required by applicable law or agreed to in writing, software
7212
+ * distributed under the License is distributed on an "AS IS" BASIS,
7213
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7214
+ * See the License for the specific language governing permissions and
7215
+ * limitations under the License.
7216
+ */
7217
+ /**
7218
+ * Check to make sure the appropriate number of arguments are provided for a public function.
7219
+ * Throws an error if it fails.
7220
+ *
7221
+ * @param fnName The function name
7222
+ * @param minCount The minimum number of arguments to allow for the function call
7223
+ * @param maxCount The maximum number of argument to allow for the function call
7224
+ * @param argCount The actual number of arguments provided.
7225
+ */
7226
+ const validateArgCount = function (fnName, minCount, maxCount, argCount) {
7227
+ let argError;
7228
+ if (argCount < minCount) {
7229
+ argError = 'at least ' + minCount;
7230
+ }
7231
+ else if (argCount > maxCount) {
7232
+ argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;
7233
+ }
7234
+ if (argError) {
7235
+ const error = fnName +
7236
+ ' failed: Was called with ' +
7237
+ argCount +
7238
+ (argCount === 1 ? ' argument.' : ' arguments.') +
7239
+ ' Expects ' +
7240
+ argError +
7241
+ '.';
7242
+ throw new Error(error);
7243
+ }
7244
+ };
7245
+ /**
7246
+ * Generates a string to prefix an error message about failed argument validation
7247
+ *
7248
+ * @param fnName The function name
7249
+ * @param argName The name of the argument
7250
+ * @return The prefix to add to the error thrown for validation.
7251
+ */
7252
+ function errorPrefix(fnName, argName) {
7253
+ return `${fnName} failed: ${argName} argument `;
7254
+ }
7255
+ /**
7256
+ * @param fnName
7257
+ * @param argumentNumber
7258
+ * @param namespace
7259
+ * @param optional
7260
+ */
7261
+ function validateNamespace(fnName, namespace, optional) {
7262
+ if (optional && !namespace) {
7263
+ return;
7264
+ }
7265
+ if (typeof namespace !== 'string') {
7266
+ //TODO: I should do more validation here. We only allow certain chars in namespaces.
7267
+ throw new Error(errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.');
7268
+ }
7269
+ }
7270
+ function validateCallback(fnName, argumentName,
7271
+ // eslint-disable-next-line @typescript-eslint/ban-types
7272
+ callback, optional) {
7273
+ if (optional && !callback) {
7274
+ return;
7275
+ }
7276
+ if (typeof callback !== 'function') {
7277
+ throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid function.');
7278
+ }
7279
+ }
7280
+ function validateContextObject(fnName, argumentName, context, optional) {
7281
+ if (optional && !context) {
7282
+ return;
7283
+ }
7284
+ if (typeof context !== 'object' || context === null) {
7285
+ throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid context object.');
7286
+ }
7287
+ }
7288
+
7289
+ /**
7290
+ * @license
7291
+ * Copyright 2017 Google LLC
7292
+ *
7293
+ * Licensed under the Apache License, Version 2.0 (the "License");
7294
+ * you may not use this file except in compliance with the License.
7295
+ * You may obtain a copy of the License at
7296
+ *
7297
+ * http://www.apache.org/licenses/LICENSE-2.0
7298
+ *
7299
+ * Unless required by applicable law or agreed to in writing, software
7300
+ * distributed under the License is distributed on an "AS IS" BASIS,
7301
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7302
+ * See the License for the specific language governing permissions and
7303
+ * limitations under the License.
7304
+ */
7305
+ // Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they
7306
+ // automatically replaced '\r\n' with '\n', and they didn't handle surrogate pairs,
7307
+ // so it's been modified.
7308
+ // Note that not all Unicode characters appear as single characters in JavaScript strings.
7309
+ // fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters
7310
+ // use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first
7311
+ // character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate
7312
+ // pair).
7313
+ // See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3
7314
+ /**
7315
+ * @param {string} str
7316
+ * @return {Array}
7317
+ */
7318
+ const stringToByteArray = function (str) {
7319
+ const out = [];
7320
+ let p = 0;
7321
+ for (let i = 0; i < str.length; i++) {
7322
+ let c = str.charCodeAt(i);
7323
+ // Is this the lead surrogate in a surrogate pair?
7324
+ if (c >= 0xd800 && c <= 0xdbff) {
7325
+ const high = c - 0xd800; // the high 10 bits.
7326
+ i++;
7327
+ assert(i < str.length, 'Surrogate pair missing trail surrogate.');
7328
+ const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.
7329
+ c = 0x10000 + (high << 10) + low;
7330
+ }
7331
+ if (c < 128) {
7332
+ out[p++] = c;
6750
7333
  }
6751
7334
  else if (c < 2048) {
6752
7335
  out[p++] = (c >> 6) | 192;
@@ -6793,6 +7376,143 @@ const stringLength = function (str) {
6793
7376
  return p;
6794
7377
  };
6795
7378
 
7379
+ /**
7380
+ * @license
7381
+ * Copyright 2022 Google LLC
7382
+ *
7383
+ * Licensed under the Apache License, Version 2.0 (the "License");
7384
+ * you may not use this file except in compliance with the License.
7385
+ * You may obtain a copy of the License at
7386
+ *
7387
+ * http://www.apache.org/licenses/LICENSE-2.0
7388
+ *
7389
+ * Unless required by applicable law or agreed to in writing, software
7390
+ * distributed under the License is distributed on an "AS IS" BASIS,
7391
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7392
+ * See the License for the specific language governing permissions and
7393
+ * limitations under the License.
7394
+ */
7395
+ /**
7396
+ * Copied from https://stackoverflow.com/a/2117523
7397
+ * Generates a new uuid.
7398
+ * @public
7399
+ */
7400
+ const uuidv4 = function () {
7401
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
7402
+ const r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8;
7403
+ return v.toString(16);
7404
+ });
7405
+ };
7406
+
7407
+ /**
7408
+ * @license
7409
+ * Copyright 2019 Google LLC
7410
+ *
7411
+ * Licensed under the Apache License, Version 2.0 (the "License");
7412
+ * you may not use this file except in compliance with the License.
7413
+ * You may obtain a copy of the License at
7414
+ *
7415
+ * http://www.apache.org/licenses/LICENSE-2.0
7416
+ *
7417
+ * Unless required by applicable law or agreed to in writing, software
7418
+ * distributed under the License is distributed on an "AS IS" BASIS,
7419
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7420
+ * See the License for the specific language governing permissions and
7421
+ * limitations under the License.
7422
+ */
7423
+ /**
7424
+ * The amount of milliseconds to exponentially increase.
7425
+ */
7426
+ const DEFAULT_INTERVAL_MILLIS = 1000;
7427
+ /**
7428
+ * The factor to backoff by.
7429
+ * Should be a number greater than 1.
7430
+ */
7431
+ const DEFAULT_BACKOFF_FACTOR = 2;
7432
+ /**
7433
+ * The maximum milliseconds to increase to.
7434
+ *
7435
+ * <p>Visible for testing
7436
+ */
7437
+ const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.
7438
+ /**
7439
+ * The percentage of backoff time to randomize by.
7440
+ * See
7441
+ * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic
7442
+ * for context.
7443
+ *
7444
+ * <p>Visible for testing
7445
+ */
7446
+ const RANDOM_FACTOR = 0.5;
7447
+ /**
7448
+ * Based on the backoff method from
7449
+ * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.
7450
+ * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.
7451
+ */
7452
+ function calculateBackoffMillis(backoffCount, intervalMillis = DEFAULT_INTERVAL_MILLIS, backoffFactor = DEFAULT_BACKOFF_FACTOR) {
7453
+ // Calculates an exponentially increasing value.
7454
+ // Deviation: calculates value from count and a constant interval, so we only need to save value
7455
+ // and count to restore state.
7456
+ const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);
7457
+ // A random "fuzz" to avoid waves of retries.
7458
+ // Deviation: randomFactor is required.
7459
+ const randomWait = Math.round(
7460
+ // A fraction of the backoff value to add/subtract.
7461
+ // Deviation: changes multiplication order to improve readability.
7462
+ RANDOM_FACTOR *
7463
+ currBaseValue *
7464
+ // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines
7465
+ // if we add or subtract.
7466
+ (Math.random() - 0.5) *
7467
+ 2);
7468
+ // Limits backoff to max to avoid effectively permanent backoff.
7469
+ return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);
7470
+ }
7471
+
7472
+ /**
7473
+ * @license
7474
+ * Copyright 2020 Google LLC
7475
+ *
7476
+ * Licensed under the Apache License, Version 2.0 (the "License");
7477
+ * you may not use this file except in compliance with the License.
7478
+ * You may obtain a copy of the License at
7479
+ *
7480
+ * http://www.apache.org/licenses/LICENSE-2.0
7481
+ *
7482
+ * Unless required by applicable law or agreed to in writing, software
7483
+ * distributed under the License is distributed on an "AS IS" BASIS,
7484
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7485
+ * See the License for the specific language governing permissions and
7486
+ * limitations under the License.
7487
+ */
7488
+ /**
7489
+ * Provide English ordinal letters after a number
7490
+ */
7491
+ function ordinal(i) {
7492
+ if (!Number.isFinite(i)) {
7493
+ return `${i}`;
7494
+ }
7495
+ return i + indicator(i);
7496
+ }
7497
+ function indicator(i) {
7498
+ i = Math.abs(i);
7499
+ const cent = i % 100;
7500
+ if (cent >= 10 && cent <= 20) {
7501
+ return 'th';
7502
+ }
7503
+ const dec = i % 10;
7504
+ if (dec === 1) {
7505
+ return 'st';
7506
+ }
7507
+ if (dec === 2) {
7508
+ return 'nd';
7509
+ }
7510
+ if (dec === 3) {
7511
+ return 'rd';
7512
+ }
7513
+ return 'th';
7514
+ }
7515
+
6796
7516
  /**
6797
7517
  * @license
6798
7518
  * Copyright 2021 Google LLC
@@ -7239,6 +7959,10 @@ class ComponentContainer {
7239
7959
  * See the License for the specific language governing permissions and
7240
7960
  * limitations under the License.
7241
7961
  */
7962
+ /**
7963
+ * A container for all of the Logger instances
7964
+ */
7965
+ const instances = [];
7242
7966
  /**
7243
7967
  * The JS SDK supports 5 log levels and also allows a user the ability to
7244
7968
  * silence the logs altogether.
@@ -7324,6 +8048,10 @@ class Logger {
7324
8048
  * The optional, additional, user-defined log handler for the Logger instance.
7325
8049
  */
7326
8050
  this._userLogHandler = null;
8051
+ /**
8052
+ * Capture the current instance for later use
8053
+ */
8054
+ instances.push(this);
7327
8055
  }
7328
8056
  get logLevel() {
7329
8057
  return this._logLevel;
@@ -7377,21 +8105,74 @@ class Logger {
7377
8105
  this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);
7378
8106
  this._logHandler(this, LogLevel.ERROR, ...args);
7379
8107
  }
7380
- }
7381
-
7382
- const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
7383
-
7384
- let idbProxyableTypes;
7385
- let cursorAdvanceMethods;
7386
- // This is a function to prevent it throwing up in node environments.
7387
- function getIdbProxyableTypes() {
7388
- return (idbProxyableTypes ||
7389
- (idbProxyableTypes = [
7390
- IDBDatabase,
7391
- IDBObjectStore,
7392
- IDBIndex,
7393
- IDBCursor,
7394
- IDBTransaction,
8108
+ }
8109
+ function setLogLevel$1(level) {
8110
+ instances.forEach(inst => {
8111
+ inst.setLogLevel(level);
8112
+ });
8113
+ }
8114
+ function setUserLogHandler(logCallback, options) {
8115
+ for (const instance of instances) {
8116
+ let customLogLevel = null;
8117
+ if (options && options.level) {
8118
+ customLogLevel = levelStringToEnum[options.level];
8119
+ }
8120
+ if (logCallback === null) {
8121
+ instance.userLogHandler = null;
8122
+ }
8123
+ else {
8124
+ instance.userLogHandler = (instance, level, ...args) => {
8125
+ const message = args
8126
+ .map(arg => {
8127
+ if (arg == null) {
8128
+ return null;
8129
+ }
8130
+ else if (typeof arg === 'string') {
8131
+ return arg;
8132
+ }
8133
+ else if (typeof arg === 'number' || typeof arg === 'boolean') {
8134
+ return arg.toString();
8135
+ }
8136
+ else if (arg instanceof Error) {
8137
+ return arg.message;
8138
+ }
8139
+ else {
8140
+ try {
8141
+ return JSON.stringify(arg);
8142
+ }
8143
+ catch (ignored) {
8144
+ return null;
8145
+ }
8146
+ }
8147
+ })
8148
+ .filter(arg => arg)
8149
+ .join(' ');
8150
+ if (level >= (customLogLevel !== null && customLogLevel !== void 0 ? customLogLevel : instance.logLevel)) {
8151
+ logCallback({
8152
+ level: LogLevel[level].toLowerCase(),
8153
+ message,
8154
+ args,
8155
+ type: instance.name
8156
+ });
8157
+ }
8158
+ };
8159
+ }
8160
+ }
8161
+ }
8162
+
8163
+ const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
8164
+
8165
+ let idbProxyableTypes;
8166
+ let cursorAdvanceMethods;
8167
+ // This is a function to prevent it throwing up in node environments.
8168
+ function getIdbProxyableTypes() {
8169
+ return (idbProxyableTypes ||
8170
+ (idbProxyableTypes = [
8171
+ IDBDatabase,
8172
+ IDBObjectStore,
8173
+ IDBIndex,
8174
+ IDBCursor,
8175
+ IDBTransaction,
7395
8176
  ]));
7396
8177
  }
7397
8178
  // This is a function to prevent it throwing up in node environments.
@@ -7594,6 +8375,20 @@ function openDB(name, version, { blocked, upgrade, blocking, terminated } = {})
7594
8375
  .catch(() => { });
7595
8376
  return openPromise;
7596
8377
  }
8378
+ /**
8379
+ * Delete a database.
8380
+ *
8381
+ * @param name Name of the database.
8382
+ */
8383
+ function deleteDB(name, { blocked } = {}) {
8384
+ const request = indexedDB.deleteDatabase(name);
8385
+ if (blocked) {
8386
+ request.addEventListener('blocked', (event) => blocked(
8387
+ // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
8388
+ event.oldVersion, event));
8389
+ }
8390
+ return wrap(request).then(() => undefined);
8391
+ }
7597
8392
 
7598
8393
  const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
7599
8394
  const writeMethods = ['put', 'add', 'delete', 'clear'];
@@ -7854,6 +8649,13 @@ function _addComponent(app, component) {
7854
8649
  logger$1.debug(`Component ${component.name} failed to register with FirebaseApp ${app.name}`, e);
7855
8650
  }
7856
8651
  }
8652
+ /**
8653
+ *
8654
+ * @internal
8655
+ */
8656
+ function _addOrOverwriteComponent(app, component) {
8657
+ app.container.addOrOverwriteComponent(component);
8658
+ }
7857
8659
  /**
7858
8660
  *
7859
8661
  * @param component - the component to register
@@ -7892,6 +8694,25 @@ function _getProvider(app, name) {
7892
8694
  }
7893
8695
  return app.container.getProvider(name);
7894
8696
  }
8697
+ /**
8698
+ *
8699
+ * @param app - FirebaseApp instance
8700
+ * @param name - service name
8701
+ * @param instanceIdentifier - service instance identifier in case the service supports multiple instances
8702
+ *
8703
+ * @internal
8704
+ */
8705
+ function _removeServiceInstance(app, name, instanceIdentifier = DEFAULT_ENTRY_NAME) {
8706
+ _getProvider(app, name).clearInstance(instanceIdentifier);
8707
+ }
8708
+ /**
8709
+ * Test only
8710
+ *
8711
+ * @internal
8712
+ */
8713
+ function _clearComponents() {
8714
+ _components.clear();
8715
+ }
7895
8716
 
7896
8717
  /**
7897
8718
  * @license
@@ -8090,6 +8911,40 @@ function getApp(name = DEFAULT_ENTRY_NAME) {
8090
8911
  }
8091
8912
  return app;
8092
8913
  }
8914
+ /**
8915
+ * A (read-only) array of all initialized apps.
8916
+ * @public
8917
+ */
8918
+ function getApps() {
8919
+ return Array.from(_apps.values());
8920
+ }
8921
+ /**
8922
+ * Renders this app unusable and frees the resources of all associated
8923
+ * services.
8924
+ *
8925
+ * @example
8926
+ * ```javascript
8927
+ * deleteApp(app)
8928
+ * .then(function() {
8929
+ * console.log("App deleted successfully");
8930
+ * })
8931
+ * .catch(function(error) {
8932
+ * console.log("Error deleting app:", error);
8933
+ * });
8934
+ * ```
8935
+ *
8936
+ * @public
8937
+ */
8938
+ async function deleteApp(app) {
8939
+ const name = app.name;
8940
+ if (_apps.has(name)) {
8941
+ _apps.delete(name);
8942
+ await Promise.all(app.container
8943
+ .getProviders()
8944
+ .map(provider => provider.delete()));
8945
+ app.isDeleted = true;
8946
+ }
8947
+ }
8093
8948
  /**
8094
8949
  * Registers a library's name and version for platform logging purposes.
8095
8950
  * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)
@@ -8126,6 +8981,31 @@ function registerVersion(libraryKeyOrName, version, variant) {
8126
8981
  }
8127
8982
  _registerComponent(new Component(`${library}-version`, () => ({ library, version }), "VERSION" /* ComponentType.VERSION */));
8128
8983
  }
8984
+ /**
8985
+ * Sets log handler for all Firebase SDKs.
8986
+ * @param logCallback - An optional custom log handler that executes user code whenever
8987
+ * the Firebase SDK makes a logging call.
8988
+ *
8989
+ * @public
8990
+ */
8991
+ function onLog(logCallback, options) {
8992
+ if (logCallback !== null && typeof logCallback !== 'function') {
8993
+ throw ERROR_FACTORY.create("invalid-log-argument" /* AppError.INVALID_LOG_ARGUMENT */);
8994
+ }
8995
+ setUserLogHandler(logCallback, options);
8996
+ }
8997
+ /**
8998
+ * Sets log level for all Firebase SDKs.
8999
+ *
9000
+ * All of the log types above the current log level are captured (i.e. if
9001
+ * you set the log level to `info`, errors are logged, but `debug` and
9002
+ * `verbose` logs are not).
9003
+ *
9004
+ * @public
9005
+ */
9006
+ function setLogLevel(logLevel) {
9007
+ setLogLevel$1(logLevel);
9008
+ }
8129
9009
 
8130
9010
  /**
8131
9011
  * @license
@@ -8835,7 +9715,7 @@ const isInvalidJSONNumber = function (data) {
8835
9715
  data === Number.NEGATIVE_INFINITY));
8836
9716
  };
8837
9717
  const executeWhenDOMReady = function (fn) {
8838
- if (document.readyState === 'complete') {
9718
+ if (isNodeSdk() || document.readyState === 'complete') {
8839
9719
  fn();
8840
9720
  }
8841
9721
  else {
@@ -9847,7 +10727,10 @@ class BrowserPollConnection {
9847
10727
  }
9848
10728
  // Static method, use string literal so it can be accessed in a generic way
9849
10729
  static isAvailable() {
9850
- if (BrowserPollConnection.forceAllow_) {
10730
+ if (isNodeSdk()) {
10731
+ return false;
10732
+ }
10733
+ else if (BrowserPollConnection.forceAllow_) {
9851
10734
  return true;
9852
10735
  }
9853
10736
  else {
@@ -9933,6 +10816,9 @@ class BrowserPollConnection {
9933
10816
  * trigger XHR requests in some browsers (everything but Opera basically).
9934
10817
  */
9935
10818
  addDisconnectPingFrame(id, pw) {
10819
+ if (isNodeSdk()) {
10820
+ return;
10821
+ }
9936
10822
  this.myDisconnFrame = document.createElement('iframe');
9937
10823
  const urlParams = {};
9938
10824
  urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = 't';
@@ -9979,7 +10865,7 @@ class FirebaseIFrameScriptHolder {
9979
10865
  // This gets set to false when we're "closing down" the connection (e.g. we're switching transports but there's still
9980
10866
  // incoming data from the server that we're waiting for).
9981
10867
  this.sendNewPolls = true;
9982
- {
10868
+ if (!isNodeSdk()) {
9983
10869
  //Each script holder registers a couple of uniquely named callbacks with the window. These are called from the
9984
10870
  //iframes where we put the long-polling script tags. We have two callbacks:
9985
10871
  // 1) Command Callback - Triggered for control issues, like starting a connection.
@@ -10013,6 +10899,10 @@ class FirebaseIFrameScriptHolder {
10013
10899
  log(e);
10014
10900
  }
10015
10901
  }
10902
+ else {
10903
+ this.commandCB = commandCB;
10904
+ this.onMessageCB = onMessageCB;
10905
+ }
10016
10906
  }
10017
10907
  /**
10018
10908
  * Each browser has its own funny way to handle iframes. Here we mush them all together into one object that I can
@@ -10206,7 +11096,11 @@ class FirebaseIFrameScriptHolder {
10206
11096
  * @param loadCB - A callback to be triggered once the script has loaded.
10207
11097
  */
10208
11098
  addTag(url, loadCB) {
10209
- {
11099
+ if (isNodeSdk()) {
11100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11101
+ this.doNodeLongPoll(url, loadCB);
11102
+ }
11103
+ else {
10210
11104
  setTimeout(() => {
10211
11105
  try {
10212
11106
  // if we're already closed, don't add this poll
@@ -10311,7 +11205,8 @@ class WebSocketConnection {
10311
11205
  static connectionURL_(repoInfo, transportSessionId, lastSessionId, appCheckToken, applicationId) {
10312
11206
  const urlParams = {};
10313
11207
  urlParams[VERSION_PARAM] = PROTOCOL_VERSION;
10314
- if (typeof location !== 'undefined' &&
11208
+ if (!isNodeSdk() &&
11209
+ typeof location !== 'undefined' &&
10315
11210
  location.hostname &&
10316
11211
  FORGE_DOMAIN_RE.test(location.hostname)) {
10317
11212
  urlParams[REFERER_PARAM] = FORGE_REF;
@@ -10343,6 +11238,35 @@ class WebSocketConnection {
10343
11238
  PersistentStorage.set('previous_websocket_failure', true);
10344
11239
  try {
10345
11240
  let options;
11241
+ if (isNodeSdk()) {
11242
+ const device = this.nodeAdmin ? 'AdminNode' : 'Node';
11243
+ // UA Format: Firebase/<wire_protocol>/<sdk_version>/<platform>/<device>
11244
+ options = {
11245
+ headers: {
11246
+ 'User-Agent': `Firebase/${PROTOCOL_VERSION}/${SDK_VERSION}/${process.platform}/${device}`,
11247
+ 'X-Firebase-GMPID': this.applicationId || ''
11248
+ }
11249
+ };
11250
+ // If using Node with admin creds, AppCheck-related checks are unnecessary.
11251
+ // Note that we send the credentials here even if they aren't admin credentials, which is
11252
+ // not a problem.
11253
+ // Note that this header is just used to bypass appcheck, and the token should still be sent
11254
+ // through the websocket connection once it is established.
11255
+ if (this.authToken) {
11256
+ options.headers['Authorization'] = `Bearer ${this.authToken}`;
11257
+ }
11258
+ if (this.appCheckToken) {
11259
+ options.headers['X-Firebase-AppCheck'] = this.appCheckToken;
11260
+ }
11261
+ // Plumb appropriate http_proxy environment variable into faye-websocket if it exists.
11262
+ const env = process['env'];
11263
+ const proxy = this.connURL.indexOf('wss://') === 0
11264
+ ? env['HTTPS_PROXY'] || env['https_proxy']
11265
+ : env['HTTP_PROXY'] || env['http_proxy'];
11266
+ if (proxy) {
11267
+ options['proxy'] = { origin: proxy };
11268
+ }
11269
+ }
10346
11270
  this.mySock = new WebSocketImpl(this.connURL, [], options);
10347
11271
  }
10348
11272
  catch (e) {
@@ -12417,6 +13341,14 @@ class PersistentConnection extends ServerActions {
12417
13341
  sendConnectStats_() {
12418
13342
  const stats = {};
12419
13343
  let clientName = 'js';
13344
+ if (isNodeSdk()) {
13345
+ if (this.repoInfo_.nodeAdmin) {
13346
+ clientName = 'admin_node';
13347
+ }
13348
+ else {
13349
+ clientName = 'node';
13350
+ }
13351
+ }
12420
13352
  stats['sdk.' + clientName + '.' + SDK_VERSION.replace(/\./g, '-')] = 1;
12421
13353
  if (isMobileCordova()) {
12422
13354
  stats['framework.cordova'] = 1;
@@ -15012,6 +15944,81 @@ function queryParamsGetNodeFilter(queryParams) {
15012
15944
  return new RangedFilter(queryParams);
15013
15945
  }
15014
15946
  }
15947
+ function queryParamsLimitToFirst(queryParams, newLimit) {
15948
+ const newParams = queryParams.copy();
15949
+ newParams.limitSet_ = true;
15950
+ newParams.limit_ = newLimit;
15951
+ newParams.viewFrom_ = "l" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT */;
15952
+ return newParams;
15953
+ }
15954
+ function queryParamsLimitToLast(queryParams, newLimit) {
15955
+ const newParams = queryParams.copy();
15956
+ newParams.limitSet_ = true;
15957
+ newParams.limit_ = newLimit;
15958
+ newParams.viewFrom_ = "r" /* WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT */;
15959
+ return newParams;
15960
+ }
15961
+ function queryParamsStartAt(queryParams, indexValue, key) {
15962
+ const newParams = queryParams.copy();
15963
+ newParams.startSet_ = true;
15964
+ if (indexValue === undefined) {
15965
+ indexValue = null;
15966
+ }
15967
+ newParams.indexStartValue_ = indexValue;
15968
+ if (key != null) {
15969
+ newParams.startNameSet_ = true;
15970
+ newParams.indexStartName_ = key;
15971
+ }
15972
+ else {
15973
+ newParams.startNameSet_ = false;
15974
+ newParams.indexStartName_ = '';
15975
+ }
15976
+ return newParams;
15977
+ }
15978
+ function queryParamsStartAfter(queryParams, indexValue, key) {
15979
+ let params;
15980
+ if (queryParams.index_ === KEY_INDEX || !!key) {
15981
+ params = queryParamsStartAt(queryParams, indexValue, key);
15982
+ }
15983
+ else {
15984
+ params = queryParamsStartAt(queryParams, indexValue, MAX_NAME);
15985
+ }
15986
+ params.startAfterSet_ = true;
15987
+ return params;
15988
+ }
15989
+ function queryParamsEndAt(queryParams, indexValue, key) {
15990
+ const newParams = queryParams.copy();
15991
+ newParams.endSet_ = true;
15992
+ if (indexValue === undefined) {
15993
+ indexValue = null;
15994
+ }
15995
+ newParams.indexEndValue_ = indexValue;
15996
+ if (key !== undefined) {
15997
+ newParams.endNameSet_ = true;
15998
+ newParams.indexEndName_ = key;
15999
+ }
16000
+ else {
16001
+ newParams.endNameSet_ = false;
16002
+ newParams.indexEndName_ = '';
16003
+ }
16004
+ return newParams;
16005
+ }
16006
+ function queryParamsEndBefore(queryParams, indexValue, key) {
16007
+ let params;
16008
+ if (queryParams.index_ === KEY_INDEX || !!key) {
16009
+ params = queryParamsEndAt(queryParams, indexValue, key);
16010
+ }
16011
+ else {
16012
+ params = queryParamsEndAt(queryParams, indexValue, MIN_NAME);
16013
+ }
16014
+ params.endBeforeSet_ = true;
16015
+ return params;
16016
+ }
16017
+ function queryParamsOrderBy(queryParams, index) {
16018
+ const newParams = queryParams.copy();
16019
+ newParams.index_ = index;
16020
+ return newParams;
16021
+ }
15015
16022
  /**
15016
16023
  * Returns a set of REST query string parameters representing this query.
15017
16024
  *
@@ -15359,6 +16366,49 @@ function sparseSnapshotTreeRemember(sparseSnapshotTree, path, data) {
15359
16366
  sparseSnapshotTreeRemember(child, path, data);
15360
16367
  }
15361
16368
  }
16369
+ /**
16370
+ * Purge the data at path from the cache.
16371
+ *
16372
+ * @param path - Path to look up snapshot for.
16373
+ * @returns True if this node should now be removed.
16374
+ */
16375
+ function sparseSnapshotTreeForget(sparseSnapshotTree, path) {
16376
+ if (pathIsEmpty(path)) {
16377
+ sparseSnapshotTree.value = null;
16378
+ sparseSnapshotTree.children.clear();
16379
+ return true;
16380
+ }
16381
+ else {
16382
+ if (sparseSnapshotTree.value !== null) {
16383
+ if (sparseSnapshotTree.value.isLeafNode()) {
16384
+ // We're trying to forget a node that doesn't exist
16385
+ return false;
16386
+ }
16387
+ else {
16388
+ const value = sparseSnapshotTree.value;
16389
+ sparseSnapshotTree.value = null;
16390
+ value.forEachChild(PRIORITY_INDEX, (key, tree) => {
16391
+ sparseSnapshotTreeRemember(sparseSnapshotTree, new Path(key), tree);
16392
+ });
16393
+ return sparseSnapshotTreeForget(sparseSnapshotTree, path);
16394
+ }
16395
+ }
16396
+ else if (sparseSnapshotTree.children.size > 0) {
16397
+ const childKey = pathGetFront(path);
16398
+ path = pathPopFront(path);
16399
+ if (sparseSnapshotTree.children.has(childKey)) {
16400
+ const safeToRemove = sparseSnapshotTreeForget(sparseSnapshotTree.children.get(childKey), path);
16401
+ if (safeToRemove) {
16402
+ sparseSnapshotTree.children.delete(childKey);
16403
+ }
16404
+ }
16405
+ return sparseSnapshotTree.children.size === 0;
16406
+ }
16407
+ else {
16408
+ return true;
16409
+ }
16410
+ }
16411
+ }
15362
16412
  /**
15363
16413
  * Recursively iterates through all of the stored tree and calls the
15364
16414
  * callback on each one.
@@ -17478,6 +18528,9 @@ class View {
17478
18528
  function viewGetServerCache(view) {
17479
18529
  return view.viewCache_.serverCache.getNode();
17480
18530
  }
18531
+ function viewGetCompleteNode(view) {
18532
+ return viewCacheGetCompleteEventSnap(view.viewCache_);
18533
+ }
17481
18534
  function viewGetCompleteServerCache(view, path) {
17482
18535
  const cache = viewCacheGetCompleteServerSnap(view.viewCache_);
17483
18536
  if (cache) {
@@ -18150,6 +19203,33 @@ function syncTreeCalcCompleteEventCache(syncTree, path, writeIdsToExclude) {
18150
19203
  });
18151
19204
  return writeTreeCalcCompleteEventCache(writeTree, path, serverCache, writeIdsToExclude, includeHiddenSets);
18152
19205
  }
19206
+ function syncTreeGetServerValue(syncTree, query) {
19207
+ const path = query._path;
19208
+ let serverCache = null;
19209
+ // Any covering writes will necessarily be at the root, so really all we need to find is the server cache.
19210
+ // Consider optimizing this once there's a better understanding of what actual behavior will be.
19211
+ syncTree.syncPointTree_.foreachOnPath(path, (pathToSyncPoint, sp) => {
19212
+ const relativePath = newRelativePath(pathToSyncPoint, path);
19213
+ serverCache =
19214
+ serverCache || syncPointGetCompleteServerCache(sp, relativePath);
19215
+ });
19216
+ let syncPoint = syncTree.syncPointTree_.get(path);
19217
+ if (!syncPoint) {
19218
+ syncPoint = new SyncPoint();
19219
+ syncTree.syncPointTree_ = syncTree.syncPointTree_.set(path, syncPoint);
19220
+ }
19221
+ else {
19222
+ serverCache =
19223
+ serverCache || syncPointGetCompleteServerCache(syncPoint, newEmptyPath());
19224
+ }
19225
+ const serverCacheComplete = serverCache != null;
19226
+ const serverCacheNode = serverCacheComplete
19227
+ ? new CacheNode(serverCache, true, false)
19228
+ : null;
19229
+ const writesCache = writeTreeChildWrites(syncTree.pendingWriteTree_, query._path);
19230
+ const view = syncPointGetView(syncPoint, query, writesCache, serverCacheComplete ? serverCacheNode.getNode() : ChildrenNode.EMPTY_NODE, serverCacheComplete);
19231
+ return viewGetCompleteNode(view);
19232
+ }
18153
19233
  /**
18154
19234
  * A helper method that visits all descendant and ancestor SyncPoints, applying the operation.
18155
19235
  *
@@ -18901,6 +19981,36 @@ const validateFirebaseMergeDataArg = function (fnName, data, path, optional) {
18901
19981
  });
18902
19982
  validateFirebaseMergePaths(errorPrefix$1, mergePaths);
18903
19983
  };
19984
+ const validatePriority = function (fnName, priority, optional) {
19985
+ if (optional && priority === undefined) {
19986
+ return;
19987
+ }
19988
+ if (isInvalidJSONNumber(priority)) {
19989
+ throw new Error(errorPrefix(fnName, 'priority') +
19990
+ 'is ' +
19991
+ priority.toString() +
19992
+ ', but must be a valid Firebase priority (a string, finite number, ' +
19993
+ 'server value, or null).');
19994
+ }
19995
+ // Special case to allow importing data with a .sv.
19996
+ if (!isValidPriority(priority)) {
19997
+ throw new Error(errorPrefix(fnName, 'priority') +
19998
+ 'must be a valid Firebase priority ' +
19999
+ '(a string, finite number, server value, or null).');
20000
+ }
20001
+ };
20002
+ const validateKey = function (fnName, argumentName, key, optional) {
20003
+ if (optional && key === undefined) {
20004
+ return;
20005
+ }
20006
+ if (!isValidKey(key)) {
20007
+ throw new Error(errorPrefix(fnName, argumentName) +
20008
+ 'was an invalid key = "' +
20009
+ key +
20010
+ '". Firebase keys must be non-empty strings and ' +
20011
+ 'can\'t contain ".", "#", "$", "/", "[", or "]").');
20012
+ }
20013
+ };
18904
20014
  /**
18905
20015
  * @internal
18906
20016
  */
@@ -19270,6 +20380,63 @@ function repoUpdateInfo(repo, pathString, value) {
19270
20380
  function repoGetNextWriteId(repo) {
19271
20381
  return repo.nextWriteId_++;
19272
20382
  }
20383
+ /**
20384
+ * The purpose of `getValue` is to return the latest known value
20385
+ * satisfying `query`.
20386
+ *
20387
+ * This method will first check for in-memory cached values
20388
+ * belonging to active listeners. If they are found, such values
20389
+ * are considered to be the most up-to-date.
20390
+ *
20391
+ * If the client is not connected, this method will wait until the
20392
+ * repo has established a connection and then request the value for `query`.
20393
+ * If the client is not able to retrieve the query result for another reason,
20394
+ * it reports an error.
20395
+ *
20396
+ * @param query - The query to surface a value for.
20397
+ */
20398
+ function repoGetValue(repo, query, eventRegistration) {
20399
+ // Only active queries are cached. There is no persisted cache.
20400
+ const cached = syncTreeGetServerValue(repo.serverSyncTree_, query);
20401
+ if (cached != null) {
20402
+ return Promise.resolve(cached);
20403
+ }
20404
+ return repo.server_.get(query).then(payload => {
20405
+ const node = nodeFromJSON(payload).withIndex(query._queryParams.getIndex());
20406
+ /**
20407
+ * Below we simulate the actions of an `onlyOnce` `onValue()` event where:
20408
+ * Add an event registration,
20409
+ * Update data at the path,
20410
+ * Raise any events,
20411
+ * Cleanup the SyncTree
20412
+ */
20413
+ syncTreeAddEventRegistration(repo.serverSyncTree_, query, eventRegistration, true);
20414
+ let events;
20415
+ if (query._queryParams.loadsAllData()) {
20416
+ events = syncTreeApplyServerOverwrite(repo.serverSyncTree_, query._path, node);
20417
+ }
20418
+ else {
20419
+ const tag = syncTreeTagForQuery(repo.serverSyncTree_, query);
20420
+ events = syncTreeApplyTaggedQueryOverwrite(repo.serverSyncTree_, query._path, node, tag);
20421
+ }
20422
+ /*
20423
+ * We need to raise events in the scenario where `get()` is called at a parent path, and
20424
+ * while the `get()` is pending, `onValue` is called at a child location. While get() is waiting
20425
+ * for the data, `onValue` will register a new event. Then, get() will come back, and update the syncTree
20426
+ * and its corresponding serverCache, including the child location where `onValue` is called. Then,
20427
+ * `onValue` will receive the event from the server, but look at the syncTree and see that the data received
20428
+ * from the server is already at the SyncPoint, and so the `onValue` callback will never get fired.
20429
+ * Calling `eventQueueRaiseEventsForChangedPath()` is the correct way to propagate the events and
20430
+ * ensure the corresponding child events will get fired.
20431
+ */
20432
+ eventQueueRaiseEventsForChangedPath(repo.eventQueue_, query._path, events);
20433
+ syncTreeRemoveEventRegistration(repo.serverSyncTree_, query, eventRegistration, null, true);
20434
+ return node;
20435
+ }, err => {
20436
+ repoLog(repo, 'get for query ' + stringify(query) + ' failed: ' + err);
20437
+ return Promise.reject(new Error(err));
20438
+ });
20439
+ }
19273
20440
  function repoSetWithPriority(repo, path, newVal, newPriority, onComplete) {
19274
20441
  repoLog(repo, 'set', {
19275
20442
  path: path.toString(),
@@ -19355,6 +20522,48 @@ function repoRunOnDisconnectEvents(repo) {
19355
20522
  repo.onDisconnect_ = newSparseSnapshotTree();
19356
20523
  eventQueueRaiseEventsForChangedPath(repo.eventQueue_, newEmptyPath(), events);
19357
20524
  }
20525
+ function repoOnDisconnectCancel(repo, path, onComplete) {
20526
+ repo.server_.onDisconnectCancel(path.toString(), (status, errorReason) => {
20527
+ if (status === 'ok') {
20528
+ sparseSnapshotTreeForget(repo.onDisconnect_, path);
20529
+ }
20530
+ repoCallOnCompleteCallback(repo, onComplete, status, errorReason);
20531
+ });
20532
+ }
20533
+ function repoOnDisconnectSet(repo, path, value, onComplete) {
20534
+ const newNode = nodeFromJSON(value);
20535
+ repo.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/ true), (status, errorReason) => {
20536
+ if (status === 'ok') {
20537
+ sparseSnapshotTreeRemember(repo.onDisconnect_, path, newNode);
20538
+ }
20539
+ repoCallOnCompleteCallback(repo, onComplete, status, errorReason);
20540
+ });
20541
+ }
20542
+ function repoOnDisconnectSetWithPriority(repo, path, value, priority, onComplete) {
20543
+ const newNode = nodeFromJSON(value, priority);
20544
+ repo.server_.onDisconnectPut(path.toString(), newNode.val(/*export=*/ true), (status, errorReason) => {
20545
+ if (status === 'ok') {
20546
+ sparseSnapshotTreeRemember(repo.onDisconnect_, path, newNode);
20547
+ }
20548
+ repoCallOnCompleteCallback(repo, onComplete, status, errorReason);
20549
+ });
20550
+ }
20551
+ function repoOnDisconnectUpdate(repo, path, childrenToMerge, onComplete) {
20552
+ if (isEmpty(childrenToMerge)) {
20553
+ log("onDisconnect().update() called with empty data. Don't do anything.");
20554
+ repoCallOnCompleteCallback(repo, onComplete, 'ok', undefined);
20555
+ return;
20556
+ }
20557
+ repo.server_.onDisconnectMerge(path.toString(), childrenToMerge, (status, errorReason) => {
20558
+ if (status === 'ok') {
20559
+ each(childrenToMerge, (childName, childNode) => {
20560
+ const newChildNode = nodeFromJSON(childNode);
20561
+ sparseSnapshotTreeRemember(repo.onDisconnect_, pathChild(path, childName), newChildNode);
20562
+ });
20563
+ }
20564
+ repoCallOnCompleteCallback(repo, onComplete, status, errorReason);
20565
+ });
20566
+ }
19358
20567
  function repoAddEventCallbackForQuery(repo, query, eventRegistration) {
19359
20568
  let events;
19360
20569
  if (pathGetFront(query._path) === '.info') {
@@ -19382,6 +20591,11 @@ function repoInterrupt(repo) {
19382
20591
  repo.persistentConnection_.interrupt(INTERRUPT_REASON);
19383
20592
  }
19384
20593
  }
20594
+ function repoResume(repo) {
20595
+ if (repo.persistentConnection_) {
20596
+ repo.persistentConnection_.resume(INTERRUPT_REASON);
20597
+ }
20598
+ }
19385
20599
  function repoLog(repo, ...varArgs) {
19386
20600
  let prefix = '';
19387
20601
  if (repo.persistentConnection_) {
@@ -19409,6 +20623,92 @@ function repoCallOnCompleteCallback(repo, callback, status, errorReason) {
19409
20623
  });
19410
20624
  }
19411
20625
  }
20626
+ /**
20627
+ * Creates a new transaction, adds it to the transactions we're tracking, and
20628
+ * sends it to the server if possible.
20629
+ *
20630
+ * @param path - Path at which to do transaction.
20631
+ * @param transactionUpdate - Update callback.
20632
+ * @param onComplete - Completion callback.
20633
+ * @param unwatcher - Function that will be called when the transaction no longer
20634
+ * need data updates for `path`.
20635
+ * @param applyLocally - Whether or not to make intermediate results visible
20636
+ */
20637
+ function repoStartTransaction(repo, path, transactionUpdate, onComplete, unwatcher, applyLocally) {
20638
+ repoLog(repo, 'transaction on ' + path);
20639
+ // Initialize transaction.
20640
+ const transaction = {
20641
+ path,
20642
+ update: transactionUpdate,
20643
+ onComplete,
20644
+ // One of TransactionStatus enums.
20645
+ status: null,
20646
+ // Used when combining transactions at different locations to figure out
20647
+ // which one goes first.
20648
+ order: LUIDGenerator(),
20649
+ // Whether to raise local events for this transaction.
20650
+ applyLocally,
20651
+ // Count of how many times we've retried the transaction.
20652
+ retryCount: 0,
20653
+ // Function to call to clean up our .on() listener.
20654
+ unwatcher,
20655
+ // Stores why a transaction was aborted.
20656
+ abortReason: null,
20657
+ currentWriteId: null,
20658
+ currentInputSnapshot: null,
20659
+ currentOutputSnapshotRaw: null,
20660
+ currentOutputSnapshotResolved: null
20661
+ };
20662
+ // Run transaction initially.
20663
+ const currentState = repoGetLatestState(repo, path, undefined);
20664
+ transaction.currentInputSnapshot = currentState;
20665
+ const newVal = transaction.update(currentState.val());
20666
+ if (newVal === undefined) {
20667
+ // Abort transaction.
20668
+ transaction.unwatcher();
20669
+ transaction.currentOutputSnapshotRaw = null;
20670
+ transaction.currentOutputSnapshotResolved = null;
20671
+ if (transaction.onComplete) {
20672
+ transaction.onComplete(null, false, transaction.currentInputSnapshot);
20673
+ }
20674
+ }
20675
+ else {
20676
+ validateFirebaseData('transaction failed: Data returned ', newVal, transaction.path);
20677
+ // Mark as run and add to our queue.
20678
+ transaction.status = 0 /* TransactionStatus.RUN */;
20679
+ const queueNode = treeSubTree(repo.transactionQueueTree_, path);
20680
+ const nodeQueue = treeGetValue(queueNode) || [];
20681
+ nodeQueue.push(transaction);
20682
+ treeSetValue(queueNode, nodeQueue);
20683
+ // Update visibleData and raise events
20684
+ // Note: We intentionally raise events after updating all of our
20685
+ // transaction state, since the user could start new transactions from the
20686
+ // event callbacks.
20687
+ let priorityForNode;
20688
+ if (typeof newVal === 'object' &&
20689
+ newVal !== null &&
20690
+ contains(newVal, '.priority')) {
20691
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20692
+ priorityForNode = safeGet(newVal, '.priority');
20693
+ assert(isValidPriority(priorityForNode), 'Invalid priority returned by transaction. ' +
20694
+ 'Priority must be a valid string, finite number, server value, or null.');
20695
+ }
20696
+ else {
20697
+ const currentNode = syncTreeCalcCompleteEventCache(repo.serverSyncTree_, path) ||
20698
+ ChildrenNode.EMPTY_NODE;
20699
+ priorityForNode = currentNode.getPriority().val();
20700
+ }
20701
+ const serverValues = repoGenerateServerValues(repo);
20702
+ const newNodeUnresolved = nodeFromJSON(newVal, priorityForNode);
20703
+ const newNode = resolveDeferredValueSnapshot(newNodeUnresolved, currentState, serverValues);
20704
+ transaction.currentOutputSnapshotRaw = newNodeUnresolved;
20705
+ transaction.currentOutputSnapshotResolved = newNode;
20706
+ transaction.currentWriteId = repoGetNextWriteId(repo);
20707
+ const events = syncTreeApplyUserOverwrite(repo.serverSyncTree_, path, newNode, transaction.currentWriteId, transaction.applyLocally);
20708
+ eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events);
20709
+ repoSendReadyTransactions(repo, repo.transactionQueueTree_);
20710
+ }
20711
+ }
19412
20712
  /**
19413
20713
  * @param excludeSets - A specific set to exclude
19414
20714
  */
@@ -20126,7 +21426,7 @@ class CallbackContext {
20126
21426
 
20127
21427
  /**
20128
21428
  * @license
20129
- * Copyright 2020 Google LLC
21429
+ * Copyright 2021 Google LLC
20130
21430
  *
20131
21431
  * Licensed under the Apache License, Version 2.0 (the "License");
20132
21432
  * you may not use this file except in compliance with the License.
@@ -20141,17 +21441,155 @@ class CallbackContext {
20141
21441
  * limitations under the License.
20142
21442
  */
20143
21443
  /**
20144
- * @internal
21444
+ * The `onDisconnect` class allows you to write or clear data when your client
21445
+ * disconnects from the Database server. These updates occur whether your
21446
+ * client disconnects cleanly or not, so you can rely on them to clean up data
21447
+ * even if a connection is dropped or a client crashes.
21448
+ *
21449
+ * The `onDisconnect` class is most commonly used to manage presence in
21450
+ * applications where it is useful to detect how many clients are connected and
21451
+ * when other clients disconnect. See
21452
+ * {@link https://firebase.google.com/docs/database/web/offline-capabilities | Enabling Offline Capabilities in JavaScript}
21453
+ * for more information.
21454
+ *
21455
+ * To avoid problems when a connection is dropped before the requests can be
21456
+ * transferred to the Database server, these functions should be called before
21457
+ * writing any data.
21458
+ *
21459
+ * Note that `onDisconnect` operations are only triggered once. If you want an
21460
+ * operation to occur each time a disconnect occurs, you'll need to re-establish
21461
+ * the `onDisconnect` operations each time you reconnect.
20145
21462
  */
20146
- class QueryImpl {
20147
- /**
20148
- * @hideconstructor
20149
- */
20150
- constructor(_repo, _path, _queryParams, _orderByCalled) {
21463
+ class OnDisconnect {
21464
+ /** @hideconstructor */
21465
+ constructor(_repo, _path) {
20151
21466
  this._repo = _repo;
20152
21467
  this._path = _path;
20153
- this._queryParams = _queryParams;
20154
- this._orderByCalled = _orderByCalled;
21468
+ }
21469
+ /**
21470
+ * Cancels all previously queued `onDisconnect()` set or update events for this
21471
+ * location and all children.
21472
+ *
21473
+ * If a write has been queued for this location via a `set()` or `update()` at a
21474
+ * parent location, the write at this location will be canceled, though writes
21475
+ * to sibling locations will still occur.
21476
+ *
21477
+ * @returns Resolves when synchronization to the server is complete.
21478
+ */
21479
+ cancel() {
21480
+ const deferred = new Deferred();
21481
+ repoOnDisconnectCancel(this._repo, this._path, deferred.wrapCallback(() => { }));
21482
+ return deferred.promise;
21483
+ }
21484
+ /**
21485
+ * Ensures the data at this location is deleted when the client is disconnected
21486
+ * (due to closing the browser, navigating to a new page, or network issues).
21487
+ *
21488
+ * @returns Resolves when synchronization to the server is complete.
21489
+ */
21490
+ remove() {
21491
+ validateWritablePath('OnDisconnect.remove', this._path);
21492
+ const deferred = new Deferred();
21493
+ repoOnDisconnectSet(this._repo, this._path, null, deferred.wrapCallback(() => { }));
21494
+ return deferred.promise;
21495
+ }
21496
+ /**
21497
+ * Ensures the data at this location is set to the specified value when the
21498
+ * client is disconnected (due to closing the browser, navigating to a new page,
21499
+ * or network issues).
21500
+ *
21501
+ * `set()` is especially useful for implementing "presence" systems, where a
21502
+ * value should be changed or cleared when a user disconnects so that they
21503
+ * appear "offline" to other users. See
21504
+ * {@link https://firebase.google.com/docs/database/web/offline-capabilities | Enabling Offline Capabilities in JavaScript}
21505
+ * for more information.
21506
+ *
21507
+ * Note that `onDisconnect` operations are only triggered once. If you want an
21508
+ * operation to occur each time a disconnect occurs, you'll need to re-establish
21509
+ * the `onDisconnect` operations each time.
21510
+ *
21511
+ * @param value - The value to be written to this location on disconnect (can
21512
+ * be an object, array, string, number, boolean, or null).
21513
+ * @returns Resolves when synchronization to the Database is complete.
21514
+ */
21515
+ set(value) {
21516
+ validateWritablePath('OnDisconnect.set', this._path);
21517
+ validateFirebaseDataArg('OnDisconnect.set', value, this._path, false);
21518
+ const deferred = new Deferred();
21519
+ repoOnDisconnectSet(this._repo, this._path, value, deferred.wrapCallback(() => { }));
21520
+ return deferred.promise;
21521
+ }
21522
+ /**
21523
+ * Ensures the data at this location is set to the specified value and priority
21524
+ * when the client is disconnected (due to closing the browser, navigating to a
21525
+ * new page, or network issues).
21526
+ *
21527
+ * @param value - The value to be written to this location on disconnect (can
21528
+ * be an object, array, string, number, boolean, or null).
21529
+ * @param priority - The priority to be written (string, number, or null).
21530
+ * @returns Resolves when synchronization to the Database is complete.
21531
+ */
21532
+ setWithPriority(value, priority) {
21533
+ validateWritablePath('OnDisconnect.setWithPriority', this._path);
21534
+ validateFirebaseDataArg('OnDisconnect.setWithPriority', value, this._path, false);
21535
+ validatePriority('OnDisconnect.setWithPriority', priority, false);
21536
+ const deferred = new Deferred();
21537
+ repoOnDisconnectSetWithPriority(this._repo, this._path, value, priority, deferred.wrapCallback(() => { }));
21538
+ return deferred.promise;
21539
+ }
21540
+ /**
21541
+ * Writes multiple values at this location when the client is disconnected (due
21542
+ * to closing the browser, navigating to a new page, or network issues).
21543
+ *
21544
+ * The `values` argument contains multiple property-value pairs that will be
21545
+ * written to the Database together. Each child property can either be a simple
21546
+ * property (for example, "name") or a relative path (for example, "name/first")
21547
+ * from the current location to the data to update.
21548
+ *
21549
+ * As opposed to the `set()` method, `update()` can be use to selectively update
21550
+ * only the referenced properties at the current location (instead of replacing
21551
+ * all the child properties at the current location).
21552
+ *
21553
+ * @param values - Object containing multiple values.
21554
+ * @returns Resolves when synchronization to the Database is complete.
21555
+ */
21556
+ update(values) {
21557
+ validateWritablePath('OnDisconnect.update', this._path);
21558
+ validateFirebaseMergeDataArg('OnDisconnect.update', values, this._path, false);
21559
+ const deferred = new Deferred();
21560
+ repoOnDisconnectUpdate(this._repo, this._path, values, deferred.wrapCallback(() => { }));
21561
+ return deferred.promise;
21562
+ }
21563
+ }
21564
+
21565
+ /**
21566
+ * @license
21567
+ * Copyright 2020 Google LLC
21568
+ *
21569
+ * Licensed under the Apache License, Version 2.0 (the "License");
21570
+ * you may not use this file except in compliance with the License.
21571
+ * You may obtain a copy of the License at
21572
+ *
21573
+ * http://www.apache.org/licenses/LICENSE-2.0
21574
+ *
21575
+ * Unless required by applicable law or agreed to in writing, software
21576
+ * distributed under the License is distributed on an "AS IS" BASIS,
21577
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21578
+ * See the License for the specific language governing permissions and
21579
+ * limitations under the License.
21580
+ */
21581
+ /**
21582
+ * @internal
21583
+ */
21584
+ class QueryImpl {
21585
+ /**
21586
+ * @hideconstructor
21587
+ */
21588
+ constructor(_repo, _path, _queryParams, _orderByCalled) {
21589
+ this._repo = _repo;
21590
+ this._path = _path;
21591
+ this._queryParams = _queryParams;
21592
+ this._orderByCalled = _orderByCalled;
20155
21593
  }
20156
21594
  get key() {
20157
21595
  if (pathIsEmpty(this._path)) {
@@ -20192,6 +21630,80 @@ class QueryImpl {
20192
21630
  return this._repo.toString() + pathToUrlEncodedString(this._path);
20193
21631
  }
20194
21632
  }
21633
+ /**
21634
+ * Validates that no other order by call has been made
21635
+ */
21636
+ function validateNoPreviousOrderByCall(query, fnName) {
21637
+ if (query._orderByCalled === true) {
21638
+ throw new Error(fnName + ": You can't combine multiple orderBy calls.");
21639
+ }
21640
+ }
21641
+ /**
21642
+ * Validates start/end values for queries.
21643
+ */
21644
+ function validateQueryEndpoints(params) {
21645
+ let startNode = null;
21646
+ let endNode = null;
21647
+ if (params.hasStart()) {
21648
+ startNode = params.getIndexStartValue();
21649
+ }
21650
+ if (params.hasEnd()) {
21651
+ endNode = params.getIndexEndValue();
21652
+ }
21653
+ if (params.getIndex() === KEY_INDEX) {
21654
+ const tooManyArgsError = 'Query: When ordering by key, you may only pass one argument to ' +
21655
+ 'startAt(), endAt(), or equalTo().';
21656
+ const wrongArgTypeError = 'Query: When ordering by key, the argument passed to startAt(), startAfter(), ' +
21657
+ 'endAt(), endBefore(), or equalTo() must be a string.';
21658
+ if (params.hasStart()) {
21659
+ const startName = params.getIndexStartName();
21660
+ if (startName !== MIN_NAME) {
21661
+ throw new Error(tooManyArgsError);
21662
+ }
21663
+ else if (typeof startNode !== 'string') {
21664
+ throw new Error(wrongArgTypeError);
21665
+ }
21666
+ }
21667
+ if (params.hasEnd()) {
21668
+ const endName = params.getIndexEndName();
21669
+ if (endName !== MAX_NAME) {
21670
+ throw new Error(tooManyArgsError);
21671
+ }
21672
+ else if (typeof endNode !== 'string') {
21673
+ throw new Error(wrongArgTypeError);
21674
+ }
21675
+ }
21676
+ }
21677
+ else if (params.getIndex() === PRIORITY_INDEX) {
21678
+ if ((startNode != null && !isValidPriority(startNode)) ||
21679
+ (endNode != null && !isValidPriority(endNode))) {
21680
+ throw new Error('Query: When ordering by priority, the first argument passed to startAt(), ' +
21681
+ 'startAfter() endAt(), endBefore(), or equalTo() must be a valid priority value ' +
21682
+ '(null, a number, or a string).');
21683
+ }
21684
+ }
21685
+ else {
21686
+ assert(params.getIndex() instanceof PathIndex ||
21687
+ params.getIndex() === VALUE_INDEX, 'unknown index type.');
21688
+ if ((startNode != null && typeof startNode === 'object') ||
21689
+ (endNode != null && typeof endNode === 'object')) {
21690
+ throw new Error('Query: First argument passed to startAt(), startAfter(), endAt(), endBefore(), or ' +
21691
+ 'equalTo() cannot be an object.');
21692
+ }
21693
+ }
21694
+ }
21695
+ /**
21696
+ * Validates that limit* has been called with the correct combination of parameters
21697
+ */
21698
+ function validateLimit(params) {
21699
+ if (params.hasStart() &&
21700
+ params.hasEnd() &&
21701
+ params.hasLimit() &&
21702
+ !params.hasAnchoredLimit()) {
21703
+ throw new Error("Query: Can't combine startAt(), startAfter(), endAt(), endBefore(), and limit(). Use " +
21704
+ 'limitToFirst() or limitToLast() instead.');
21705
+ }
21706
+ }
20195
21707
  /**
20196
21708
  * @internal
20197
21709
  */
@@ -20409,6 +21921,40 @@ function ref(db, path) {
20409
21921
  db._checkNotDeleted('ref');
20410
21922
  return path !== undefined ? child(db._root, path) : db._root;
20411
21923
  }
21924
+ /**
21925
+ * Returns a `Reference` representing the location in the Database
21926
+ * corresponding to the provided Firebase URL.
21927
+ *
21928
+ * An exception is thrown if the URL is not a valid Firebase Database URL or it
21929
+ * has a different domain than the current `Database` instance.
21930
+ *
21931
+ * Note that all query parameters (`orderBy`, `limitToLast`, etc.) are ignored
21932
+ * and are not applied to the returned `Reference`.
21933
+ *
21934
+ * @param db - The database instance to obtain a reference for.
21935
+ * @param url - The Firebase URL at which the returned `Reference` will
21936
+ * point.
21937
+ * @returns A `Reference` pointing to the provided
21938
+ * Firebase URL.
21939
+ */
21940
+ function refFromURL(db, url) {
21941
+ db = getModularInstance(db);
21942
+ db._checkNotDeleted('refFromURL');
21943
+ const parsedURL = parseRepoInfo(url, db._repo.repoInfo_.nodeAdmin);
21944
+ validateUrl('refFromURL', parsedURL);
21945
+ const repoInfo = parsedURL.repoInfo;
21946
+ if (!db._repo.repoInfo_.isCustomHost() &&
21947
+ repoInfo.host !== db._repo.repoInfo_.host) {
21948
+ fatal('refFromURL' +
21949
+ ': Host name does not match the current database: ' +
21950
+ '(found ' +
21951
+ repoInfo.host +
21952
+ ' but expected ' +
21953
+ db._repo.repoInfo_.host +
21954
+ ')');
21955
+ }
21956
+ return ref(db, parsedURL.path.toString());
21957
+ }
20412
21958
  /**
20413
21959
  * Gets a `Reference` for the location at the specified relative path.
20414
21960
  *
@@ -20430,6 +21976,17 @@ function child(parent, path) {
20430
21976
  }
20431
21977
  return new ReferenceImpl(parent._repo, pathChild(parent._path, path));
20432
21978
  }
21979
+ /**
21980
+ * Returns an `OnDisconnect` object - see
21981
+ * {@link https://firebase.google.com/docs/database/web/offline-capabilities | Enabling Offline Capabilities in JavaScript}
21982
+ * for more information on how to use it.
21983
+ *
21984
+ * @param ref - The reference to add OnDisconnect triggers for.
21985
+ */
21986
+ function onDisconnect(ref) {
21987
+ ref = getModularInstance(ref);
21988
+ return new OnDisconnect(ref._repo, ref._path);
21989
+ }
20433
21990
  /**
20434
21991
  * Generates a new child location using a unique key and returns its
20435
21992
  * `Reference`.
@@ -20478,6 +22035,24 @@ function push(parent, value) {
20478
22035
  thennablePushRef.catch = promise.then.bind(promise, undefined);
20479
22036
  return thennablePushRef;
20480
22037
  }
22038
+ /**
22039
+ * Removes the data at this Database location.
22040
+ *
22041
+ * Any data at child locations will also be deleted.
22042
+ *
22043
+ * The effect of the remove will be visible immediately and the corresponding
22044
+ * event 'value' will be triggered. Synchronization of the remove to the
22045
+ * Firebase servers will also be started, and the returned Promise will resolve
22046
+ * when complete. If provided, the onComplete callback will be called
22047
+ * asynchronously after synchronization has finished.
22048
+ *
22049
+ * @param ref - The location to remove.
22050
+ * @returns Resolves when remove on server is complete.
22051
+ */
22052
+ function remove(ref) {
22053
+ validateWritablePath('remove', ref._path);
22054
+ return set(ref, null);
22055
+ }
20481
22056
  /**
20482
22057
  * Writes data to this Database location.
20483
22058
  *
@@ -20516,6 +22091,52 @@ function set(ref, value) {
20516
22091
  /*priority=*/ null, deferred.wrapCallback(() => { }));
20517
22092
  return deferred.promise;
20518
22093
  }
22094
+ /**
22095
+ * Sets a priority for the data at this Database location.
22096
+ *
22097
+ * Applications need not use priority but can order collections by
22098
+ * ordinary properties (see
22099
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#sorting_and_filtering_data | Sorting and filtering data}
22100
+ * ).
22101
+ *
22102
+ * @param ref - The location to write to.
22103
+ * @param priority - The priority to be written (string, number, or null).
22104
+ * @returns Resolves when write to server is complete.
22105
+ */
22106
+ function setPriority(ref, priority) {
22107
+ ref = getModularInstance(ref);
22108
+ validateWritablePath('setPriority', ref._path);
22109
+ validatePriority('setPriority', priority, false);
22110
+ const deferred = new Deferred();
22111
+ repoSetWithPriority(ref._repo, pathChild(ref._path, '.priority'), priority, null, deferred.wrapCallback(() => { }));
22112
+ return deferred.promise;
22113
+ }
22114
+ /**
22115
+ * Writes data the Database location. Like `set()` but also specifies the
22116
+ * priority for that data.
22117
+ *
22118
+ * Applications need not use priority but can order collections by
22119
+ * ordinary properties (see
22120
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#sorting_and_filtering_data | Sorting and filtering data}
22121
+ * ).
22122
+ *
22123
+ * @param ref - The location to write to.
22124
+ * @param value - The value to be written (string, number, boolean, object,
22125
+ * array, or null).
22126
+ * @param priority - The priority to be written (string, number, or null).
22127
+ * @returns Resolves when write to server is complete.
22128
+ */
22129
+ function setWithPriority(ref, value, priority) {
22130
+ validateWritablePath('setWithPriority', ref._path);
22131
+ validateFirebaseDataArg('setWithPriority', value, ref._path, false);
22132
+ validatePriority('setWithPriority', priority, false);
22133
+ if (ref.key === '.length' || ref.key === '.keys') {
22134
+ throw 'setWithPriority failed: ' + ref.key + ' is a read-only object.';
22135
+ }
22136
+ const deferred = new Deferred();
22137
+ repoSetWithPriority(ref._repo, ref._path, value, priority, deferred.wrapCallback(() => { }));
22138
+ return deferred.promise;
22139
+ }
20519
22140
  /**
20520
22141
  * Writes multiple values to the Database at once.
20521
22142
  *
@@ -20557,6 +22178,22 @@ function update(ref, values) {
20557
22178
  repoUpdate(ref._repo, ref._path, values, deferred.wrapCallback(() => { }));
20558
22179
  return deferred.promise;
20559
22180
  }
22181
+ /**
22182
+ * Gets the most up-to-date result for this query.
22183
+ *
22184
+ * @param query - The query to run.
22185
+ * @returns A `Promise` which resolves to the resulting DataSnapshot if a value is
22186
+ * available, or rejects if the client is unable to return a value (e.g., if the
22187
+ * server is unreachable and there is nothing cached).
22188
+ */
22189
+ function get(query) {
22190
+ query = getModularInstance(query);
22191
+ const callbackContext = new CallbackContext(() => { });
22192
+ const container = new ValueEventRegistration(callbackContext);
22193
+ return repoGetValue(query._repo, query, container).then(node => {
22194
+ return new DataSnapshot(node, new ReferenceImpl(query._repo, query._path), query._queryParams.getIndex());
22195
+ });
22196
+ }
20560
22197
  /**
20561
22198
  * Represents registration for 'value' events.
20562
22199
  */
@@ -20599,87 +22236,560 @@ class ValueEventRegistration {
20599
22236
  return other.callbackContext.matches(this.callbackContext);
20600
22237
  }
20601
22238
  }
20602
- hasAnyCallback() {
20603
- return this.callbackContext !== null;
22239
+ hasAnyCallback() {
22240
+ return this.callbackContext !== null;
22241
+ }
22242
+ }
22243
+ /**
22244
+ * Represents the registration of a child_x event.
22245
+ */
22246
+ class ChildEventRegistration {
22247
+ constructor(eventType, callbackContext) {
22248
+ this.eventType = eventType;
22249
+ this.callbackContext = callbackContext;
22250
+ }
22251
+ respondsTo(eventType) {
22252
+ let eventToCheck = eventType === 'children_added' ? 'child_added' : eventType;
22253
+ eventToCheck =
22254
+ eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;
22255
+ return this.eventType === eventToCheck;
22256
+ }
22257
+ createCancelEvent(error, path) {
22258
+ if (this.callbackContext.hasCancelCallback) {
22259
+ return new CancelEvent(this, error, path);
22260
+ }
22261
+ else {
22262
+ return null;
22263
+ }
22264
+ }
22265
+ createEvent(change, query) {
22266
+ assert(change.childName != null, 'Child events should have a childName.');
22267
+ const childRef = child(new ReferenceImpl(query._repo, query._path), change.childName);
22268
+ const index = query._queryParams.getIndex();
22269
+ return new DataEvent(change.type, this, new DataSnapshot(change.snapshotNode, childRef, index), change.prevName);
22270
+ }
22271
+ getEventRunner(eventData) {
22272
+ if (eventData.getEventType() === 'cancel') {
22273
+ return () => this.callbackContext.onCancel(eventData.error);
22274
+ }
22275
+ else {
22276
+ return () => this.callbackContext.onValue(eventData.snapshot, eventData.prevName);
22277
+ }
22278
+ }
22279
+ matches(other) {
22280
+ if (other instanceof ChildEventRegistration) {
22281
+ return (this.eventType === other.eventType &&
22282
+ (!this.callbackContext ||
22283
+ !other.callbackContext ||
22284
+ this.callbackContext.matches(other.callbackContext)));
22285
+ }
22286
+ return false;
22287
+ }
22288
+ hasAnyCallback() {
22289
+ return !!this.callbackContext;
22290
+ }
22291
+ }
22292
+ function addEventListener(query, eventType, callback, cancelCallbackOrListenOptions, options) {
22293
+ let cancelCallback;
22294
+ if (typeof cancelCallbackOrListenOptions === 'object') {
22295
+ cancelCallback = undefined;
22296
+ options = cancelCallbackOrListenOptions;
22297
+ }
22298
+ if (typeof cancelCallbackOrListenOptions === 'function') {
22299
+ cancelCallback = cancelCallbackOrListenOptions;
22300
+ }
22301
+ if (options && options.onlyOnce) {
22302
+ const userCallback = callback;
22303
+ const onceCallback = (dataSnapshot, previousChildName) => {
22304
+ repoRemoveEventCallbackForQuery(query._repo, query, container);
22305
+ userCallback(dataSnapshot, previousChildName);
22306
+ };
22307
+ onceCallback.userCallback = callback.userCallback;
22308
+ onceCallback.context = callback.context;
22309
+ callback = onceCallback;
22310
+ }
22311
+ const callbackContext = new CallbackContext(callback, cancelCallback || undefined);
22312
+ const container = eventType === 'value'
22313
+ ? new ValueEventRegistration(callbackContext)
22314
+ : new ChildEventRegistration(eventType, callbackContext);
22315
+ repoAddEventCallbackForQuery(query._repo, query, container);
22316
+ return () => repoRemoveEventCallbackForQuery(query._repo, query, container);
22317
+ }
22318
+ function onValue(query, callback, cancelCallbackOrListenOptions, options) {
22319
+ return addEventListener(query, 'value', callback, cancelCallbackOrListenOptions, options);
22320
+ }
22321
+ function onChildAdded(query, callback, cancelCallbackOrListenOptions, options) {
22322
+ return addEventListener(query, 'child_added', callback, cancelCallbackOrListenOptions, options);
22323
+ }
22324
+ function onChildChanged(query, callback, cancelCallbackOrListenOptions, options) {
22325
+ return addEventListener(query, 'child_changed', callback, cancelCallbackOrListenOptions, options);
22326
+ }
22327
+ function onChildMoved(query, callback, cancelCallbackOrListenOptions, options) {
22328
+ return addEventListener(query, 'child_moved', callback, cancelCallbackOrListenOptions, options);
22329
+ }
22330
+ function onChildRemoved(query, callback, cancelCallbackOrListenOptions, options) {
22331
+ return addEventListener(query, 'child_removed', callback, cancelCallbackOrListenOptions, options);
22332
+ }
22333
+ /**
22334
+ * Detaches a callback previously attached with the corresponding `on*()` (`onValue`, `onChildAdded`) listener.
22335
+ * Note: This is not the recommended way to remove a listener. Instead, please use the returned callback function from
22336
+ * the respective `on*` callbacks.
22337
+ *
22338
+ * Detach a callback previously attached with `on*()`. Calling `off()` on a parent listener
22339
+ * will not automatically remove listeners registered on child nodes, `off()`
22340
+ * must also be called on any child listeners to remove the callback.
22341
+ *
22342
+ * If a callback is not specified, all callbacks for the specified eventType
22343
+ * will be removed. Similarly, if no eventType is specified, all callbacks
22344
+ * for the `Reference` will be removed.
22345
+ *
22346
+ * Individual listeners can also be removed by invoking their unsubscribe
22347
+ * callbacks.
22348
+ *
22349
+ * @param query - The query that the listener was registered with.
22350
+ * @param eventType - One of the following strings: "value", "child_added",
22351
+ * "child_changed", "child_removed", or "child_moved." If omitted, all callbacks
22352
+ * for the `Reference` will be removed.
22353
+ * @param callback - The callback function that was passed to `on()` or
22354
+ * `undefined` to remove all callbacks.
22355
+ */
22356
+ function off(query, eventType, callback) {
22357
+ let container = null;
22358
+ const expCallback = callback ? new CallbackContext(callback) : null;
22359
+ if (eventType === 'value') {
22360
+ container = new ValueEventRegistration(expCallback);
22361
+ }
22362
+ else if (eventType) {
22363
+ container = new ChildEventRegistration(eventType, expCallback);
22364
+ }
22365
+ repoRemoveEventCallbackForQuery(query._repo, query, container);
22366
+ }
22367
+ /**
22368
+ * A `QueryConstraint` is used to narrow the set of documents returned by a
22369
+ * Database query. `QueryConstraint`s are created by invoking {@link endAt},
22370
+ * {@link endBefore}, {@link startAt}, {@link startAfter}, {@link
22371
+ * limitToFirst}, {@link limitToLast}, {@link orderByChild},
22372
+ * {@link orderByChild}, {@link orderByKey} , {@link orderByPriority} ,
22373
+ * {@link orderByValue} or {@link equalTo} and
22374
+ * can then be passed to {@link query} to create a new query instance that
22375
+ * also contains this `QueryConstraint`.
22376
+ */
22377
+ class QueryConstraint {
22378
+ }
22379
+ class QueryEndAtConstraint extends QueryConstraint {
22380
+ constructor(_value, _key) {
22381
+ super();
22382
+ this._value = _value;
22383
+ this._key = _key;
22384
+ }
22385
+ _apply(query) {
22386
+ validateFirebaseDataArg('endAt', this._value, query._path, true);
22387
+ const newParams = queryParamsEndAt(query._queryParams, this._value, this._key);
22388
+ validateLimit(newParams);
22389
+ validateQueryEndpoints(newParams);
22390
+ if (query._queryParams.hasEnd()) {
22391
+ throw new Error('endAt: Starting point was already set (by another call to endAt, ' +
22392
+ 'endBefore or equalTo).');
22393
+ }
22394
+ return new QueryImpl(query._repo, query._path, newParams, query._orderByCalled);
22395
+ }
22396
+ }
22397
+ /**
22398
+ * Creates a `QueryConstraint` with the specified ending point.
22399
+ *
22400
+ * Using `startAt()`, `startAfter()`, `endBefore()`, `endAt()` and `equalTo()`
22401
+ * allows you to choose arbitrary starting and ending points for your queries.
22402
+ *
22403
+ * The ending point is inclusive, so children with exactly the specified value
22404
+ * will be included in the query. The optional key argument can be used to
22405
+ * further limit the range of the query. If it is specified, then children that
22406
+ * have exactly the specified value must also have a key name less than or equal
22407
+ * to the specified key.
22408
+ *
22409
+ * You can read more about `endAt()` in
22410
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#filtering_data | Filtering data}.
22411
+ *
22412
+ * @param value - The value to end at. The argument type depends on which
22413
+ * `orderBy*()` function was used in this query. Specify a value that matches
22414
+ * the `orderBy*()` type. When used in combination with `orderByKey()`, the
22415
+ * value must be a string.
22416
+ * @param key - The child key to end at, among the children with the previously
22417
+ * specified priority. This argument is only allowed if ordering by child,
22418
+ * value, or priority.
22419
+ */
22420
+ function endAt(value, key) {
22421
+ validateKey('endAt', 'key', key, true);
22422
+ return new QueryEndAtConstraint(value, key);
22423
+ }
22424
+ class QueryEndBeforeConstraint extends QueryConstraint {
22425
+ constructor(_value, _key) {
22426
+ super();
22427
+ this._value = _value;
22428
+ this._key = _key;
22429
+ }
22430
+ _apply(query) {
22431
+ validateFirebaseDataArg('endBefore', this._value, query._path, false);
22432
+ const newParams = queryParamsEndBefore(query._queryParams, this._value, this._key);
22433
+ validateLimit(newParams);
22434
+ validateQueryEndpoints(newParams);
22435
+ if (query._queryParams.hasEnd()) {
22436
+ throw new Error('endBefore: Starting point was already set (by another call to endAt, ' +
22437
+ 'endBefore or equalTo).');
22438
+ }
22439
+ return new QueryImpl(query._repo, query._path, newParams, query._orderByCalled);
22440
+ }
22441
+ }
22442
+ /**
22443
+ * Creates a `QueryConstraint` with the specified ending point (exclusive).
22444
+ *
22445
+ * Using `startAt()`, `startAfter()`, `endBefore()`, `endAt()` and `equalTo()`
22446
+ * allows you to choose arbitrary starting and ending points for your queries.
22447
+ *
22448
+ * The ending point is exclusive. If only a value is provided, children
22449
+ * with a value less than the specified value will be included in the query.
22450
+ * If a key is specified, then children must have a value less than or equal
22451
+ * to the specified value and a key name less than the specified key.
22452
+ *
22453
+ * @param value - The value to end before. The argument type depends on which
22454
+ * `orderBy*()` function was used in this query. Specify a value that matches
22455
+ * the `orderBy*()` type. When used in combination with `orderByKey()`, the
22456
+ * value must be a string.
22457
+ * @param key - The child key to end before, among the children with the
22458
+ * previously specified priority. This argument is only allowed if ordering by
22459
+ * child, value, or priority.
22460
+ */
22461
+ function endBefore(value, key) {
22462
+ validateKey('endBefore', 'key', key, true);
22463
+ return new QueryEndBeforeConstraint(value, key);
22464
+ }
22465
+ class QueryStartAtConstraint extends QueryConstraint {
22466
+ constructor(_value, _key) {
22467
+ super();
22468
+ this._value = _value;
22469
+ this._key = _key;
22470
+ }
22471
+ _apply(query) {
22472
+ validateFirebaseDataArg('startAt', this._value, query._path, true);
22473
+ const newParams = queryParamsStartAt(query._queryParams, this._value, this._key);
22474
+ validateLimit(newParams);
22475
+ validateQueryEndpoints(newParams);
22476
+ if (query._queryParams.hasStart()) {
22477
+ throw new Error('startAt: Starting point was already set (by another call to startAt, ' +
22478
+ 'startBefore or equalTo).');
22479
+ }
22480
+ return new QueryImpl(query._repo, query._path, newParams, query._orderByCalled);
22481
+ }
22482
+ }
22483
+ /**
22484
+ * Creates a `QueryConstraint` with the specified starting point.
22485
+ *
22486
+ * Using `startAt()`, `startAfter()`, `endBefore()`, `endAt()` and `equalTo()`
22487
+ * allows you to choose arbitrary starting and ending points for your queries.
22488
+ *
22489
+ * The starting point is inclusive, so children with exactly the specified value
22490
+ * will be included in the query. The optional key argument can be used to
22491
+ * further limit the range of the query. If it is specified, then children that
22492
+ * have exactly the specified value must also have a key name greater than or
22493
+ * equal to the specified key.
22494
+ *
22495
+ * You can read more about `startAt()` in
22496
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#filtering_data | Filtering data}.
22497
+ *
22498
+ * @param value - The value to start at. The argument type depends on which
22499
+ * `orderBy*()` function was used in this query. Specify a value that matches
22500
+ * the `orderBy*()` type. When used in combination with `orderByKey()`, the
22501
+ * value must be a string.
22502
+ * @param key - The child key to start at. This argument is only allowed if
22503
+ * ordering by child, value, or priority.
22504
+ */
22505
+ function startAt(value = null, key) {
22506
+ validateKey('startAt', 'key', key, true);
22507
+ return new QueryStartAtConstraint(value, key);
22508
+ }
22509
+ class QueryStartAfterConstraint extends QueryConstraint {
22510
+ constructor(_value, _key) {
22511
+ super();
22512
+ this._value = _value;
22513
+ this._key = _key;
22514
+ }
22515
+ _apply(query) {
22516
+ validateFirebaseDataArg('startAfter', this._value, query._path, false);
22517
+ const newParams = queryParamsStartAfter(query._queryParams, this._value, this._key);
22518
+ validateLimit(newParams);
22519
+ validateQueryEndpoints(newParams);
22520
+ if (query._queryParams.hasStart()) {
22521
+ throw new Error('startAfter: Starting point was already set (by another call to startAt, ' +
22522
+ 'startAfter, or equalTo).');
22523
+ }
22524
+ return new QueryImpl(query._repo, query._path, newParams, query._orderByCalled);
22525
+ }
22526
+ }
22527
+ /**
22528
+ * Creates a `QueryConstraint` with the specified starting point (exclusive).
22529
+ *
22530
+ * Using `startAt()`, `startAfter()`, `endBefore()`, `endAt()` and `equalTo()`
22531
+ * allows you to choose arbitrary starting and ending points for your queries.
22532
+ *
22533
+ * The starting point is exclusive. If only a value is provided, children
22534
+ * with a value greater than the specified value will be included in the query.
22535
+ * If a key is specified, then children must have a value greater than or equal
22536
+ * to the specified value and a a key name greater than the specified key.
22537
+ *
22538
+ * @param value - The value to start after. The argument type depends on which
22539
+ * `orderBy*()` function was used in this query. Specify a value that matches
22540
+ * the `orderBy*()` type. When used in combination with `orderByKey()`, the
22541
+ * value must be a string.
22542
+ * @param key - The child key to start after. This argument is only allowed if
22543
+ * ordering by child, value, or priority.
22544
+ */
22545
+ function startAfter(value, key) {
22546
+ validateKey('startAfter', 'key', key, true);
22547
+ return new QueryStartAfterConstraint(value, key);
22548
+ }
22549
+ class QueryLimitToFirstConstraint extends QueryConstraint {
22550
+ constructor(_limit) {
22551
+ super();
22552
+ this._limit = _limit;
22553
+ }
22554
+ _apply(query) {
22555
+ if (query._queryParams.hasLimit()) {
22556
+ throw new Error('limitToFirst: Limit was already set (by another call to limitToFirst ' +
22557
+ 'or limitToLast).');
22558
+ }
22559
+ return new QueryImpl(query._repo, query._path, queryParamsLimitToFirst(query._queryParams, this._limit), query._orderByCalled);
22560
+ }
22561
+ }
22562
+ /**
22563
+ * Creates a new `QueryConstraint` that if limited to the first specific number
22564
+ * of children.
22565
+ *
22566
+ * The `limitToFirst()` method is used to set a maximum number of children to be
22567
+ * synced for a given callback. If we set a limit of 100, we will initially only
22568
+ * receive up to 100 `child_added` events. If we have fewer than 100 messages
22569
+ * stored in our Database, a `child_added` event will fire for each message.
22570
+ * However, if we have over 100 messages, we will only receive a `child_added`
22571
+ * event for the first 100 ordered messages. As items change, we will receive
22572
+ * `child_removed` events for each item that drops out of the active list so
22573
+ * that the total number stays at 100.
22574
+ *
22575
+ * You can read more about `limitToFirst()` in
22576
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#filtering_data | Filtering data}.
22577
+ *
22578
+ * @param limit - The maximum number of nodes to include in this query.
22579
+ */
22580
+ function limitToFirst(limit) {
22581
+ if (typeof limit !== 'number' || Math.floor(limit) !== limit || limit <= 0) {
22582
+ throw new Error('limitToFirst: First argument must be a positive integer.');
22583
+ }
22584
+ return new QueryLimitToFirstConstraint(limit);
22585
+ }
22586
+ class QueryLimitToLastConstraint extends QueryConstraint {
22587
+ constructor(_limit) {
22588
+ super();
22589
+ this._limit = _limit;
22590
+ }
22591
+ _apply(query) {
22592
+ if (query._queryParams.hasLimit()) {
22593
+ throw new Error('limitToLast: Limit was already set (by another call to limitToFirst ' +
22594
+ 'or limitToLast).');
22595
+ }
22596
+ return new QueryImpl(query._repo, query._path, queryParamsLimitToLast(query._queryParams, this._limit), query._orderByCalled);
22597
+ }
22598
+ }
22599
+ /**
22600
+ * Creates a new `QueryConstraint` that is limited to return only the last
22601
+ * specified number of children.
22602
+ *
22603
+ * The `limitToLast()` method is used to set a maximum number of children to be
22604
+ * synced for a given callback. If we set a limit of 100, we will initially only
22605
+ * receive up to 100 `child_added` events. If we have fewer than 100 messages
22606
+ * stored in our Database, a `child_added` event will fire for each message.
22607
+ * However, if we have over 100 messages, we will only receive a `child_added`
22608
+ * event for the last 100 ordered messages. As items change, we will receive
22609
+ * `child_removed` events for each item that drops out of the active list so
22610
+ * that the total number stays at 100.
22611
+ *
22612
+ * You can read more about `limitToLast()` in
22613
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#filtering_data | Filtering data}.
22614
+ *
22615
+ * @param limit - The maximum number of nodes to include in this query.
22616
+ */
22617
+ function limitToLast(limit) {
22618
+ if (typeof limit !== 'number' || Math.floor(limit) !== limit || limit <= 0) {
22619
+ throw new Error('limitToLast: First argument must be a positive integer.');
22620
+ }
22621
+ return new QueryLimitToLastConstraint(limit);
22622
+ }
22623
+ class QueryOrderByChildConstraint extends QueryConstraint {
22624
+ constructor(_path) {
22625
+ super();
22626
+ this._path = _path;
22627
+ }
22628
+ _apply(query) {
22629
+ validateNoPreviousOrderByCall(query, 'orderByChild');
22630
+ const parsedPath = new Path(this._path);
22631
+ if (pathIsEmpty(parsedPath)) {
22632
+ throw new Error('orderByChild: cannot pass in empty path. Use orderByValue() instead.');
22633
+ }
22634
+ const index = new PathIndex(parsedPath);
22635
+ const newParams = queryParamsOrderBy(query._queryParams, index);
22636
+ validateQueryEndpoints(newParams);
22637
+ return new QueryImpl(query._repo, query._path, newParams,
22638
+ /*orderByCalled=*/ true);
22639
+ }
22640
+ }
22641
+ /**
22642
+ * Creates a new `QueryConstraint` that orders by the specified child key.
22643
+ *
22644
+ * Queries can only order by one key at a time. Calling `orderByChild()`
22645
+ * multiple times on the same query is an error.
22646
+ *
22647
+ * Firebase queries allow you to order your data by any child key on the fly.
22648
+ * However, if you know in advance what your indexes will be, you can define
22649
+ * them via the .indexOn rule in your Security Rules for better performance. See
22650
+ * the{@link https://firebase.google.com/docs/database/security/indexing-data}
22651
+ * rule for more information.
22652
+ *
22653
+ * You can read more about `orderByChild()` in
22654
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#sort_data | Sort data}.
22655
+ *
22656
+ * @param path - The path to order by.
22657
+ */
22658
+ function orderByChild(path) {
22659
+ if (path === '$key') {
22660
+ throw new Error('orderByChild: "$key" is invalid. Use orderByKey() instead.');
22661
+ }
22662
+ else if (path === '$priority') {
22663
+ throw new Error('orderByChild: "$priority" is invalid. Use orderByPriority() instead.');
22664
+ }
22665
+ else if (path === '$value') {
22666
+ throw new Error('orderByChild: "$value" is invalid. Use orderByValue() instead.');
22667
+ }
22668
+ validatePathString('orderByChild', 'path', path, false);
22669
+ return new QueryOrderByChildConstraint(path);
22670
+ }
22671
+ class QueryOrderByKeyConstraint extends QueryConstraint {
22672
+ _apply(query) {
22673
+ validateNoPreviousOrderByCall(query, 'orderByKey');
22674
+ const newParams = queryParamsOrderBy(query._queryParams, KEY_INDEX);
22675
+ validateQueryEndpoints(newParams);
22676
+ return new QueryImpl(query._repo, query._path, newParams,
22677
+ /*orderByCalled=*/ true);
20604
22678
  }
20605
22679
  }
20606
22680
  /**
20607
- * Represents the registration of a child_x event.
22681
+ * Creates a new `QueryConstraint` that orders by the key.
22682
+ *
22683
+ * Sorts the results of a query by their (ascending) key values.
22684
+ *
22685
+ * You can read more about `orderByKey()` in
22686
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#sort_data | Sort data}.
20608
22687
  */
20609
- class ChildEventRegistration {
20610
- constructor(eventType, callbackContext) {
20611
- this.eventType = eventType;
20612
- this.callbackContext = callbackContext;
20613
- }
20614
- respondsTo(eventType) {
20615
- let eventToCheck = eventType === 'children_added' ? 'child_added' : eventType;
20616
- eventToCheck =
20617
- eventToCheck === 'children_removed' ? 'child_removed' : eventToCheck;
20618
- return this.eventType === eventToCheck;
22688
+ function orderByKey() {
22689
+ return new QueryOrderByKeyConstraint();
22690
+ }
22691
+ class QueryOrderByPriorityConstraint extends QueryConstraint {
22692
+ _apply(query) {
22693
+ validateNoPreviousOrderByCall(query, 'orderByPriority');
22694
+ const newParams = queryParamsOrderBy(query._queryParams, PRIORITY_INDEX);
22695
+ validateQueryEndpoints(newParams);
22696
+ return new QueryImpl(query._repo, query._path, newParams,
22697
+ /*orderByCalled=*/ true);
20619
22698
  }
20620
- createCancelEvent(error, path) {
20621
- if (this.callbackContext.hasCancelCallback) {
20622
- return new CancelEvent(this, error, path);
20623
- }
20624
- else {
20625
- return null;
20626
- }
22699
+ }
22700
+ /**
22701
+ * Creates a new `QueryConstraint` that orders by priority.
22702
+ *
22703
+ * Applications need not use priority but can order collections by
22704
+ * ordinary properties (see
22705
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#sort_data | Sort data}
22706
+ * for alternatives to priority.
22707
+ */
22708
+ function orderByPriority() {
22709
+ return new QueryOrderByPriorityConstraint();
22710
+ }
22711
+ class QueryOrderByValueConstraint extends QueryConstraint {
22712
+ _apply(query) {
22713
+ validateNoPreviousOrderByCall(query, 'orderByValue');
22714
+ const newParams = queryParamsOrderBy(query._queryParams, VALUE_INDEX);
22715
+ validateQueryEndpoints(newParams);
22716
+ return new QueryImpl(query._repo, query._path, newParams,
22717
+ /*orderByCalled=*/ true);
20627
22718
  }
20628
- createEvent(change, query) {
20629
- assert(change.childName != null, 'Child events should have a childName.');
20630
- const childRef = child(new ReferenceImpl(query._repo, query._path), change.childName);
20631
- const index = query._queryParams.getIndex();
20632
- return new DataEvent(change.type, this, new DataSnapshot(change.snapshotNode, childRef, index), change.prevName);
22719
+ }
22720
+ /**
22721
+ * Creates a new `QueryConstraint` that orders by value.
22722
+ *
22723
+ * If the children of a query are all scalar values (string, number, or
22724
+ * boolean), you can order the results by their (ascending) values.
22725
+ *
22726
+ * You can read more about `orderByValue()` in
22727
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#sort_data | Sort data}.
22728
+ */
22729
+ function orderByValue() {
22730
+ return new QueryOrderByValueConstraint();
22731
+ }
22732
+ class QueryEqualToValueConstraint extends QueryConstraint {
22733
+ constructor(_value, _key) {
22734
+ super();
22735
+ this._value = _value;
22736
+ this._key = _key;
20633
22737
  }
20634
- getEventRunner(eventData) {
20635
- if (eventData.getEventType() === 'cancel') {
20636
- return () => this.callbackContext.onCancel(eventData.error);
22738
+ _apply(query) {
22739
+ validateFirebaseDataArg('equalTo', this._value, query._path, false);
22740
+ if (query._queryParams.hasStart()) {
22741
+ throw new Error('equalTo: Starting point was already set (by another call to startAt/startAfter or ' +
22742
+ 'equalTo).');
20637
22743
  }
20638
- else {
20639
- return () => this.callbackContext.onValue(eventData.snapshot, eventData.prevName);
20640
- }
20641
- }
20642
- matches(other) {
20643
- if (other instanceof ChildEventRegistration) {
20644
- return (this.eventType === other.eventType &&
20645
- (!this.callbackContext ||
20646
- !other.callbackContext ||
20647
- this.callbackContext.matches(other.callbackContext)));
22744
+ if (query._queryParams.hasEnd()) {
22745
+ throw new Error('equalTo: Ending point was already set (by another call to endAt/endBefore or ' +
22746
+ 'equalTo).');
20648
22747
  }
20649
- return false;
20650
- }
20651
- hasAnyCallback() {
20652
- return !!this.callbackContext;
22748
+ return new QueryEndAtConstraint(this._value, this._key)._apply(new QueryStartAtConstraint(this._value, this._key)._apply(query));
20653
22749
  }
20654
22750
  }
20655
- function addEventListener(query, eventType, callback, cancelCallbackOrListenOptions, options) {
20656
- let cancelCallback;
20657
- if (typeof cancelCallbackOrListenOptions === 'object') {
20658
- cancelCallback = undefined;
20659
- options = cancelCallbackOrListenOptions;
20660
- }
20661
- if (typeof cancelCallbackOrListenOptions === 'function') {
20662
- cancelCallback = cancelCallbackOrListenOptions;
20663
- }
20664
- if (options && options.onlyOnce) {
20665
- const userCallback = callback;
20666
- const onceCallback = (dataSnapshot, previousChildName) => {
20667
- repoRemoveEventCallbackForQuery(query._repo, query, container);
20668
- userCallback(dataSnapshot, previousChildName);
20669
- };
20670
- onceCallback.userCallback = callback.userCallback;
20671
- onceCallback.context = callback.context;
20672
- callback = onceCallback;
20673
- }
20674
- const callbackContext = new CallbackContext(callback, cancelCallback || undefined);
20675
- const container = eventType === 'value'
20676
- ? new ValueEventRegistration(callbackContext)
20677
- : new ChildEventRegistration(eventType, callbackContext);
20678
- repoAddEventCallbackForQuery(query._repo, query, container);
20679
- return () => repoRemoveEventCallbackForQuery(query._repo, query, container);
22751
+ /**
22752
+ * Creates a `QueryConstraint` that includes children that match the specified
22753
+ * value.
22754
+ *
22755
+ * Using `startAt()`, `startAfter()`, `endBefore()`, `endAt()` and `equalTo()`
22756
+ * allows you to choose arbitrary starting and ending points for your queries.
22757
+ *
22758
+ * The optional key argument can be used to further limit the range of the
22759
+ * query. If it is specified, then children that have exactly the specified
22760
+ * value must also have exactly the specified key as their key name. This can be
22761
+ * used to filter result sets with many matches for the same value.
22762
+ *
22763
+ * You can read more about `equalTo()` in
22764
+ * {@link https://firebase.google.com/docs/database/web/lists-of-data#filtering_data | Filtering data}.
22765
+ *
22766
+ * @param value - The value to match for. The argument type depends on which
22767
+ * `orderBy*()` function was used in this query. Specify a value that matches
22768
+ * the `orderBy*()` type. When used in combination with `orderByKey()`, the
22769
+ * value must be a string.
22770
+ * @param key - The child key to start at, among the children with the
22771
+ * previously specified priority. This argument is only allowed if ordering by
22772
+ * child, value, or priority.
22773
+ */
22774
+ function equalTo(value, key) {
22775
+ validateKey('equalTo', 'key', key, true);
22776
+ return new QueryEqualToValueConstraint(value, key);
20680
22777
  }
20681
- function onValue(query, callback, cancelCallbackOrListenOptions, options) {
20682
- return addEventListener(query, 'value', callback, cancelCallbackOrListenOptions, options);
22778
+ /**
22779
+ * Creates a new immutable instance of `Query` that is extended to also include
22780
+ * additional query constraints.
22781
+ *
22782
+ * @param query - The Query instance to use as a base for the new constraints.
22783
+ * @param queryConstraints - The list of `QueryConstraint`s to apply.
22784
+ * @throws if any of the provided query constraints cannot be combined with the
22785
+ * existing or new constraints.
22786
+ */
22787
+ function query(query, ...queryConstraints) {
22788
+ let queryImpl = getModularInstance(query);
22789
+ for (const constraint of queryConstraints) {
22790
+ queryImpl = constraint._apply(queryImpl);
22791
+ }
22792
+ return queryImpl;
20683
22793
  }
20684
22794
  /**
20685
22795
  * Define reference constructor in various modules
@@ -20809,6 +22919,12 @@ function repoManagerCreateRepo(repoInfo, app, authTokenProvider, appCheckProvide
20809
22919
  appRepos[repoInfo.toURLString()] = repo;
20810
22920
  return repo;
20811
22921
  }
22922
+ /**
22923
+ * Forces us to use ReadonlyRestClient instead of PersistentConnection for new Repos.
22924
+ */
22925
+ function repoManagerForceRestClient(forceRestClient) {
22926
+ useRestClient = forceRestClient;
22927
+ }
20812
22928
  /**
20813
22929
  * Class representing a Firebase Realtime Database.
20814
22930
  */
@@ -20851,6 +22967,26 @@ class Database {
20851
22967
  }
20852
22968
  }
20853
22969
  }
22970
+ function checkTransportInit() {
22971
+ if (TransportManager.IS_TRANSPORT_INITIALIZED) {
22972
+ warn('Transport has already been initialized. Please call this function before calling ref or setting up a listener');
22973
+ }
22974
+ }
22975
+ /**
22976
+ * Force the use of websockets instead of longPolling.
22977
+ */
22978
+ function forceWebSockets() {
22979
+ checkTransportInit();
22980
+ BrowserPollConnection.forceDisallow();
22981
+ }
22982
+ /**
22983
+ * Force the use of longPolling instead of websockets. This will be ignored if websocket protocol is used in databaseURL.
22984
+ */
22985
+ function forceLongPolling() {
22986
+ checkTransportInit();
22987
+ WebSocketConnection.forceDisallow();
22988
+ BrowserPollConnection.forceAllow();
22989
+ }
20854
22990
  /**
20855
22991
  * Returns the instance of the Realtime Database SDK that is associated
20856
22992
  * with the provided {@link @firebase/app#FirebaseApp}. Initializes a new instance with
@@ -20909,6 +23045,51 @@ function connectDatabaseEmulator(db, host, port, options = {}) {
20909
23045
  // Modify the repo to apply emulator settings
20910
23046
  repoManagerApplyEmulatorSettings(repo, host, port, tokenProvider);
20911
23047
  }
23048
+ /**
23049
+ * Disconnects from the server (all Database operations will be completed
23050
+ * offline).
23051
+ *
23052
+ * The client automatically maintains a persistent connection to the Database
23053
+ * server, which will remain active indefinitely and reconnect when
23054
+ * disconnected. However, the `goOffline()` and `goOnline()` methods may be used
23055
+ * to control the client connection in cases where a persistent connection is
23056
+ * undesirable.
23057
+ *
23058
+ * While offline, the client will no longer receive data updates from the
23059
+ * Database. However, all Database operations performed locally will continue to
23060
+ * immediately fire events, allowing your application to continue behaving
23061
+ * normally. Additionally, each operation performed locally will automatically
23062
+ * be queued and retried upon reconnection to the Database server.
23063
+ *
23064
+ * To reconnect to the Database and begin receiving remote events, see
23065
+ * `goOnline()`.
23066
+ *
23067
+ * @param db - The instance to disconnect.
23068
+ */
23069
+ function goOffline(db) {
23070
+ db = getModularInstance(db);
23071
+ db._checkNotDeleted('goOffline');
23072
+ repoInterrupt(db._repo);
23073
+ }
23074
+ /**
23075
+ * Reconnects to the server and synchronizes the offline Database state
23076
+ * with the server state.
23077
+ *
23078
+ * This method should be used after disabling the active connection with
23079
+ * `goOffline()`. Once reconnected, the client will transmit the proper data
23080
+ * and fire the appropriate events so that your client "catches up"
23081
+ * automatically.
23082
+ *
23083
+ * @param db - The instance to reconnect.
23084
+ */
23085
+ function goOnline(db) {
23086
+ db = getModularInstance(db);
23087
+ db._checkNotDeleted('goOnline');
23088
+ repoResume(db._repo);
23089
+ }
23090
+ function enableLogging(logger, persistent) {
23091
+ enableLogging$1(logger, persistent);
23092
+ }
20912
23093
 
20913
23094
  /**
20914
23095
  * @license
@@ -20938,6 +23119,164 @@ function registerDatabase(variant) {
20938
23119
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
20939
23120
  registerVersion(name, version, 'esm2017');
20940
23121
  }
23122
+
23123
+ /**
23124
+ * @license
23125
+ * Copyright 2020 Google LLC
23126
+ *
23127
+ * Licensed under the Apache License, Version 2.0 (the "License");
23128
+ * you may not use this file except in compliance with the License.
23129
+ * You may obtain a copy of the License at
23130
+ *
23131
+ * http://www.apache.org/licenses/LICENSE-2.0
23132
+ *
23133
+ * Unless required by applicable law or agreed to in writing, software
23134
+ * distributed under the License is distributed on an "AS IS" BASIS,
23135
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23136
+ * See the License for the specific language governing permissions and
23137
+ * limitations under the License.
23138
+ */
23139
+ const SERVER_TIMESTAMP = {
23140
+ '.sv': 'timestamp'
23141
+ };
23142
+ /**
23143
+ * Returns a placeholder value for auto-populating the current timestamp (time
23144
+ * since the Unix epoch, in milliseconds) as determined by the Firebase
23145
+ * servers.
23146
+ */
23147
+ function serverTimestamp() {
23148
+ return SERVER_TIMESTAMP;
23149
+ }
23150
+ /**
23151
+ * Returns a placeholder value that can be used to atomically increment the
23152
+ * current database value by the provided delta.
23153
+ *
23154
+ * @param delta - the amount to modify the current value atomically.
23155
+ * @returns A placeholder value for modifying data atomically server-side.
23156
+ */
23157
+ function increment(delta) {
23158
+ return {
23159
+ '.sv': {
23160
+ 'increment': delta
23161
+ }
23162
+ };
23163
+ }
23164
+
23165
+ /**
23166
+ * @license
23167
+ * Copyright 2020 Google LLC
23168
+ *
23169
+ * Licensed under the Apache License, Version 2.0 (the "License");
23170
+ * you may not use this file except in compliance with the License.
23171
+ * You may obtain a copy of the License at
23172
+ *
23173
+ * http://www.apache.org/licenses/LICENSE-2.0
23174
+ *
23175
+ * Unless required by applicable law or agreed to in writing, software
23176
+ * distributed under the License is distributed on an "AS IS" BASIS,
23177
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23178
+ * See the License for the specific language governing permissions and
23179
+ * limitations under the License.
23180
+ */
23181
+ /**
23182
+ * A type for the resolve value of {@link runTransaction}.
23183
+ */
23184
+ class TransactionResult {
23185
+ /** @hideconstructor */
23186
+ constructor(
23187
+ /** Whether the transaction was successfully committed. */
23188
+ committed,
23189
+ /** The resulting data snapshot. */
23190
+ snapshot) {
23191
+ this.committed = committed;
23192
+ this.snapshot = snapshot;
23193
+ }
23194
+ /** Returns a JSON-serializable representation of this object. */
23195
+ toJSON() {
23196
+ return { committed: this.committed, snapshot: this.snapshot.toJSON() };
23197
+ }
23198
+ }
23199
+ /**
23200
+ * Atomically modifies the data at this location.
23201
+ *
23202
+ * Atomically modify the data at this location. Unlike a normal `set()`, which
23203
+ * just overwrites the data regardless of its previous value, `runTransaction()` is
23204
+ * used to modify the existing value to a new value, ensuring there are no
23205
+ * conflicts with other clients writing to the same location at the same time.
23206
+ *
23207
+ * To accomplish this, you pass `runTransaction()` an update function which is
23208
+ * used to transform the current value into a new value. If another client
23209
+ * writes to the location before your new value is successfully written, your
23210
+ * update function will be called again with the new current value, and the
23211
+ * write will be retried. This will happen repeatedly until your write succeeds
23212
+ * without conflict or you abort the transaction by not returning a value from
23213
+ * your update function.
23214
+ *
23215
+ * Note: Modifying data with `set()` will cancel any pending transactions at
23216
+ * that location, so extreme care should be taken if mixing `set()` and
23217
+ * `runTransaction()` to update the same data.
23218
+ *
23219
+ * Note: When using transactions with Security and Firebase Rules in place, be
23220
+ * aware that a client needs `.read` access in addition to `.write` access in
23221
+ * order to perform a transaction. This is because the client-side nature of
23222
+ * transactions requires the client to read the data in order to transactionally
23223
+ * update it.
23224
+ *
23225
+ * @param ref - The location to atomically modify.
23226
+ * @param transactionUpdate - A developer-supplied function which will be passed
23227
+ * the current data stored at this location (as a JavaScript object). The
23228
+ * function should return the new value it would like written (as a JavaScript
23229
+ * object). If `undefined` is returned (i.e. you return with no arguments) the
23230
+ * transaction will be aborted and the data at this location will not be
23231
+ * modified.
23232
+ * @param options - An options object to configure transactions.
23233
+ * @returns A `Promise` that can optionally be used instead of the `onComplete`
23234
+ * callback to handle success and failure.
23235
+ */
23236
+ function runTransaction(ref,
23237
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23238
+ transactionUpdate, options) {
23239
+ var _a;
23240
+ ref = getModularInstance(ref);
23241
+ validateWritablePath('Reference.transaction', ref._path);
23242
+ if (ref.key === '.length' || ref.key === '.keys') {
23243
+ throw ('Reference.transaction failed: ' + ref.key + ' is a read-only object.');
23244
+ }
23245
+ const applyLocally = (_a = options === null || options === void 0 ? void 0 : options.applyLocally) !== null && _a !== void 0 ? _a : true;
23246
+ const deferred = new Deferred();
23247
+ const promiseComplete = (error, committed, node) => {
23248
+ let dataSnapshot = null;
23249
+ if (error) {
23250
+ deferred.reject(error);
23251
+ }
23252
+ else {
23253
+ dataSnapshot = new DataSnapshot(node, new ReferenceImpl(ref._repo, ref._path), PRIORITY_INDEX);
23254
+ deferred.resolve(new TransactionResult(committed, dataSnapshot));
23255
+ }
23256
+ };
23257
+ // Add a watch to make sure we get server updates.
23258
+ const unwatcher = onValue(ref, () => { });
23259
+ repoStartTransaction(ref._repo, ref._path, transactionUpdate, promiseComplete, unwatcher, applyLocally);
23260
+ return deferred.promise;
23261
+ }
23262
+
23263
+ /**
23264
+ * @license
23265
+ * Copyright 2017 Google LLC
23266
+ *
23267
+ * Licensed under the Apache License, Version 2.0 (the "License");
23268
+ * you may not use this file except in compliance with the License.
23269
+ * You may obtain a copy of the License at
23270
+ *
23271
+ * http://www.apache.org/licenses/LICENSE-2.0
23272
+ *
23273
+ * Unless required by applicable law or agreed to in writing, software
23274
+ * distributed under the License is distributed on an "AS IS" BASIS,
23275
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23276
+ * See the License for the specific language governing permissions and
23277
+ * limitations under the License.
23278
+ */
23279
+ PersistentConnection;
20941
23280
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20942
23281
  PersistentConnection.prototype.simpleListen = function (pathString, onComplete) {
20943
23282
  this.sendRequest('q', { p: pathString }, onComplete);
@@ -20946,6 +23285,31 @@ PersistentConnection.prototype.simpleListen = function (pathString, onComplete)
20946
23285
  PersistentConnection.prototype.echo = function (data, onEcho) {
20947
23286
  this.sendRequest('echo', { d: data }, onEcho);
20948
23287
  };
23288
+ // RealTimeConnection properties that we use in tests.
23289
+ Connection;
23290
+ /**
23291
+ * @internal
23292
+ */
23293
+ const hijackHash = function (newHash) {
23294
+ const oldPut = PersistentConnection.prototype.put;
23295
+ PersistentConnection.prototype.put = function (pathString, data, onComplete, hash) {
23296
+ if (hash !== undefined) {
23297
+ hash = newHash();
23298
+ }
23299
+ oldPut.call(this, pathString, data, onComplete, hash);
23300
+ };
23301
+ return function () {
23302
+ PersistentConnection.prototype.put = oldPut;
23303
+ };
23304
+ };
23305
+ RepoInfo;
23306
+ /**
23307
+ * Forces the RepoManager to create Repos that use ReadonlyRestClient instead of PersistentConnection.
23308
+ * @internal
23309
+ */
23310
+ const forceRestClient = function (forceRestClient) {
23311
+ repoManagerForceRestClient(forceRestClient);
23312
+ };
20949
23313
 
20950
23314
  /**
20951
23315
  * Firebase Realtime Database
@@ -20954,8 +23318,8 @@ PersistentConnection.prototype.echo = function (data, onEcho) {
20954
23318
  */
20955
23319
  registerDatabase();
20956
23320
 
20957
- var dayjs_min = _commonjsHelpers.createCommonjsModule(function (module, exports) {
20958
- !function(t,e){module.exports=e();}(_commonjsHelpers.commonjsGlobal,(function(){var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",f="month",h="quarter",c="year",d="date",$="Invalid Date",l=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},m=function(t,e,n){var r=String(t);return !r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},g={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return (e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()<n.date())return -t(n,e);var r=12*(n.year()-e.year())+(n.month()-e.month()),i=e.clone().add(r,f),s=n-i<0,u=e.clone().add(r+(s?-1:1),f);return +(-(r+(n-i)/(s?i-u:u-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return {M:f,y:c,w:o,d:a,D:d,h:u,m:s,s:i,ms:r,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},D="en",v={};v[D]=M;var p=function(t){return t instanceof _},S=function(t,e,n){var r;if(!t)return D;if("string"==typeof t)v[t]&&(r=t),e&&(v[t]=e,r=t);else {var i=t.name;v[i]=t,r=i;}return !n&&r&&(D=r),r||!n&&D},w=function(t,e){if(p(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},O=g;O.l=S,O.i=p,O.w=function(t,e){return w(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=S(t.locale,null,!0),this.parse(t);}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(l);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.$x=t.x||{},this.init();},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds();},m.$utils=function(){return O},m.isValid=function(){return !(this.$d.toString()===$)},m.isSame=function(t,e){var n=w(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return w(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<w(t)},m.$g=function(t,e,n){return O.u(t)?this[e]:this.set(n,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var n=this,r=!!O.u(e)||e,h=O.p(t),$=function(t,e){var i=O.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return r?i:i.endOf(a)},l=function(t,e){return O.w(n.toDate()[t].apply(n.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},y=this.$W,M=this.$M,m=this.$D,g="set"+(this.$u?"UTC":"");switch(h){case c:return r?$(1,0):$(31,11);case f:return r?$(1,M):$(0,M+1);case o:var D=this.$locale().weekStart||0,v=(y<D?y+7:y)-D;return $(r?m-v:m+(6-v),M);case a:case d:return l(g+"Hours",0);case u:return l(g+"Minutes",1);case s:return l(g+"Seconds",2);case i:return l(g+"Milliseconds",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,!1)},m.$set=function(t,e){var n,o=O.p(t),h="set"+(this.$u?"UTC":""),$=(n={},n[a]=h+"Date",n[d]=h+"Date",n[f]=h+"Month",n[c]=h+"FullYear",n[u]=h+"Hours",n[s]=h+"Minutes",n[i]=h+"Seconds",n[r]=h+"Milliseconds",n)[o],l=o===a?this.$D+(e-this.$W):e;if(o===f||o===c){var y=this.clone().set(d,1);y.$d[$](l),y.init(),this.$d=y.set(d,Math.min(this.$D,y.daysInMonth())).$d;}else $&&this.$d[$](l);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[O.p(t)]()},m.add=function(r,h){var d,$=this;r=Number(r);var l=O.p(h),y=function(t){var e=w($);return O.w(e.date(e.date()+Math.round(t*r)),$)};if(l===f)return this.set(f,this.$M+r);if(l===c)return this.set(c,this.$y+r);if(l===a)return y(1);if(l===o)return y(7);var M=(d={},d[s]=e,d[u]=n,d[i]=t,d)[l]||1,m=this.$d.getTime()+r*M;return O.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||$;var r=t||"YYYY-MM-DDTHH:mm:ssZ",i=O.z(this),s=this.$H,u=this.$m,a=this.$M,o=n.weekdays,f=n.months,h=function(t,n,i,s){return t&&(t[n]||t(e,r))||i[n].substr(0,s)},c=function(t){return O.s(s%12||12,t,"0")},d=n.meridiem||function(t,e,n){var r=t<12?"AM":"PM";return n?r.toLowerCase():r},l={YY:String(this.$y).slice(-2),YYYY:this.$y,M:a+1,MM:O.s(a+1,2,"0"),MMM:h(n.monthsShort,a,f,3),MMMM:h(f,a),D:this.$D,DD:O.s(this.$D,2,"0"),d:String(this.$W),dd:h(n.weekdaysMin,this.$W,o,2),ddd:h(n.weekdaysShort,this.$W,o,3),dddd:o[this.$W],H:String(s),HH:O.s(s,2,"0"),h:c(1),hh:c(2),a:d(s,u,!0),A:d(s,u,!1),m:String(u),mm:O.s(u,2,"0"),s:String(this.$s),ss:O.s(this.$s,2,"0"),SSS:O.s(this.$ms,3,"0"),Z:i};return r.replace(y,(function(t,e){return e||l[t]||i.replace(":","")}))},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(r,d,$){var l,y=O.p(d),M=w(r),m=(M.utcOffset()-this.utcOffset())*e,g=this-M,D=O.m(this,M);return D=(l={},l[c]=D/12,l[f]=D,l[h]=D/3,l[o]=(g-m)/6048e5,l[a]=(g-m)/864e5,l[u]=g/n,l[s]=g/e,l[i]=g/t,l)[y]||g,$?D:O.a(D)},m.daysInMonth=function(){return this.endOf(f).$D},m.$locale=function(){return v[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),r=S(t,e,!0);return r&&(n.$L=r),n},m.clone=function(){return O.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},M}(),b=_.prototype;return w.prototype=b,[["$ms",r],["$s",i],["$m",s],["$H",u],["$W",a],["$M",f],["$y",c],["$D",d]].forEach((function(t){b[t[1]]=function(e){return this.$g(e,t[0],t[1])};})),w.extend=function(t,e){return t.$i||(t(e,_,w),t.$i=!0),w},w.locale=S,w.isDayjs=p,w.unix=function(t){return w(1e3*t)},w.en=v[D],w.Ls=v,w.p={},w}));
23321
+ var dayjs_min = createCommonjsModule(function (module, exports) {
23322
+ !function(t,e){"object"=='object'&&"undefined"!='object'?module.exports=e():"function"==typeof undefined&&undefined.amd?undefined(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs=e();}(commonjsGlobal,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",f="month",h="quarter",c="year",d="date",$="Invalid Date",l=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},m=function(t,e,n){var r=String(t);return !r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},g={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return (e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()<n.date())return -t(n,e);var r=12*(n.year()-e.year())+(n.month()-e.month()),i=e.clone().add(r,f),s=n-i<0,u=e.clone().add(r+(s?-1:1),f);return +(-(r+(n-i)/(s?i-u:u-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return {M:f,y:c,w:o,d:a,D:d,h:u,m:s,s:i,ms:r,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},D="en",v={};v[D]=M;var p=function(t){return t instanceof _},S=function(t,e,n){var r;if(!t)return D;if("string"==typeof t)v[t]&&(r=t),e&&(v[t]=e,r=t);else {var i=t.name;v[i]=t,r=i;}return !n&&r&&(D=r),r||!n&&D},w=function(t,e){if(p(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},O=g;O.l=S,O.i=p,O.w=function(t,e){return w(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=S(t.locale,null,!0),this.parse(t);}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(l);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.$x=t.x||{},this.init();},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds();},m.$utils=function(){return O},m.isValid=function(){return !(this.$d.toString()===$)},m.isSame=function(t,e){var n=w(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return w(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<w(t)},m.$g=function(t,e,n){return O.u(t)?this[e]:this.set(n,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var n=this,r=!!O.u(e)||e,h=O.p(t),$=function(t,e){var i=O.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return r?i:i.endOf(a)},l=function(t,e){return O.w(n.toDate()[t].apply(n.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},y=this.$W,M=this.$M,m=this.$D,g="set"+(this.$u?"UTC":"");switch(h){case c:return r?$(1,0):$(31,11);case f:return r?$(1,M):$(0,M+1);case o:var D=this.$locale().weekStart||0,v=(y<D?y+7:y)-D;return $(r?m-v:m+(6-v),M);case a:case d:return l(g+"Hours",0);case u:return l(g+"Minutes",1);case s:return l(g+"Seconds",2);case i:return l(g+"Milliseconds",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,!1)},m.$set=function(t,e){var n,o=O.p(t),h="set"+(this.$u?"UTC":""),$=(n={},n[a]=h+"Date",n[d]=h+"Date",n[f]=h+"Month",n[c]=h+"FullYear",n[u]=h+"Hours",n[s]=h+"Minutes",n[i]=h+"Seconds",n[r]=h+"Milliseconds",n)[o],l=o===a?this.$D+(e-this.$W):e;if(o===f||o===c){var y=this.clone().set(d,1);y.$d[$](l),y.init(),this.$d=y.set(d,Math.min(this.$D,y.daysInMonth())).$d;}else $&&this.$d[$](l);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[O.p(t)]()},m.add=function(r,h){var d,$=this;r=Number(r);var l=O.p(h),y=function(t){var e=w($);return O.w(e.date(e.date()+Math.round(t*r)),$)};if(l===f)return this.set(f,this.$M+r);if(l===c)return this.set(c,this.$y+r);if(l===a)return y(1);if(l===o)return y(7);var M=(d={},d[s]=e,d[u]=n,d[i]=t,d)[l]||1,m=this.$d.getTime()+r*M;return O.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||$;var r=t||"YYYY-MM-DDTHH:mm:ssZ",i=O.z(this),s=this.$H,u=this.$m,a=this.$M,o=n.weekdays,f=n.months,h=function(t,n,i,s){return t&&(t[n]||t(e,r))||i[n].substr(0,s)},c=function(t){return O.s(s%12||12,t,"0")},d=n.meridiem||function(t,e,n){var r=t<12?"AM":"PM";return n?r.toLowerCase():r},l={YY:String(this.$y).slice(-2),YYYY:this.$y,M:a+1,MM:O.s(a+1,2,"0"),MMM:h(n.monthsShort,a,f,3),MMMM:h(f,a),D:this.$D,DD:O.s(this.$D,2,"0"),d:String(this.$W),dd:h(n.weekdaysMin,this.$W,o,2),ddd:h(n.weekdaysShort,this.$W,o,3),dddd:o[this.$W],H:String(s),HH:O.s(s,2,"0"),h:c(1),hh:c(2),a:d(s,u,!0),A:d(s,u,!1),m:String(u),mm:O.s(u,2,"0"),s:String(this.$s),ss:O.s(this.$s,2,"0"),SSS:O.s(this.$ms,3,"0"),Z:i};return r.replace(y,(function(t,e){return e||l[t]||i.replace(":","")}))},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(r,d,$){var l,y=O.p(d),M=w(r),m=(M.utcOffset()-this.utcOffset())*e,g=this-M,D=O.m(this,M);return D=(l={},l[c]=D/12,l[f]=D,l[h]=D/3,l[o]=(g-m)/6048e5,l[a]=(g-m)/864e5,l[u]=g/n,l[s]=g/e,l[i]=g/t,l)[y]||g,$?D:O.a(D)},m.daysInMonth=function(){return this.endOf(f).$D},m.$locale=function(){return v[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),r=S(t,e,!0);return r&&(n.$L=r),n},m.clone=function(){return O.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},M}(),b=_.prototype;return w.prototype=b,[["$ms",r],["$s",i],["$m",s],["$H",u],["$W",a],["$M",f],["$y",c],["$D",d]].forEach((function(t){b[t[1]]=function(e){return this.$g(e,t[0],t[1])};})),w.extend=function(t,e){return t.$i||(t(e,_,w),t.$i=!0),w},w.locale=S,w.isDayjs=p,w.unix=function(t){return w(1e3*t)},w.en=v[D],w.Ls=v,w.p={},w}));
20959
23323
  });
20960
23324
 
20961
23325
  function createService(blob) {
@@ -21022,6 +23386,23 @@ function createUser(blob) {
21022
23386
  lastName: blob.last_name,
21023
23387
  fullName: userNames.length > 0 ? userNames.join(' ') : (blob.fullName || blob.name || blob.username),
21024
23388
  avatar: blob.avatar || blob.full_profile_image_thumb,
23389
+ mobilePhone: blob.mobile_phone,
23390
+ accessToken: blob.access_token,
23391
+ email: blob.email,
23392
+ password: blob.password,
23393
+ };
23394
+ }
23395
+ function createUserFromChatRoom(blob) {
23396
+ const fullName = blob.salon_detail
23397
+ ? blob.salon_detail.business_name
23398
+ : [blob.first_name, blob.last_name].filter(name => !!name).join(' ');
23399
+ return {
23400
+ id: blob.id || blob.user_id,
23401
+ firstName: blob.first_name,
23402
+ lastName: blob.last_name,
23403
+ fullName: fullName || blob.email || blob.mobile_phone,
23404
+ avatar: blob.avatar || blob.full_profile_image_thumb,
23405
+ mobilePhone: blob.mobile_phone,
21025
23406
  };
21026
23407
  }
21027
23408
 
@@ -21156,6 +23537,8 @@ function createReviewPhoto(blob) {
21156
23537
  imageUrlThumb: blob.full_image_url_thumb,
21157
23538
  };
21158
23539
  }
23540
+ class Review {
23541
+ }
21159
23542
  function createReview(blob) {
21160
23543
  const reviewPhotos = blob.review_photo || [];
21161
23544
  const [createdDay, createdTime] = String(blob.create_date).split(' ');
@@ -21188,6 +23571,7 @@ function createChatMessage(blob) {
21188
23571
  timestamp: blob.timestamp,
21189
23572
  unRead: blob.unRead,
21190
23573
  senderId: Number(blob.senderId),
23574
+ dateName: dayjs_min(blob.timestamp).format(shortDateYearFormat),
21191
23575
  };
21192
23576
  }
21193
23577
  class ChatRoom {
@@ -21199,22 +23583,11 @@ function createChatRoom(blob) {
21199
23583
  return new ChatRoom({
21200
23584
  id: blob.id,
21201
23585
  uid: blob.firebase_room_id,
21202
- members: blob.from_user && blob.to_user ? [createUser(blob.from_user), createUser(blob.to_user)] : [],
23586
+ members: blob.from_user && blob.to_user ? [createUserFromChatRoom(blob.from_user), createUserFromChatRoom(blob.to_user)] : [],
21203
23587
  messages: [],
21204
23588
  });
21205
23589
  }
21206
23590
 
21207
- var __rest = (undefined && undefined.__rest) || function (s, e) {
21208
- var t = {};
21209
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
21210
- t[p] = s[p];
21211
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
21212
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
21213
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
21214
- t[p[i]] = s[p[i]];
21215
- }
21216
- return t;
21217
- };
21218
23591
  const apiV2Prefix = 'api-ver2';
21219
23592
  const firebaseMessagesNode = 'favesalon--messages';
21220
23593
  class HttpService {
@@ -21241,6 +23614,57 @@ class HttpService {
21241
23614
  }
21242
23615
  catch (error) { }
21243
23616
  }
23617
+ login(apiUrl, options) {
23618
+ const url = `${apiUrl}/${apiV2Prefix}/user/login`;
23619
+ return this.http.post(url, options)
23620
+ .then(response => {
23621
+ const status = get_1(response, 'data.status');
23622
+ const blob = get_1(response, 'data.data');
23623
+ if (status && blob.id) {
23624
+ const userEntity = createUser(blob);
23625
+ return Promise.resolve(userEntity);
23626
+ }
23627
+ return Promise.reject(response);
23628
+ });
23629
+ }
23630
+ register(options) {
23631
+ const url = `${apiV2Prefix}/user/create`;
23632
+ return this.http.post(url, options);
23633
+ }
23634
+ resendActivateCode(email) {
23635
+ const url = `${apiV2Prefix}/user/resend-activate?email=${email}`;
23636
+ return this.http.get(url);
23637
+ }
23638
+ activateAccount(email, code) {
23639
+ const url = `${apiV2Prefix}/user/active?email=${email}&code=${code}`;
23640
+ return this.http.get(url);
23641
+ }
23642
+ resetPassword(email) {
23643
+ const url = `${apiV2Prefix}/user/forgot-password?${email.indexOf('@') > -1 ? 'email' : 'phone'}=${email}`;
23644
+ return this.http.get(url);
23645
+ }
23646
+ onChangePassword(options) {
23647
+ const url = `${apiV2Prefix}/user/change-password`;
23648
+ return this.http.post(url, options);
23649
+ }
23650
+ fetchClients(salonId, keyword, accessToken) {
23651
+ const url = `${apiV1Prefix}/salon/clients/list/${salonId}?page=1&limit=10&access_token=${accessToken}`;
23652
+ const payload = {
23653
+ keyword,
23654
+ is_allow_get_ads: -1,
23655
+ day_since_last_visit: -1,
23656
+ sort_by: 2,
23657
+ };
23658
+ return this.http.post(url, payload)
23659
+ .then((response) => {
23660
+ const { status, data } = response.data;
23661
+ if (status) {
23662
+ return (data || []).map(blob => createUser(blob.user));
23663
+ }
23664
+ return [];
23665
+ })
23666
+ .catch(() => ([]));
23667
+ }
21244
23668
  fetchStyleDetail(styleId) {
21245
23669
  return this.http.get(`${apiV2Prefix}/style/${styleId}/detail`)
21246
23670
  .then((response) => {
@@ -21271,7 +23695,7 @@ class HttpService {
21271
23695
  }
21272
23696
  fetchSalonLatestStyles(salonId, options) {
21273
23697
  const url = `${apiV2Prefix}/salon/${salonId}/styles`;
21274
- return this.http.post(url, Object.assign(Object.assign({}, options), { sort: 'newest' }))
23698
+ return this.http.post(url, { ...options, sort: 'newest' })
21275
23699
  .then(response => {
21276
23700
  const { data } = response.data;
21277
23701
  return (data || []).slice(0, options.limit).map(createFaveStyle);
@@ -21295,7 +23719,7 @@ class HttpService {
21295
23719
  type: 'sub-category',
21296
23720
  data: (subCate.services || []).map(rawService => {
21297
23721
  const serviceObj = createService(rawService);
21298
- return Object.assign(Object.assign({}, serviceObj), { type: 'service' });
23722
+ return { ...serviceObj, type: 'service' };
21299
23723
  }),
21300
23724
  };
21301
23725
  }),
@@ -21328,7 +23752,7 @@ class HttpService {
21328
23752
  }
21329
23753
  fetchSalonReviews(salonId, options) {
21330
23754
  const url = `${apiV2Prefix}/salon/${salonId}/reviews`;
21331
- return this.http.post(url, Object.assign({ avg_point_greater_than: 0 }, options))
23755
+ return this.http.post(url, { avg_point_greater_than: 0, ...options })
21332
23756
  .then(response => {
21333
23757
  const { data, paging } = response.data || {};
21334
23758
  const { total_1star: onestar, total_2star: twoStar, total_3star: threeStar, total_4star: fourStar, total_5star: fiveStar, total_review: totalReviews, avg_point: reviewPoint, } = paging.review_detail || {};
@@ -21369,7 +23793,11 @@ class HttpService {
21369
23793
  fetchSalonLookbooks(salonId, options) {
21370
23794
  const noResult = { total: 0, allLookbooks: [] };
21371
23795
  const url = `${apiV2Prefix}/salon/${salonId}/styles`;
21372
- const postData = Object.assign({ page: 1, limit: 20 }, options);
23796
+ const postData = {
23797
+ page: 1,
23798
+ limit: 20,
23799
+ ...options,
23800
+ };
21373
23801
  return this.http.post(url, postData)
21374
23802
  .then(response => {
21375
23803
  const { status, data, paging } = response.data;
@@ -21428,7 +23856,7 @@ class HttpService {
21428
23856
  onValue(roomMessagesRef, (snapshot) => {
21429
23857
  const conversations = [];
21430
23858
  each$1(snapshot.val(), (message, key) => {
21431
- const chatMessage = createChatMessage(Object.assign(Object.assign({}, message), { uid: key }));
23859
+ const chatMessage = createChatMessage({ ...message, uid: key });
21432
23860
  conversations.push(chatMessage);
21433
23861
  });
21434
23862
  onDone(sortBy_1(conversations, 'timestamp'));
@@ -21446,8 +23874,8 @@ class HttpService {
21446
23874
  const roomMessagesRef = ref(this.firebaseDatabase, `${firebaseMessagesNode}/${roomId}`);
21447
23875
  const updates = {};
21448
23876
  roomMessages.forEach(message => {
21449
- const nestedMessage = __rest(message, ["uid"]);
21450
- updates[`${message.uid}`] = Object.assign(Object.assign({}, nestedMessage), { unRead: 0 });
23877
+ const { uid, ...nestedMessage } = message;
23878
+ updates[`${message.uid}`] = { ...nestedMessage, unRead: 0 };
21451
23879
  });
21452
23880
  return update(roomMessagesRef, updates);
21453
23881
  }
@@ -21475,7 +23903,10 @@ class HttpService {
21475
23903
  };
21476
23904
  return update(roomMessagesRef, updates)
21477
23905
  .then(() => {
21478
- return Object.assign(Object.assign({}, newMessage), { uid: newMessageKey });
23906
+ return {
23907
+ ...newMessage,
23908
+ uid: newMessageKey,
23909
+ };
21479
23910
  });
21480
23911
  }
21481
23912
  catch (error) { }
@@ -21485,10 +23916,4 @@ class HttpService {
21485
23916
  }
21486
23917
  const HttpService$1 = () => new HttpService();
21487
23918
 
21488
- exports.HttpService = HttpService$1;
21489
- exports.dateFormat = dateFormat;
21490
- exports.dayjs_min = dayjs_min;
21491
- exports.getSalonImage = getSalonImage;
21492
- exports.isVideoMedia = isVideoMedia;
21493
- exports.shortDateYearFormat = shortDateYearFormat;
21494
- exports.sortBy_1 = sortBy_1;
23919
+ export { BusinessHourStatus as B, HttpService$1 as H, sortBy_1 as a, dayjs_min as d, getSalonImage as g, isVideoMedia as i, shortDateYearFormat as s, timeFormatAmPm as t };