firebase-admin 9.12.0
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.
- package/LICENSE +201 -0
- package/README.md +90 -0
- package/lib/app-check/app-check-api-client-internal.js +197 -0
- package/lib/app-check/app-check.js +79 -0
- package/lib/app-check/index.d.ts +160 -0
- package/lib/app-check/index.js +19 -0
- package/lib/app-check/token-generator.js +161 -0
- package/lib/app-check/token-verifier.js +152 -0
- package/lib/auth/action-code-settings-builder.js +118 -0
- package/lib/auth/auth-api-request.js +1856 -0
- package/lib/auth/auth-config.js +636 -0
- package/lib/auth/auth.js +836 -0
- package/lib/auth/identifier.js +40 -0
- package/lib/auth/index.d.ts +1927 -0
- package/lib/auth/index.js +18 -0
- package/lib/auth/tenant-manager.js +140 -0
- package/lib/auth/tenant.js +171 -0
- package/lib/auth/token-generator.js +200 -0
- package/lib/auth/token-verifier.js +259 -0
- package/lib/auth/user-import-builder.js +387 -0
- package/lib/auth/user-record.js +346 -0
- package/lib/credential/credential-internal.js +391 -0
- package/lib/credential/credential.js +44 -0
- package/lib/credential/index.d.ts +169 -0
- package/lib/credential/index.js +23 -0
- package/lib/database/database-internal.js +266 -0
- package/lib/database/index.d.ts +89 -0
- package/lib/database/index.js +31 -0
- package/lib/default-namespace.js +31 -0
- package/lib/firebase-app.js +349 -0
- package/lib/firebase-namespace-api.d.ts +243 -0
- package/lib/firebase-namespace-api.js +18 -0
- package/lib/firebase-namespace.d.ts +31 -0
- package/lib/firebase-namespace.js +417 -0
- package/lib/firestore/firestore-internal.js +105 -0
- package/lib/firestore/index.d.ts +50 -0
- package/lib/firestore/index.js +47 -0
- package/lib/index.d.ts +24 -0
- package/lib/index.js +27 -0
- package/lib/installations/index.d.ts +81 -0
- package/lib/installations/index.js +18 -0
- package/lib/installations/installations-request-handler.js +117 -0
- package/lib/installations/installations.js +62 -0
- package/lib/instance-id/index.d.ts +83 -0
- package/lib/instance-id/index.js +18 -0
- package/lib/instance-id/instance-id.js +87 -0
- package/lib/machine-learning/index.d.ts +249 -0
- package/lib/machine-learning/index.js +18 -0
- package/lib/machine-learning/machine-learning-api-client.js +304 -0
- package/lib/machine-learning/machine-learning-utils.js +62 -0
- package/lib/machine-learning/machine-learning.js +364 -0
- package/lib/messaging/batch-request-internal.js +129 -0
- package/lib/messaging/index.d.ts +1174 -0
- package/lib/messaging/index.js +18 -0
- package/lib/messaging/messaging-api-request-internal.js +128 -0
- package/lib/messaging/messaging-errors-internal.js +106 -0
- package/lib/messaging/messaging-internal.js +484 -0
- package/lib/messaging/messaging.js +846 -0
- package/lib/project-management/android-app.js +176 -0
- package/lib/project-management/index.d.ts +363 -0
- package/lib/project-management/index.js +41 -0
- package/lib/project-management/ios-app.js +88 -0
- package/lib/project-management/project-management-api-request-internal.js +273 -0
- package/lib/project-management/project-management.js +254 -0
- package/lib/remote-config/index.d.ts +369 -0
- package/lib/remote-config/index.js +18 -0
- package/lib/remote-config/remote-config-api-client-internal.js +407 -0
- package/lib/remote-config/remote-config.js +304 -0
- package/lib/security-rules/index.d.ts +216 -0
- package/lib/security-rules/index.js +18 -0
- package/lib/security-rules/security-rules-api-client-internal.js +237 -0
- package/lib/security-rules/security-rules-internal.js +41 -0
- package/lib/security-rules/security-rules.js +310 -0
- package/lib/storage/index.d.ts +60 -0
- package/lib/storage/index.js +18 -0
- package/lib/storage/storage.js +123 -0
- package/lib/utils/api-request.js +845 -0
- package/lib/utils/crypto-signer.js +237 -0
- package/lib/utils/deep-copy.js +78 -0
- package/lib/utils/error.js +1063 -0
- package/lib/utils/index.js +217 -0
- package/lib/utils/jwt.js +355 -0
- package/lib/utils/validator.js +271 -0
- package/package.json +122 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/*! firebase-admin v9.12.0 */
|
|
2
|
+
"use strict";
|
|
3
|
+
/*!
|
|
4
|
+
* Copyright 2020 Google Inc.
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.Model = exports.MachineLearning = void 0;
|
|
20
|
+
var machine_learning_api_client_1 = require("./machine-learning-api-client");
|
|
21
|
+
var error_1 = require("../utils/error");
|
|
22
|
+
var validator = require("../utils/validator");
|
|
23
|
+
var machine_learning_utils_1 = require("./machine-learning-utils");
|
|
24
|
+
var deep_copy_1 = require("../utils/deep-copy");
|
|
25
|
+
var utils = require("../utils");
|
|
26
|
+
/**
|
|
27
|
+
* The Firebase Machine Learning class
|
|
28
|
+
*/
|
|
29
|
+
var MachineLearning = /** @class */ (function () {
|
|
30
|
+
/**
|
|
31
|
+
* @param {FirebaseApp} app The app for this ML service.
|
|
32
|
+
* @constructor
|
|
33
|
+
*/
|
|
34
|
+
function MachineLearning(app) {
|
|
35
|
+
if (!validator.isNonNullObject(app) || !('options' in app)) {
|
|
36
|
+
throw new error_1.FirebaseError({
|
|
37
|
+
code: 'machine-learning/invalid-argument',
|
|
38
|
+
message: 'First argument passed to admin.machineLearning() must be a ' +
|
|
39
|
+
'valid Firebase app instance.',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
this.appInternal = app;
|
|
43
|
+
this.client = new machine_learning_api_client_1.MachineLearningApiClient(app);
|
|
44
|
+
}
|
|
45
|
+
Object.defineProperty(MachineLearning.prototype, "app", {
|
|
46
|
+
/**
|
|
47
|
+
* Returns the app associated with this ML instance.
|
|
48
|
+
*
|
|
49
|
+
* @return {FirebaseApp} The app associated with this ML instance.
|
|
50
|
+
*/
|
|
51
|
+
get: function () {
|
|
52
|
+
return this.appInternal;
|
|
53
|
+
},
|
|
54
|
+
enumerable: false,
|
|
55
|
+
configurable: true
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Creates a model in Firebase ML.
|
|
59
|
+
*
|
|
60
|
+
* @param {ModelOptions} model The model to create.
|
|
61
|
+
*
|
|
62
|
+
* @return {Promise<Model>} A Promise fulfilled with the created model.
|
|
63
|
+
*/
|
|
64
|
+
MachineLearning.prototype.createModel = function (model) {
|
|
65
|
+
var _this = this;
|
|
66
|
+
return this.signUrlIfPresent(model)
|
|
67
|
+
.then(function (modelContent) { return _this.client.createModel(modelContent); })
|
|
68
|
+
.then(function (operation) { return _this.client.handleOperation(operation); })
|
|
69
|
+
.then(function (modelResponse) { return new Model(modelResponse, _this.client); });
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Updates a model in Firebase ML.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} modelId The id of the model to update.
|
|
75
|
+
* @param {ModelOptions} model The model fields to update.
|
|
76
|
+
*
|
|
77
|
+
* @return {Promise<Model>} A Promise fulfilled with the updated model.
|
|
78
|
+
*/
|
|
79
|
+
MachineLearning.prototype.updateModel = function (modelId, model) {
|
|
80
|
+
var _this = this;
|
|
81
|
+
var updateMask = utils.generateUpdateMask(model);
|
|
82
|
+
return this.signUrlIfPresent(model)
|
|
83
|
+
.then(function (modelContent) { return _this.client.updateModel(modelId, modelContent, updateMask); })
|
|
84
|
+
.then(function (operation) { return _this.client.handleOperation(operation); })
|
|
85
|
+
.then(function (modelResponse) { return new Model(modelResponse, _this.client); });
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Publishes a model in Firebase ML.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} modelId The id of the model to publish.
|
|
91
|
+
*
|
|
92
|
+
* @return {Promise<Model>} A Promise fulfilled with the published model.
|
|
93
|
+
*/
|
|
94
|
+
MachineLearning.prototype.publishModel = function (modelId) {
|
|
95
|
+
return this.setPublishStatus(modelId, true);
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Unpublishes a model in Firebase ML.
|
|
99
|
+
*
|
|
100
|
+
* @param {string} modelId The id of the model to unpublish.
|
|
101
|
+
*
|
|
102
|
+
* @return {Promise<Model>} A Promise fulfilled with the unpublished model.
|
|
103
|
+
*/
|
|
104
|
+
MachineLearning.prototype.unpublishModel = function (modelId) {
|
|
105
|
+
return this.setPublishStatus(modelId, false);
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Gets a model from Firebase ML.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} modelId The id of the model to get.
|
|
111
|
+
*
|
|
112
|
+
* @return {Promise<Model>} A Promise fulfilled with the unpublished model.
|
|
113
|
+
*/
|
|
114
|
+
MachineLearning.prototype.getModel = function (modelId) {
|
|
115
|
+
var _this = this;
|
|
116
|
+
return this.client.getModel(modelId)
|
|
117
|
+
.then(function (modelResponse) { return new Model(modelResponse, _this.client); });
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Lists models from Firebase ML.
|
|
121
|
+
*
|
|
122
|
+
* @param {ListModelsOptions} options The listing options.
|
|
123
|
+
*
|
|
124
|
+
* @return {Promise<{models: Model[], pageToken?: string}>} A promise that
|
|
125
|
+
* resolves with the current (filtered) list of models and the next page
|
|
126
|
+
* token. For the last page, an empty list of models and no page token are
|
|
127
|
+
* returned.
|
|
128
|
+
*/
|
|
129
|
+
MachineLearning.prototype.listModels = function (options) {
|
|
130
|
+
var _this = this;
|
|
131
|
+
if (options === void 0) { options = {}; }
|
|
132
|
+
return this.client.listModels(options)
|
|
133
|
+
.then(function (resp) {
|
|
134
|
+
if (!validator.isNonNullObject(resp)) {
|
|
135
|
+
throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-argument', "Invalid ListModels response: " + JSON.stringify(resp));
|
|
136
|
+
}
|
|
137
|
+
var models = [];
|
|
138
|
+
if (resp.models) {
|
|
139
|
+
models = resp.models.map(function (rs) { return new Model(rs, _this.client); });
|
|
140
|
+
}
|
|
141
|
+
var result = { models: models };
|
|
142
|
+
if (resp.nextPageToken) {
|
|
143
|
+
result.pageToken = resp.nextPageToken;
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Deletes a model from Firebase ML.
|
|
150
|
+
*
|
|
151
|
+
* @param {string} modelId The id of the model to delete.
|
|
152
|
+
*/
|
|
153
|
+
MachineLearning.prototype.deleteModel = function (modelId) {
|
|
154
|
+
return this.client.deleteModel(modelId);
|
|
155
|
+
};
|
|
156
|
+
MachineLearning.prototype.setPublishStatus = function (modelId, publish) {
|
|
157
|
+
var _this = this;
|
|
158
|
+
var updateMask = ['state.published'];
|
|
159
|
+
var options = { state: { published: publish } };
|
|
160
|
+
return this.client.updateModel(modelId, options, updateMask)
|
|
161
|
+
.then(function (operation) { return _this.client.handleOperation(operation); })
|
|
162
|
+
.then(function (modelResponse) { return new Model(modelResponse, _this.client); });
|
|
163
|
+
};
|
|
164
|
+
MachineLearning.prototype.signUrlIfPresent = function (options) {
|
|
165
|
+
var modelOptions = deep_copy_1.deepCopy(options);
|
|
166
|
+
if (machine_learning_api_client_1.isGcsTfliteModelOptions(modelOptions)) {
|
|
167
|
+
return this.signUrl(modelOptions.tfliteModel.gcsTfliteUri)
|
|
168
|
+
.then(function (uri) {
|
|
169
|
+
modelOptions.tfliteModel.gcsTfliteUri = uri;
|
|
170
|
+
return modelOptions;
|
|
171
|
+
})
|
|
172
|
+
.catch(function (err) {
|
|
173
|
+
throw new machine_learning_utils_1.FirebaseMachineLearningError('internal-error', "Error during signing upload url: " + err.message);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return Promise.resolve(modelOptions);
|
|
177
|
+
};
|
|
178
|
+
MachineLearning.prototype.signUrl = function (unsignedUrl) {
|
|
179
|
+
var MINUTES_IN_MILLIS = 60 * 1000;
|
|
180
|
+
var URL_VALID_DURATION = 10 * MINUTES_IN_MILLIS;
|
|
181
|
+
var gcsRegex = /^gs:\/\/([a-z0-9_.-]{3,63})\/(.+)$/;
|
|
182
|
+
var matches = gcsRegex.exec(unsignedUrl);
|
|
183
|
+
if (!matches) {
|
|
184
|
+
throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-argument', "Invalid unsigned url: " + unsignedUrl);
|
|
185
|
+
}
|
|
186
|
+
var bucketName = matches[1];
|
|
187
|
+
var blobName = matches[2];
|
|
188
|
+
var bucket = this.appInternal.storage().bucket(bucketName);
|
|
189
|
+
var blob = bucket.file(blobName);
|
|
190
|
+
return blob.getSignedUrl({
|
|
191
|
+
action: 'read',
|
|
192
|
+
expires: Date.now() + URL_VALID_DURATION,
|
|
193
|
+
}).then(function (signUrl) { return signUrl[0]; });
|
|
194
|
+
};
|
|
195
|
+
return MachineLearning;
|
|
196
|
+
}());
|
|
197
|
+
exports.MachineLearning = MachineLearning;
|
|
198
|
+
/**
|
|
199
|
+
* A Firebase ML Model output object.
|
|
200
|
+
*/
|
|
201
|
+
var Model = /** @class */ (function () {
|
|
202
|
+
function Model(model, client) {
|
|
203
|
+
this.model = Model.validateAndClone(model);
|
|
204
|
+
this.client = client;
|
|
205
|
+
}
|
|
206
|
+
Object.defineProperty(Model.prototype, "modelId", {
|
|
207
|
+
get: function () {
|
|
208
|
+
return extractModelId(this.model.name);
|
|
209
|
+
},
|
|
210
|
+
enumerable: false,
|
|
211
|
+
configurable: true
|
|
212
|
+
});
|
|
213
|
+
Object.defineProperty(Model.prototype, "displayName", {
|
|
214
|
+
get: function () {
|
|
215
|
+
return this.model.displayName;
|
|
216
|
+
},
|
|
217
|
+
enumerable: false,
|
|
218
|
+
configurable: true
|
|
219
|
+
});
|
|
220
|
+
Object.defineProperty(Model.prototype, "tags", {
|
|
221
|
+
get: function () {
|
|
222
|
+
return this.model.tags || [];
|
|
223
|
+
},
|
|
224
|
+
enumerable: false,
|
|
225
|
+
configurable: true
|
|
226
|
+
});
|
|
227
|
+
Object.defineProperty(Model.prototype, "createTime", {
|
|
228
|
+
get: function () {
|
|
229
|
+
return new Date(this.model.createTime).toUTCString();
|
|
230
|
+
},
|
|
231
|
+
enumerable: false,
|
|
232
|
+
configurable: true
|
|
233
|
+
});
|
|
234
|
+
Object.defineProperty(Model.prototype, "updateTime", {
|
|
235
|
+
get: function () {
|
|
236
|
+
return new Date(this.model.updateTime).toUTCString();
|
|
237
|
+
},
|
|
238
|
+
enumerable: false,
|
|
239
|
+
configurable: true
|
|
240
|
+
});
|
|
241
|
+
Object.defineProperty(Model.prototype, "validationError", {
|
|
242
|
+
get: function () {
|
|
243
|
+
var _a, _b;
|
|
244
|
+
return (_b = (_a = this.model.state) === null || _a === void 0 ? void 0 : _a.validationError) === null || _b === void 0 ? void 0 : _b.message;
|
|
245
|
+
},
|
|
246
|
+
enumerable: false,
|
|
247
|
+
configurable: true
|
|
248
|
+
});
|
|
249
|
+
Object.defineProperty(Model.prototype, "published", {
|
|
250
|
+
get: function () {
|
|
251
|
+
var _a;
|
|
252
|
+
return ((_a = this.model.state) === null || _a === void 0 ? void 0 : _a.published) || false;
|
|
253
|
+
},
|
|
254
|
+
enumerable: false,
|
|
255
|
+
configurable: true
|
|
256
|
+
});
|
|
257
|
+
Object.defineProperty(Model.prototype, "etag", {
|
|
258
|
+
get: function () {
|
|
259
|
+
return this.model.etag;
|
|
260
|
+
},
|
|
261
|
+
enumerable: false,
|
|
262
|
+
configurable: true
|
|
263
|
+
});
|
|
264
|
+
Object.defineProperty(Model.prototype, "modelHash", {
|
|
265
|
+
get: function () {
|
|
266
|
+
return this.model.modelHash;
|
|
267
|
+
},
|
|
268
|
+
enumerable: false,
|
|
269
|
+
configurable: true
|
|
270
|
+
});
|
|
271
|
+
Object.defineProperty(Model.prototype, "tfliteModel", {
|
|
272
|
+
get: function () {
|
|
273
|
+
// Make a copy so people can't directly modify the private this.model object.
|
|
274
|
+
return deep_copy_1.deepCopy(this.model.tfliteModel);
|
|
275
|
+
},
|
|
276
|
+
enumerable: false,
|
|
277
|
+
configurable: true
|
|
278
|
+
});
|
|
279
|
+
Object.defineProperty(Model.prototype, "locked", {
|
|
280
|
+
/**
|
|
281
|
+
* Locked indicates if there are active long running operations on the model.
|
|
282
|
+
* Models may not be modified when they are locked.
|
|
283
|
+
*/
|
|
284
|
+
get: function () {
|
|
285
|
+
var _a, _b;
|
|
286
|
+
return ((_b = (_a = this.model.activeOperations) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
287
|
+
},
|
|
288
|
+
enumerable: false,
|
|
289
|
+
configurable: true
|
|
290
|
+
});
|
|
291
|
+
Model.prototype.toJSON = function () {
|
|
292
|
+
// We can't just return this.model because it has extra fields and
|
|
293
|
+
// different formats etc. So we build the expected model object.
|
|
294
|
+
var jsonModel = {
|
|
295
|
+
modelId: this.modelId,
|
|
296
|
+
displayName: this.displayName,
|
|
297
|
+
tags: this.tags,
|
|
298
|
+
createTime: this.createTime,
|
|
299
|
+
updateTime: this.updateTime,
|
|
300
|
+
published: this.published,
|
|
301
|
+
etag: this.etag,
|
|
302
|
+
locked: this.locked,
|
|
303
|
+
};
|
|
304
|
+
// Also add possibly undefined fields if they exist.
|
|
305
|
+
if (this.validationError) {
|
|
306
|
+
jsonModel['validationError'] = this.validationError;
|
|
307
|
+
}
|
|
308
|
+
if (this.modelHash) {
|
|
309
|
+
jsonModel['modelHash'] = this.modelHash;
|
|
310
|
+
}
|
|
311
|
+
if (this.tfliteModel) {
|
|
312
|
+
jsonModel['tfliteModel'] = this.tfliteModel;
|
|
313
|
+
}
|
|
314
|
+
return jsonModel;
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* Wait for the active operations on the model to complete.
|
|
318
|
+
* @param maxTimeMillis The number of milliseconds to wait for the model to be unlocked. If unspecified,
|
|
319
|
+
* a default will be used.
|
|
320
|
+
*/
|
|
321
|
+
Model.prototype.waitForUnlocked = function (maxTimeMillis) {
|
|
322
|
+
var _this = this;
|
|
323
|
+
var _a, _b;
|
|
324
|
+
if (((_b = (_a = this.model.activeOperations) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
|
|
325
|
+
// The client will always be defined on Models that have activeOperations
|
|
326
|
+
// because models with active operations came back from the server and
|
|
327
|
+
// were constructed with a non-empty client.
|
|
328
|
+
return this.client.handleOperation(this.model.activeOperations[0], { wait: true, maxTimeMillis: maxTimeMillis })
|
|
329
|
+
.then(function (modelResponse) {
|
|
330
|
+
_this.model = Model.validateAndClone(modelResponse);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return Promise.resolve();
|
|
334
|
+
};
|
|
335
|
+
Model.validateAndClone = function (model) {
|
|
336
|
+
if (!validator.isNonNullObject(model) ||
|
|
337
|
+
!validator.isNonEmptyString(model.name) ||
|
|
338
|
+
!validator.isNonEmptyString(model.createTime) ||
|
|
339
|
+
!validator.isNonEmptyString(model.updateTime) ||
|
|
340
|
+
!validator.isNonEmptyString(model.displayName) ||
|
|
341
|
+
!validator.isNonEmptyString(model.etag)) {
|
|
342
|
+
throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-server-response', "Invalid Model response: " + JSON.stringify(model));
|
|
343
|
+
}
|
|
344
|
+
var tmpModel = deep_copy_1.deepCopy(model);
|
|
345
|
+
// If tflite Model is specified, it must have a source consisting of
|
|
346
|
+
// oneof {gcsTfliteUri, automlModel}
|
|
347
|
+
if (model.tfliteModel &&
|
|
348
|
+
!validator.isNonEmptyString(model.tfliteModel.gcsTfliteUri) &&
|
|
349
|
+
!validator.isNonEmptyString(model.tfliteModel.automlModel)) {
|
|
350
|
+
// If we have some other source, ignore the whole tfliteModel.
|
|
351
|
+
delete tmpModel.tfliteModel;
|
|
352
|
+
}
|
|
353
|
+
// Remove '@type' field. We don't need it.
|
|
354
|
+
if (tmpModel['@type']) {
|
|
355
|
+
delete tmpModel['@type'];
|
|
356
|
+
}
|
|
357
|
+
return tmpModel;
|
|
358
|
+
};
|
|
359
|
+
return Model;
|
|
360
|
+
}());
|
|
361
|
+
exports.Model = Model;
|
|
362
|
+
function extractModelId(resourceName) {
|
|
363
|
+
return resourceName.split('/').pop();
|
|
364
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/*! firebase-admin v9.12.0 */
|
|
2
|
+
"use strict";
|
|
3
|
+
/*!
|
|
4
|
+
* Copyright 2019 Google Inc.
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.BatchRequestClient = void 0;
|
|
20
|
+
var api_request_1 = require("../utils/api-request");
|
|
21
|
+
var error_1 = require("../utils/error");
|
|
22
|
+
var PART_BOUNDARY = '__END_OF_PART__';
|
|
23
|
+
var TEN_SECONDS_IN_MILLIS = 10000;
|
|
24
|
+
/**
|
|
25
|
+
* An HTTP client that can be used to make batch requests. This client is not tied to any service
|
|
26
|
+
* (FCM or otherwise). Therefore it can be used to make batch requests to any service that allows
|
|
27
|
+
* it. If this requirement ever arises we can move this implementation to the utils module
|
|
28
|
+
* where it can be easily shared among other modules.
|
|
29
|
+
*/
|
|
30
|
+
var BatchRequestClient = /** @class */ (function () {
|
|
31
|
+
/**
|
|
32
|
+
* @param {HttpClient} httpClient The client that will be used to make HTTP calls.
|
|
33
|
+
* @param {string} batchUrl The URL that accepts batch requests.
|
|
34
|
+
* @param {object=} commonHeaders Optional headers that will be included in all requests.
|
|
35
|
+
*
|
|
36
|
+
* @constructor
|
|
37
|
+
*/
|
|
38
|
+
function BatchRequestClient(httpClient, batchUrl, commonHeaders) {
|
|
39
|
+
this.httpClient = httpClient;
|
|
40
|
+
this.batchUrl = batchUrl;
|
|
41
|
+
this.commonHeaders = commonHeaders;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Sends the given array of sub requests as a single batch, and parses the results into an array
|
|
45
|
+
* of HttpResponse objects.
|
|
46
|
+
*
|
|
47
|
+
* @param {SubRequest[]} requests An array of sub requests to send.
|
|
48
|
+
* @return {Promise<HttpResponse[]>} A promise that resolves when the send operation is complete.
|
|
49
|
+
*/
|
|
50
|
+
BatchRequestClient.prototype.send = function (requests) {
|
|
51
|
+
var _this = this;
|
|
52
|
+
requests = requests.map(function (req) {
|
|
53
|
+
req.headers = Object.assign({}, _this.commonHeaders, req.headers);
|
|
54
|
+
return req;
|
|
55
|
+
});
|
|
56
|
+
var requestHeaders = {
|
|
57
|
+
'Content-Type': "multipart/mixed; boundary=" + PART_BOUNDARY,
|
|
58
|
+
};
|
|
59
|
+
var request = {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
url: this.batchUrl,
|
|
62
|
+
data: this.getMultipartPayload(requests),
|
|
63
|
+
headers: Object.assign({}, this.commonHeaders, requestHeaders),
|
|
64
|
+
timeout: TEN_SECONDS_IN_MILLIS,
|
|
65
|
+
};
|
|
66
|
+
return this.httpClient.send(request).then(function (response) {
|
|
67
|
+
if (!response.multipart) {
|
|
68
|
+
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INTERNAL_ERROR, 'Expected a multipart response.');
|
|
69
|
+
}
|
|
70
|
+
return response.multipart.map(function (buff) {
|
|
71
|
+
return api_request_1.parseHttpResponse(buff, request);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
BatchRequestClient.prototype.getMultipartPayload = function (requests) {
|
|
76
|
+
var buffer = '';
|
|
77
|
+
requests.forEach(function (request, idx) {
|
|
78
|
+
buffer += createPart(request, PART_BOUNDARY, idx);
|
|
79
|
+
});
|
|
80
|
+
buffer += "--" + PART_BOUNDARY + "--\r\n";
|
|
81
|
+
return Buffer.from(buffer, 'utf-8');
|
|
82
|
+
};
|
|
83
|
+
return BatchRequestClient;
|
|
84
|
+
}());
|
|
85
|
+
exports.BatchRequestClient = BatchRequestClient;
|
|
86
|
+
/**
|
|
87
|
+
* Creates a single part in a multipart HTTP request body. The part consists of several headers
|
|
88
|
+
* followed by the serialized sub request as the body. As per the requirements of the FCM batch
|
|
89
|
+
* API, sets the content-type header to application/http, and the content-transfer-encoding to
|
|
90
|
+
* binary.
|
|
91
|
+
*
|
|
92
|
+
* @param {SubRequest} request A sub request that will be used to populate the part.
|
|
93
|
+
* @param {string} boundary Multipart boundary string.
|
|
94
|
+
* @param {number} idx An index number that is used to set the content-id header.
|
|
95
|
+
* @return {string} The part as a string that can be included in the HTTP body.
|
|
96
|
+
*/
|
|
97
|
+
function createPart(request, boundary, idx) {
|
|
98
|
+
var serializedRequest = serializeSubRequest(request);
|
|
99
|
+
var part = "--" + boundary + "\r\n";
|
|
100
|
+
part += "Content-Length: " + serializedRequest.length + "\r\n";
|
|
101
|
+
part += 'Content-Type: application/http\r\n';
|
|
102
|
+
part += "content-id: " + (idx + 1) + "\r\n";
|
|
103
|
+
part += 'content-transfer-encoding: binary\r\n';
|
|
104
|
+
part += '\r\n';
|
|
105
|
+
part += serializedRequest + "\r\n";
|
|
106
|
+
return part;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Serializes a sub request into a string that can be embedded in a multipart HTTP request. The
|
|
110
|
+
* format of the string is the wire format of a typical HTTP request, consisting of a header and a
|
|
111
|
+
* body.
|
|
112
|
+
*
|
|
113
|
+
* @param request {SubRequest} The sub request to be serialized.
|
|
114
|
+
* @return {string} String representation of the SubRequest.
|
|
115
|
+
*/
|
|
116
|
+
function serializeSubRequest(request) {
|
|
117
|
+
var requestBody = JSON.stringify(request.body);
|
|
118
|
+
var messagePayload = "POST " + request.url + " HTTP/1.1\r\n";
|
|
119
|
+
messagePayload += "Content-Length: " + requestBody.length + "\r\n";
|
|
120
|
+
messagePayload += 'Content-Type: application/json; charset=UTF-8\r\n';
|
|
121
|
+
if (request.headers) {
|
|
122
|
+
Object.keys(request.headers).forEach(function (key) {
|
|
123
|
+
messagePayload += key + ": " + request.headers[key] + "\r\n";
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
messagePayload += '\r\n';
|
|
127
|
+
messagePayload += requestBody;
|
|
128
|
+
return messagePayload;
|
|
129
|
+
}
|