firebase-admin 4.1.2 → 4.2.1

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.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,14 +7,12 @@ var api_request_1 = require("../utils/api-request");
7
7
  var error_2 = require("../utils/error");
8
8
  var validator = require("../utils/validator");
9
9
  // FCM backend constants
10
- var FIREBASE_MESSAGING_HOST = 'fcm.googleapis.com';
11
10
  var FIREBASE_MESSAGING_PORT = 443;
12
- var FIREBASE_MESSAGING_PATH = '/fcm/send';
13
11
  var FIREBASE_MESSAGING_TIMEOUT = 10000;
14
12
  var FIREBASE_MESSAGING_HTTP_METHOD = 'POST';
15
13
  var FIREBASE_MESSAGING_HEADERS = {
16
14
  'Content-Type': 'application/json',
17
- 'Sdk-Version': 'Node/Admin/4.1.2',
15
+ 'Sdk-Version': 'Node/Admin/4.2.1',
18
16
  access_token_auth: 'true',
19
17
  };
20
18
  /**
@@ -46,11 +44,13 @@ var FirebaseMessagingRequestHandler = (function () {
46
44
  /**
47
45
  * Invokes the request handler with the provided request data.
48
46
  *
47
+ * @param {string} host The host to which to send the request.
48
+ * @param {string} path The path to which to send the request.
49
49
  * @param {Object} requestData The request data.
50
50
  * @return {Promise<Object>} A promise that resolves with the response.
51
51
  */
52
- FirebaseMessagingRequestHandler.prototype.invokeRequestHandler = function (requestData) {
53
- return this.signedApiRequestHandler.sendRequest(FIREBASE_MESSAGING_HOST, FIREBASE_MESSAGING_PORT, FIREBASE_MESSAGING_PATH, FIREBASE_MESSAGING_HTTP_METHOD, requestData, FIREBASE_MESSAGING_HEADERS, FIREBASE_MESSAGING_TIMEOUT).then(function (response) {
52
+ FirebaseMessagingRequestHandler.prototype.invokeRequestHandler = function (host, path, requestData) {
53
+ return this.signedApiRequestHandler.sendRequest(host, FIREBASE_MESSAGING_PORT, path, FIREBASE_MESSAGING_HTTP_METHOD, requestData, FIREBASE_MESSAGING_HEADERS, FIREBASE_MESSAGING_TIMEOUT).then(function (response) {
54
54
  // Send non-JSON responses to the catch() below where they will be treated as errors.
55
55
  if (typeof response === 'string') {
56
56
  return Promise.reject({
@@ -71,7 +71,10 @@ var FirebaseMessagingRequestHandler = (function () {
71
71
  })
72
72
  .catch(function (response) {
73
73
  // Re-throw the error if it already has the proper format.
74
- if (response.error instanceof error_1.FirebaseError) {
74
+ if (response instanceof error_1.FirebaseError) {
75
+ throw response;
76
+ }
77
+ else if (response.error instanceof error_1.FirebaseError) {
75
78
  throw response.error;
76
79
  }
77
80
  // Add special handling for non-JSON responses.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,6 +7,12 @@ var messaging_api_request_1 = require("./messaging-api-request");
7
7
  var error_1 = require("../utils/error");
8
8
  var utils = require("../utils");
9
9
  var validator = require("../utils/validator");
10
+ // FCM endpoints
11
+ var FCM_SEND_HOST = 'fcm.googleapis.com';
12
+ var FCM_SEND_PATH = '/fcm/send';
13
+ var FCM_TOPIC_MANAGEMENT_HOST = 'iid.googleapis.com';
14
+ var FCM_TOPIC_MANAGEMENT_ADD_PATH = '/iid/v1:batchAdd';
15
+ var FCM_TOPIC_MANAGEMENT_REMOVE_PATH = '/iid/v1:batchRemove';
10
16
  // Key renames for the messaging notification payload object.
11
17
  var CAMELCASED_NOTIFICATION_PAYLOAD_KEYS_MAP = {
12
18
  bodyLocArgs: 'body_loc_args',
@@ -93,6 +99,38 @@ function mapRawResponseToDeviceGroupResponse(response) {
93
99
  response.failedRegistrationTokens = response.failedRegistrationTokens || [];
94
100
  return response;
95
101
  }
102
+ /**
103
+ * Maps a raw FCM server response to a MessagingTopicManagementResponse object.
104
+ *
105
+ * @param {Object} response The raw FCM server response to map.
106
+ *
107
+ * @return {MessagingTopicManagementResponse} The mapped MessagingTopicManagementResponse object.
108
+ */
109
+ function mapRawResponseToTopicManagementResponse(response) {
110
+ // Add the success and failure counts.
111
+ response.successCount = 0;
112
+ response.failureCount = 0;
113
+ var errors = [];
114
+ if ('results' in response) {
115
+ response.results.forEach(function (tokenManagementResult, index) {
116
+ // Map the FCM server's error strings to actual error objects.
117
+ if ('error' in tokenManagementResult) {
118
+ response.failureCount += 1;
119
+ var newError = error_1.FirebaseMessagingError.fromServerError(tokenManagementResult.error, /* message */ undefined, tokenManagementResult.error);
120
+ errors.push({
121
+ index: index,
122
+ error: newError,
123
+ });
124
+ }
125
+ else {
126
+ response.successCount += 1;
127
+ }
128
+ });
129
+ }
130
+ delete response.results;
131
+ response.errors = errors;
132
+ return response;
133
+ }
96
134
  /**
97
135
  * Internals of a Messaging instance.
98
136
  */
@@ -154,34 +192,15 @@ var Messaging = (function () {
154
192
  Messaging.prototype.sendToDevice = function (registrationTokenOrTokens, payload, options) {
155
193
  var _this = this;
156
194
  if (options === void 0) { options = {}; }
157
- if (registrationTokenOrTokens instanceof Array && registrationTokenOrTokens.length !== 0) {
158
- // Validate the array contains no more than 1,000 registration tokens.
159
- if (registrationTokenOrTokens.length > 1000) {
160
- return Promise.reject(new error_1.FirebaseMessagingError(error_1.MessagingClientErrorCode.INVALID_RECIPIENT, 'Too many registration tokens provided in a single request. Batch your requests to ' +
161
- 'contain no more than 1,000 registration tokens per request.'));
162
- }
163
- // Validate the array contains registration tokens which are non-empty strings.
164
- try {
165
- registrationTokenOrTokens.forEach(function (registrationToken, index) {
166
- if (!validator.isNonEmptyString(registrationToken)) {
167
- throw new error_1.FirebaseMessagingError(error_1.MessagingClientErrorCode.INVALID_RECIPIENT, "Registration token provided to sendToDevice() at index " + index + " must be a non-empty string.");
168
- }
169
- });
170
- }
171
- catch (error) {
172
- return Promise.reject(error);
173
- }
174
- }
175
- else if (!validator.isNonEmptyString(registrationTokenOrTokens)) {
176
- throw new error_1.FirebaseMessagingError(error_1.MessagingClientErrorCode.INVALID_RECIPIENT, 'Registration token provided to sendToDevice() must be a non-empty string or a non-empty array.');
177
- }
178
- // Validate the types of the payload and options arguments. Since these are common developer
179
- // errors, throw an error instead of returning a rejected promise.
195
+ // Validate the input argument types. Since these are common developer errors when getting
196
+ // started, throw an error instead of returning a rejected promise.
197
+ this.validateRegistrationTokensType(registrationTokenOrTokens, 'sendToDevice', error_1.MessagingClientErrorCode.INVALID_RECIPIENT);
180
198
  this.validateMessagingPayloadAndOptionsTypes(payload, options);
181
199
  return Promise.resolve()
182
200
  .then(function () {
183
- // Validate the contents of the payload and options objects. Because we are now in a
184
- // promise, any thrown error will cause this method to return a rejected promise.
201
+ // Validate the contents of the input arguments. Because we are now in a promise, any thrown
202
+ // error will cause this method to return a rejected promise.
203
+ _this.validateRegistrationTokens(registrationTokenOrTokens, 'sendToDevice', error_1.MessagingClientErrorCode.INVALID_RECIPIENT);
185
204
  var payloadCopy = _this.validateMessagingPayload(payload);
186
205
  var optionsCopy = _this.validateMessagingOptions(options);
187
206
  var request = deep_copy_1.deepCopy(payloadCopy);
@@ -192,7 +211,7 @@ var Messaging = (function () {
192
211
  else {
193
212
  request.registration_ids = registrationTokenOrTokens;
194
213
  }
195
- return _this.messagingRequestHandler.invokeRequestHandler(request);
214
+ return _this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request);
196
215
  })
197
216
  .then(function (response) {
198
217
  // The sendToDevice() and sendToDeviceGroup() methods both set the `to` query parameter in
@@ -246,7 +265,7 @@ var Messaging = (function () {
246
265
  var request = deep_copy_1.deepCopy(payloadCopy);
247
266
  deep_copy_1.deepExtend(request, optionsCopy);
248
267
  request.to = notificationKey;
249
- return _this.messagingRequestHandler.invokeRequestHandler(request);
268
+ return _this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request);
250
269
  })
251
270
  .then(function (response) {
252
271
  // The sendToDevice() and sendToDeviceGroup() methods both set the `to` query parameter in
@@ -281,29 +300,23 @@ var Messaging = (function () {
281
300
  Messaging.prototype.sendToTopic = function (topic, payload, options) {
282
301
  var _this = this;
283
302
  if (options === void 0) { options = {}; }
284
- if (!validator.isNonEmptyString(topic)) {
285
- throw new error_1.FirebaseMessagingError(error_1.MessagingClientErrorCode.INVALID_RECIPIENT, 'Topic provided to sendToTopic() must be a string which matches the format "/topics/[a-zA-Z0-9-_.~%]+".');
286
- }
287
- else if (!validator.isTopic(topic)) {
288
- return Promise.reject(new error_1.FirebaseMessagingError(error_1.MessagingClientErrorCode.INVALID_RECIPIENT, 'Topic provided to sendToTopic() must be a string which matches the format "/topics/[a-zA-Z0-9-_.~%]+".'));
289
- }
290
- // Prepend the topic with /topics/ if necessary
291
- if (!/^\/topics\//.test(topic)) {
292
- topic = "/topics/" + topic;
293
- }
294
- // Validate the types of the payload and options arguments. Since these are common developer
295
- // errors, throw an error instead of returning a rejected promise.
303
+ // Validate the input argument types. Since these are common developer errors when getting
304
+ // started, throw an error instead of returning a rejected promise.
305
+ this.validateTopicType(topic, 'sendToTopic', error_1.MessagingClientErrorCode.INVALID_RECIPIENT);
296
306
  this.validateMessagingPayloadAndOptionsTypes(payload, options);
307
+ // Prepend the topic with /topics/ if necessary.
308
+ topic = this.normalizeTopic(topic);
297
309
  return Promise.resolve()
298
310
  .then(function () {
299
311
  // Validate the contents of the payload and options objects. Because we are now in a
300
312
  // promise, any thrown error will cause this method to return a rejected promise.
301
313
  var payloadCopy = _this.validateMessagingPayload(payload);
302
314
  var optionsCopy = _this.validateMessagingOptions(options);
315
+ _this.validateTopic(topic, 'sendToTopic', error_1.MessagingClientErrorCode.INVALID_RECIPIENT);
303
316
  var request = deep_copy_1.deepCopy(payloadCopy);
304
317
  deep_copy_1.deepExtend(request, optionsCopy);
305
318
  request.to = topic;
306
- return _this.messagingRequestHandler.invokeRequestHandler(request);
319
+ return _this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request);
307
320
  })
308
321
  .then(function (response) {
309
322
  // Rename properties on the server response
@@ -344,7 +357,7 @@ var Messaging = (function () {
344
357
  var request = deep_copy_1.deepCopy(payloadCopy);
345
358
  deep_copy_1.deepExtend(request, optionsCopy);
346
359
  request.condition = condition;
347
- return _this.messagingRequestHandler.invokeRequestHandler(request);
360
+ return _this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request);
348
361
  })
349
362
  .then(function (response) {
350
363
  // Rename properties on the server response
@@ -352,6 +365,71 @@ var Messaging = (function () {
352
365
  return response;
353
366
  });
354
367
  };
368
+ /**
369
+ * Subscribes a single device or an array of devices to a topic.
370
+ *
371
+ * @param {string|string[]} registrationTokenOrTokens The registration token or an array of
372
+ * registration tokens to subscribe to the topic.
373
+ * @param {string} topic The topic to which to subscribe.
374
+ *
375
+ * @return {Promise<MessagingTopicManagementResponse>} A Promise fulfilled with the parsed FCM
376
+ * server response.
377
+ */
378
+ Messaging.prototype.subscribeToTopic = function (registrationTokenOrTokens, topic) {
379
+ return this.sendTopicManagementRequest(registrationTokenOrTokens, topic, 'subscribeToTopic', FCM_TOPIC_MANAGEMENT_ADD_PATH);
380
+ };
381
+ /**
382
+ * Unsubscribes a single device or an array of devices from a topic.
383
+ *
384
+ * @param {string|string[]} registrationTokenOrTokens The registration token or an array of
385
+ * registration tokens to unsubscribe from the topic.
386
+ * @param {string} topic The topic to which to subscribe.
387
+ *
388
+ * @return {Promise<MessagingTopicManagementResponse>} A Promise fulfilled with the parsed FCM
389
+ * server response.
390
+ */
391
+ Messaging.prototype.unsubscribeFromTopic = function (registrationTokenOrTokens, topic) {
392
+ return this.sendTopicManagementRequest(registrationTokenOrTokens, topic, 'unsubscribeFromTopic', FCM_TOPIC_MANAGEMENT_REMOVE_PATH);
393
+ };
394
+ /**
395
+ * Helper method which sends and handles topic subscription management requests.
396
+ *
397
+ * @param {string|string[]} registrationTokenOrTokens The registration token or an array of
398
+ * registration tokens to unsubscribe from the topic.
399
+ * @param {string} topic The topic to which to subscribe.
400
+ * @param {string} methodName The name of the original method called.
401
+ * @param {string} path The endpoint path to use for the request.
402
+ *
403
+ * @return {Promise<MessagingTopicManagementResponse>} A Promise fulfilled with the parsed server
404
+ * response.
405
+ */
406
+ Messaging.prototype.sendTopicManagementRequest = function (registrationTokenOrTokens, topic, methodName, path) {
407
+ var _this = this;
408
+ this.validateRegistrationTokensType(registrationTokenOrTokens, methodName);
409
+ this.validateTopicType(topic, methodName);
410
+ // Prepend the topic with /topics/ if necessary.
411
+ topic = this.normalizeTopic(topic);
412
+ return Promise.resolve()
413
+ .then(function () {
414
+ // Validate the contents of the input arguments. Because we are now in a promise, any thrown
415
+ // error will cause this method to return a rejected promise.
416
+ _this.validateRegistrationTokens(registrationTokenOrTokens, methodName);
417
+ _this.validateTopic(topic, methodName);
418
+ // Ensure the registration token(s) input argument is an array.
419
+ var registrationTokensArray = registrationTokenOrTokens;
420
+ if (validator.isString(registrationTokenOrTokens)) {
421
+ registrationTokensArray = [registrationTokenOrTokens];
422
+ }
423
+ var request = {
424
+ to: topic,
425
+ registration_tokens: registrationTokensArray,
426
+ };
427
+ return _this.messagingRequestHandler.invokeRequestHandler(FCM_TOPIC_MANAGEMENT_HOST, path, request);
428
+ })
429
+ .then(function (response) {
430
+ return mapRawResponseToTopicManagementResponse(response);
431
+ });
432
+ };
355
433
  /**
356
434
  * Validates the types of the messaging payload and options. If invalid, an error will be thrown.
357
435
  *
@@ -484,6 +562,87 @@ var Messaging = (function () {
484
562
  }
485
563
  return optionsCopy;
486
564
  };
565
+ /**
566
+ * Validates the type of the provided registration token(s). If invalid, an error will be thrown.
567
+ *
568
+ * @param {string|string[]} registrationTokenOrTokens The registration token(s) to validate.
569
+ * @param {string} method The method name to use in error messages.
570
+ * @param {ErrorInfo?} [errorInfo] The error info to use if the registration tokens are invalid.
571
+ */
572
+ Messaging.prototype.validateRegistrationTokensType = function (registrationTokenOrTokens, methodName, errorInfo) {
573
+ if (errorInfo === void 0) { errorInfo = error_1.MessagingClientErrorCode.INVALID_ARGUMENT; }
574
+ if (!validator.isNonEmptyArray(registrationTokenOrTokens) &&
575
+ !validator.isNonEmptyString(registrationTokenOrTokens)) {
576
+ throw new error_1.FirebaseMessagingError(errorInfo, "Registration token(s) provided to " + methodName + "() must be a non-empty string or a " +
577
+ 'non-empty array.');
578
+ }
579
+ };
580
+ /**
581
+ * Validates the provided registration tokens. If invalid, an error will be thrown.
582
+ *
583
+ * @param {string|string[]} registrationTokenOrTokens The registration token or an array of
584
+ * registration tokens to validate.
585
+ * @param {string} method The method name to use in error messages.
586
+ * @param {errorInfo?} [ErrorInfo] The error info to use if the registration tokens are invalid.
587
+ */
588
+ Messaging.prototype.validateRegistrationTokens = function (registrationTokenOrTokens, methodName, errorInfo) {
589
+ if (errorInfo === void 0) { errorInfo = error_1.MessagingClientErrorCode.INVALID_ARGUMENT; }
590
+ if (validator.isArray(registrationTokenOrTokens)) {
591
+ // Validate the array contains no more than 1,000 registration tokens.
592
+ if (registrationTokenOrTokens.length > 1000) {
593
+ throw new error_1.FirebaseMessagingError(errorInfo, "Too many registration tokens provided in a single request to " + methodName + "(). Batch " +
594
+ 'your requests to contain no more than 1,000 registration tokens per request.');
595
+ }
596
+ // Validate the array contains registration tokens which are non-empty strings.
597
+ registrationTokenOrTokens.forEach(function (registrationToken, index) {
598
+ if (!validator.isNonEmptyString(registrationToken)) {
599
+ throw new error_1.FirebaseMessagingError(errorInfo, "Registration token provided to " + methodName + "() at index " + index + " must be a " +
600
+ 'non-empty string.');
601
+ }
602
+ });
603
+ }
604
+ };
605
+ /**
606
+ * Validates the type of the provided topic. If invalid, an error will be thrown.
607
+ *
608
+ * @param {string} topic The topic to validate.
609
+ * @param {string} method The method name to use in error messages.
610
+ * @param {ErrorInfo?} [errorInfo] The error info to use if the topic is invalid.
611
+ */
612
+ Messaging.prototype.validateTopicType = function (topic, methodName, errorInfo) {
613
+ if (errorInfo === void 0) { errorInfo = error_1.MessagingClientErrorCode.INVALID_ARGUMENT; }
614
+ if (!validator.isNonEmptyString(topic)) {
615
+ throw new error_1.FirebaseMessagingError(errorInfo, "Topic provided to " + methodName + "() must be a string which matches the format " +
616
+ '"/topics/[a-zA-Z0-9-_.~%]+".');
617
+ }
618
+ };
619
+ /**
620
+ * Validates the provided topic. If invalid, an error will be thrown.
621
+ *
622
+ * @param {string} topic The topic to validate.
623
+ * @param {string} method The method name to use in error messages.
624
+ * @param {ErrorInfo?} [errorInfo] The error info to use if the topic is invalid.
625
+ */
626
+ Messaging.prototype.validateTopic = function (topic, methodName, errorInfo) {
627
+ if (errorInfo === void 0) { errorInfo = error_1.MessagingClientErrorCode.INVALID_ARGUMENT; }
628
+ if (!validator.isTopic(topic)) {
629
+ throw new error_1.FirebaseMessagingError(errorInfo, "Topic provided to " + methodName + "() must be a string which matches the format " +
630
+ '"/topics/[a-zA-Z0-9-_.~%]+".');
631
+ }
632
+ };
633
+ /**
634
+ * Normalizes the provided topic name by prepending it with '/topics/', if necessary.
635
+ *
636
+ * @param {string} topic The topic name to normalize.
637
+ *
638
+ * @return {string} The normalized topic name.
639
+ */
640
+ Messaging.prototype.normalizeTopic = function (topic) {
641
+ if (!/^\/topics\//.test(topic)) {
642
+ topic = "/topics/" + topic;
643
+ }
644
+ return topic;
645
+ };
487
646
  return Messaging;
488
647
  }());
489
648
  exports.Messaging = Messaging;
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  var __extends = (this && this.__extends) || (function () {
@@ -87,11 +87,8 @@ var HttpRequestHandler = (function () {
87
87
  }
88
88
  }
89
89
  catch (error) {
90
- var parsingError = new error_1.FirebaseError({
91
- code: 'unable-to-parse-response',
92
- message: "Failed to parse response data: \"" + error.toString() + "\". Raw server " +
93
- ("response: \"" + response + ".\""),
94
- });
90
+ var parsingError = new error_1.FirebaseAppError(error_1.AppErrorCodes.UNABLE_TO_PARSE_RESPONSE, "Failed to parse response data: \"" + error.toString() + "\". Raw server" +
91
+ ("response: \"" + response + ".\""));
95
92
  reject({
96
93
  statusCode: statusCode,
97
94
  error: parsingError,
@@ -106,10 +103,7 @@ var HttpRequestHandler = (function () {
106
103
  socket.setTimeout(timeout);
107
104
  socket.on('timeout', function () {
108
105
  req.abort();
109
- var networkTimeoutError = new error_1.FirebaseError({
110
- code: 'network-timeout',
111
- message: host + " network timeout. Please try again.",
112
- });
106
+ var networkTimeoutError = new error_1.FirebaseAppError(error_1.AppErrorCodes.NETWORK_TIMEOUT, host + " network timeout. Please try again.");
113
107
  reject({
114
108
  statusCode: 408,
115
109
  error: networkTimeoutError,
@@ -118,10 +112,7 @@ var HttpRequestHandler = (function () {
118
112
  });
119
113
  }
120
114
  req.on('error', function (error) {
121
- var networkRequestError = new error_1.FirebaseError({
122
- code: 'network-error',
123
- message: "A network request error has occurred: " + (error && error.message),
124
- });
115
+ var networkRequestError = new error_1.FirebaseAppError(error_1.AppErrorCodes.NETWORK_ERROR, "A network request error has occurred: " + (error && error.message));
125
116
  reject({
126
117
  statusCode: 502,
127
118
  error: networkRequestError,
@@ -166,11 +157,6 @@ var SignedApiRequestHandler = (function (_super) {
166
157
  SignedApiRequestHandler.prototype.sendRequest = function (host, port, path, httpMethod, data, headers, timeout) {
167
158
  var ancestorSendRequest = _super.prototype.sendRequest;
168
159
  return this.app_.INTERNAL.getToken().then(function (accessTokenObj) {
169
- if (accessTokenObj == null) {
170
- return Promise.reject('Unable to fetch Google OAuth2 access token. ' +
171
- 'Make sure you initialized the SDK with a credential that can f' +
172
- 'etch access tokens.');
173
- }
174
160
  var headersCopy = deep_copy_1.deepCopy(headers);
175
161
  var authorizationHeaderKey = 'Authorization';
176
162
  headersCopy[authorizationHeaderKey] = 'Bearer ' + accessTokenObj.accessToken;
@@ -192,9 +178,6 @@ var ApiSettings = (function () {
192
178
  if (httpMethod === void 0) { httpMethod = 'POST'; }
193
179
  this.endpoint = endpoint;
194
180
  this.httpMethod = httpMethod;
195
- if (!endpoint) {
196
- throw new Error("INTERNAL ASSERT FAILED: Unspecified API settings endpoint: " + endpoint);
197
- }
198
181
  this.setRequestValidator(null)
199
182
  .setResponseValidator(null);
200
183
  }
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  var __extends = (this && this.__extends) || (function () {
@@ -57,6 +57,24 @@ var FirebaseError = (function (_super) {
57
57
  return FirebaseError;
58
58
  }(Error));
59
59
  exports.FirebaseError = FirebaseError;
60
+ /**
61
+ * Firebase App error code structure. This extends FirebaseError.
62
+ *
63
+ * @param {string} code The error code.
64
+ * @param {string} message The error message.
65
+ * @constructor
66
+ */
67
+ var FirebaseAppError = (function (_super) {
68
+ __extends(FirebaseAppError, _super);
69
+ function FirebaseAppError(code, message) {
70
+ return _super.call(this, {
71
+ code: 'app/' + code,
72
+ message: message,
73
+ }) || this;
74
+ }
75
+ return FirebaseAppError;
76
+ }(FirebaseError));
77
+ exports.FirebaseAppError = FirebaseAppError;
60
78
  /**
61
79
  * Firebase Auth error code structure. This extends FirebaseError.
62
80
  *
@@ -138,6 +156,26 @@ var FirebaseMessagingError = (function (_super) {
138
156
  return FirebaseMessagingError;
139
157
  }(FirebaseError));
140
158
  exports.FirebaseMessagingError = FirebaseMessagingError;
159
+ /**
160
+ * App client error codes and their default messages.
161
+ */
162
+ var AppErrorCodes = (function () {
163
+ function AppErrorCodes() {
164
+ }
165
+ return AppErrorCodes;
166
+ }());
167
+ AppErrorCodes.APP_DELETED = 'app-deleted';
168
+ AppErrorCodes.DUPLICATE_APP = 'duplicate-app';
169
+ AppErrorCodes.INTERNAL_ERROR = 'internal-error';
170
+ AppErrorCodes.INVALID_APP_NAME = 'invalid-app-name';
171
+ AppErrorCodes.INVALID_APP_OPTIONS = 'invalid-app-options';
172
+ AppErrorCodes.INVALID_CREDENTIAL = 'invalid-credential';
173
+ AppErrorCodes.NETWORK_ERROR = 'network-error';
174
+ AppErrorCodes.NETWORK_TIMEOUT = 'network-timeout';
175
+ AppErrorCodes.NO_APP = 'no-app';
176
+ AppErrorCodes.UNABLE_TO_PARSE_RESPONSE = 'unable-to-parse-response';
177
+ exports.AppErrorCodes = AppErrorCodes;
178
+ ;
141
179
  /**
142
180
  * Auth client error codes and their default messages.
143
181
  */
@@ -293,6 +331,11 @@ MessagingClientErrorCode.INVALID_APNS_CREDENTIALS = {
293
331
  'SSL certificate was not uploaded or has expired. Check the validity of your development ' +
294
332
  'and production certificates.',
295
333
  };
334
+ MessagingClientErrorCode.TOO_MANY_TOPICS = {
335
+ code: 'too-many-topics',
336
+ message: 'The maximum number of topics the provided registration token can be subscribed to ' +
337
+ 'has been exceeded.',
338
+ };
296
339
  MessagingClientErrorCode.AUTHENTICATION_ERROR = {
297
340
  code: 'authentication-error',
298
341
  message: 'An error occurred when trying to authenticate to the FCM servers. Make sure the ' +
@@ -306,7 +349,7 @@ MessagingClientErrorCode.SERVER_UNAVAILABLE = {
306
349
  };
307
350
  MessagingClientErrorCode.INTERNAL_ERROR = {
308
351
  code: 'internal-error',
309
- message: 'An internal error has occurred.',
352
+ message: 'An internal error has occurred. Please retry the request.',
310
353
  };
311
354
  MessagingClientErrorCode.UNKNOWN_ERROR = {
312
355
  code: 'unknown-error',
@@ -345,14 +388,20 @@ var AUTH_SERVER_TO_CLIENT_CODE = {
345
388
  };
346
389
  /** @const {ServerToClientCode} Messaging server to client enum error codes. */
347
390
  var MESSAGING_SERVER_TO_CLIENT_CODE = {
391
+ /* GENERIC ERRORS */
348
392
  // Generic invalid message parameter provided.
349
393
  InvalidParameters: 'INVALID_ARGUMENT',
394
+ // Mismatched sender ID.
395
+ MismatchSenderId: 'MISMATCHED_CREDENTIAL',
396
+ // FCM server unavailable.
397
+ Unavailable: 'SERVER_UNAVAILABLE',
398
+ // FCM server internal error.
399
+ InternalServerError: 'INTERNAL_ERROR',
400
+ /* SEND ERRORS */
350
401
  // Invalid registration token format.
351
402
  InvalidRegistration: 'INVALID_REGISTRATION_TOKEN',
352
403
  // Registration token is not registered.
353
404
  NotRegistered: 'REGISTRATION_TOKEN_NOT_REGISTERED',
354
- // Mismatched sender ID.
355
- MismatchSenderId: 'MISMATCHED_CREDENTIAL',
356
405
  // Registration token does not match restricted package name.
357
406
  InvalidPackageName: 'INVALID_PACKAGE_NAME',
358
407
  // Message payload size limit exceeded.
@@ -367,8 +416,13 @@ var MESSAGING_SERVER_TO_CLIENT_CODE = {
367
416
  TopicsMessageRateExceeded: 'TOPICS_MESSAGE_RATE_EXCEEDED',
368
417
  // Invalid APNs credentials.
369
418
  InvalidApnsCredential: 'INVALID_APNS_CREDENTIALS',
370
- // FCM server unavailable.
371
- Unavailable: 'SERVER_UNAVAILABLE',
372
- // FCM server internal error.
373
- InternalServerError: 'INTERNAL_ERROR',
419
+ /* TOPIC SUBSCRIPTION MANAGEMENT ERRORS */
420
+ NOT_FOUND: 'REGISTRATION_TOKEN_NOT_REGISTERED',
421
+ INVALID_ARGUMENT: 'INVALID_REGISTRATION_TOKEN',
422
+ TOO_MANY_TOPICS: 'TOO_MANY_TOPICS',
423
+ RESOURCE_EXHAUSTED: 'TOO_MANY_TOPICS',
424
+ PERMISSION_DENIED: 'AUTHENTICATION_ERROR',
425
+ DEADLINE_EXCEEDED: 'SERVER_UNAVAILABLE',
426
+ INTERNAL: 'INTERNAL_ERROR',
427
+ UNKNOWN: 'UNKNOWN_ERROR',
374
428
  };
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  *
8
8
  * For example, this can be used to map underscore_cased properties to camelCase.
9
9
  *
10
- * @param {obj} Object The object whose properties to rename.
11
- * @param {keyMap} Object The mapping from old to new property names.
10
+ * @param {Object} obj The object whose properties to rename.
11
+ * @param {Object} keyMap The mapping from old to new property names.
12
12
  */
13
13
  function renameProperties(obj, keyMap) {
14
14
  Object.keys(keyMap).forEach(function (oldKey) {
@@ -21,3 +21,22 @@ function renameProperties(obj, keyMap) {
21
21
  });
22
22
  }
23
23
  exports.renameProperties = renameProperties;
24
+ /**
25
+ * Defines a new read-only property directly on an object and returns the object.
26
+ *
27
+ * @param {Object} obj The object on which to define the property.
28
+ * @param {string} prop The name of the property to be defined or modified.
29
+ * @param {any} value The value associated with the property.
30
+ *
31
+ * @return {Object} The object that was passed to the function.
32
+ */
33
+ function addReadonlyGetter(obj, prop, value) {
34
+ Object.defineProperty(obj, prop, {
35
+ value: value,
36
+ // Make this property read-only.
37
+ writable: false,
38
+ // Include this property during enumeration of obj's properties.
39
+ enumerable: true,
40
+ });
41
+ }
42
+ exports.addReadonlyGetter = addReadonlyGetter;
@@ -1,8 +1,28 @@
1
- /*! firebase-admin v4.1.2
1
+ /*! firebase-admin v4.2.1
2
2
  https://firebase.google.com/terms/ */
3
3
  "use strict";
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  var url = require("url");
6
+ /**
7
+ * Validates that a value is an array.
8
+ *
9
+ * @param {any} value The value to validate.
10
+ * @return {boolean} Whether the value is an array or not.
11
+ */
12
+ function isArray(value) {
13
+ return value instanceof Array;
14
+ }
15
+ exports.isArray = isArray;
16
+ /**
17
+ * Validates that a value is a non-empty array.
18
+ *
19
+ * @param {any} value The value to validate.
20
+ * @return {boolean} Whether the value is a non-empty array or not.
21
+ */
22
+ function isNonEmptyArray(value) {
23
+ return isArray(value) && value.length !== 0;
24
+ }
25
+ exports.isNonEmptyArray = isNonEmptyArray;
6
26
  /**
7
27
  * Validates that a value is a boolean.
8
28
  *
@@ -40,7 +60,7 @@ exports.isString = isString;
40
60
  * @return {boolean} Whether the value is a non-empty string or not.
41
61
  */
42
62
  function isNonEmptyString(value) {
43
- return typeof value === 'string' && value !== '';
63
+ return isString(value) && value !== '';
44
64
  }
45
65
  exports.isNonEmptyString = isNonEmptyString;
46
66
  /**