@dereekb/firebase-server 13.0.0 → 13.0.2

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/index.cjs.js CHANGED
@@ -5,8 +5,6 @@ var util = require('@dereekb/util');
5
5
  var https = require('firebase-functions/https');
6
6
  var date = require('@dereekb/date');
7
7
  var makeError = require('make-error');
8
- require('core-js/modules/es.iterator.constructor.js');
9
- require('core-js/modules/es.iterator.for-each.js');
10
8
  var rxjs = require('rxjs');
11
9
  var firestore = require('@google-cloud/firestore');
12
10
  var common = require('@nestjs/common');
@@ -14,152 +12,141 @@ var nestjs = require('@dereekb/nestjs');
14
12
  var v2 = require('firebase-functions/v2');
15
13
  var model = require('@dereekb/model');
16
14
  var admin = require('firebase-admin');
17
- require('core-js/modules/es.iterator.map.js');
18
15
  var storage = require('@google-cloud/storage');
19
16
  var dateFns = require('date-fns');
20
17
  var types = require('util/types');
21
- require('core-js/modules/es.map.get-or-insert.js');
22
- require('core-js/modules/es.map.get-or-insert-computed.js');
23
18
  var core = require('@nestjs/core');
24
19
  var platformExpress = require('@nestjs/platform-express');
25
20
  var express = require('express');
26
21
 
27
- /**
28
- * @deprecated use DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE instead
29
- */
30
- const NO_AUTH_ERROR_CODE = firebase.DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE;
31
22
  function unauthenticatedContextHasNoAuthData() {
32
- return unauthenticatedError({
33
- message: 'expected auth',
34
- code: NO_AUTH_ERROR_CODE
35
- });
23
+ return unauthenticatedError({
24
+ message: 'expected auth',
25
+ code: firebase.DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE
26
+ });
36
27
  }
37
- /**
38
- * @deprecated use DBX_FIREBASE_SERVER_NO_UID_ERROR_CODE instead
39
- */
40
- const NO_UID_ERROR_CODE = firebase.DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE;
41
28
  function unauthenticatedContextHasNoUidError() {
42
- return unauthenticatedError({
43
- message: 'no user uid',
44
- code: NO_UID_ERROR_CODE
45
- });
29
+ return unauthenticatedError({
30
+ message: 'no user uid',
31
+ code: firebase.DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE
32
+ });
46
33
  }
47
34
  // MARK: General Errors
48
35
  const UNAUTHENTICATED_ERROR_CODE = 'UNAUTHENTICATED';
49
36
  function unauthenticatedError(messageOrError) {
50
- const serverError = util.partialServerError(messageOrError);
51
- return new https.HttpsError('unauthenticated', serverError?.message || 'unauthenticated', {
52
- status: 401,
53
- code: UNAUTHENTICATED_ERROR_CODE,
54
- ...serverError,
55
- _error: undefined
56
- });
37
+ const serverError = util.partialServerError(messageOrError);
38
+ return new https.HttpsError('unauthenticated', serverError?.message || 'unauthenticated', {
39
+ status: 401,
40
+ code: UNAUTHENTICATED_ERROR_CODE,
41
+ ...serverError,
42
+ _error: undefined
43
+ });
57
44
  }
58
45
  const FORBIDDEN_ERROR_CODE = 'FORBIDDEN';
59
46
  function forbiddenError(messageOrError) {
60
- const serverError = util.partialServerError(messageOrError);
61
- return new https.HttpsError('permission-denied', serverError?.message || 'forbidden', {
62
- status: 403,
63
- code: FORBIDDEN_ERROR_CODE,
64
- ...serverError,
65
- _error: undefined
66
- });
47
+ const serverError = util.partialServerError(messageOrError);
48
+ return new https.HttpsError('permission-denied', serverError?.message || 'forbidden', {
49
+ status: 403,
50
+ code: FORBIDDEN_ERROR_CODE,
51
+ ...serverError,
52
+ _error: undefined
53
+ });
67
54
  }
68
55
  const PERMISSION_DENIED_ERROR_CODE = 'PERMISSION_DENIED';
69
56
  function permissionDeniedError(messageOrError) {
70
- const serverError = util.partialServerError(messageOrError);
71
- return new https.HttpsError('permission-denied', serverError?.message || 'permission denied', {
72
- status: 403,
73
- code: PERMISSION_DENIED_ERROR_CODE,
74
- ...serverError,
75
- _error: undefined
76
- });
57
+ const serverError = util.partialServerError(messageOrError);
58
+ return new https.HttpsError('permission-denied', serverError?.message || 'permission denied', {
59
+ status: 403,
60
+ code: PERMISSION_DENIED_ERROR_CODE,
61
+ ...serverError,
62
+ _error: undefined
63
+ });
77
64
  }
78
65
  const NOT_FOUND_ERROR_CODE = 'NOT_FOUND';
79
66
  function notFoundError(messageOrError) {
80
- const serverError = util.partialServerError(messageOrError);
81
- return new https.HttpsError('not-found', serverError?.message || 'not found', {
82
- status: 404,
83
- code: NOT_FOUND_ERROR_CODE,
84
- ...serverError,
85
- _error: undefined
86
- });
67
+ const serverError = util.partialServerError(messageOrError);
68
+ return new https.HttpsError('not-found', serverError?.message || 'not found', {
69
+ status: 404,
70
+ code: NOT_FOUND_ERROR_CODE,
71
+ ...serverError,
72
+ _error: undefined
73
+ });
87
74
  }
88
75
  const MODEL_NOT_AVAILABLE_ERROR_CODE = 'MODEL_NOT_AVAILABLE';
89
76
  function modelNotAvailableError(messageOrError) {
90
- const serverError = util.partialServerError(messageOrError);
91
- return new https.HttpsError('not-found', serverError?.message || 'model was not available', {
92
- status: 404,
93
- code: MODEL_NOT_AVAILABLE_ERROR_CODE,
94
- ...serverError,
95
- _error: undefined
96
- });
77
+ const serverError = util.partialServerError(messageOrError);
78
+ return new https.HttpsError('not-found', serverError?.message || 'model was not available', {
79
+ status: 404,
80
+ code: MODEL_NOT_AVAILABLE_ERROR_CODE,
81
+ ...serverError,
82
+ _error: undefined
83
+ });
97
84
  }
98
85
  const BAD_REQUEST_ERROR_CODE = 'BAD_REQUEST';
99
86
  function badRequestError(messageOrError) {
100
- const serverError = util.partialServerError(messageOrError);
101
- return new https.HttpsError('invalid-argument', serverError?.message || 'bad request', {
102
- status: 400,
103
- code: BAD_REQUEST_ERROR_CODE,
104
- ...serverError,
105
- _error: undefined
106
- });
87
+ const serverError = util.partialServerError(messageOrError);
88
+ return new https.HttpsError('invalid-argument', serverError?.message || 'bad request', {
89
+ status: 400,
90
+ code: BAD_REQUEST_ERROR_CODE,
91
+ ...serverError,
92
+ _error: undefined
93
+ });
107
94
  }
108
95
  const CONFLICT_ERROR_CODE = 'CONFLICT';
109
96
  function preconditionConflictError(messageOrError) {
110
- const serverError = util.partialServerError(messageOrError);
111
- return new https.HttpsError('failed-precondition', serverError?.message || 'conflict', {
112
- status: 409,
113
- code: CONFLICT_ERROR_CODE,
114
- ...serverError,
115
- _error: undefined
116
- });
97
+ const serverError = util.partialServerError(messageOrError);
98
+ return new https.HttpsError('failed-precondition', serverError?.message || 'conflict', {
99
+ status: 409,
100
+ code: CONFLICT_ERROR_CODE,
101
+ ...serverError,
102
+ _error: undefined
103
+ });
117
104
  }
118
105
  const ALREADY_EXISTS_ERROR_CODE = 'ALREADY_EXISTS';
119
106
  function alreadyExistsError(messageOrError) {
120
- const serverError = util.partialServerError(messageOrError);
121
- return new https.HttpsError('already-exists', serverError?.message || 'already exists', {
122
- status: 409,
123
- code: ALREADY_EXISTS_ERROR_CODE,
124
- ...serverError,
125
- _error: undefined
126
- });
107
+ const serverError = util.partialServerError(messageOrError);
108
+ return new https.HttpsError('already-exists', serverError?.message || 'already exists', {
109
+ status: 409,
110
+ code: ALREADY_EXISTS_ERROR_CODE,
111
+ ...serverError,
112
+ _error: undefined
113
+ });
127
114
  }
128
115
  const UNAVAILABLE_ERROR_CODE = 'UNAVAILABLE';
129
116
  function unavailableError(messageOrError) {
130
- const serverError = util.partialServerError(messageOrError);
131
- return new https.HttpsError('unavailable', serverError?.message || 'service unavailable', {
132
- status: 503,
133
- code: UNAVAILABLE_ERROR_CODE,
134
- ...serverError,
135
- _error: undefined
136
- });
117
+ const serverError = util.partialServerError(messageOrError);
118
+ return new https.HttpsError('unavailable', serverError?.message || 'service unavailable', {
119
+ status: 503,
120
+ code: UNAVAILABLE_ERROR_CODE,
121
+ ...serverError,
122
+ _error: undefined
123
+ });
137
124
  }
138
125
  const UNAVAILABLE_OR_DEACTIVATED_FUNCTION_ERROR_CODE = 'UNAVAILABLE_OR_DEACTIVATED_FUNCTION';
139
126
  function unavailableOrDeactivatedFunctionError(messageOrError) {
140
- const serverError = util.partialServerError(messageOrError);
141
- return new https.HttpsError('unimplemented', serverError?.message || 'the requested function is not available or has been deactivated for use', {
142
- status: 501,
143
- code: UNAVAILABLE_OR_DEACTIVATED_FUNCTION_ERROR_CODE,
144
- ...serverError,
145
- _error: undefined
146
- });
127
+ const serverError = util.partialServerError(messageOrError);
128
+ return new https.HttpsError('unimplemented', serverError?.message || 'the requested function is not available or has been deactivated for use', {
129
+ status: 501,
130
+ code: UNAVAILABLE_OR_DEACTIVATED_FUNCTION_ERROR_CODE,
131
+ ...serverError,
132
+ _error: undefined
133
+ });
147
134
  }
148
135
  const INTERNAL_SERVER_ERROR_CODE = 'INTERNAL_ERROR';
149
136
  function internalServerError(messageOrError) {
150
- const serverError = util.partialServerError(messageOrError);
151
- return new https.HttpsError('internal', serverError?.message || 'internal error', {
152
- status: 500,
153
- code: INTERNAL_SERVER_ERROR_CODE,
154
- ...serverError,
155
- _error: undefined
156
- });
137
+ const serverError = util.partialServerError(messageOrError);
138
+ return new https.HttpsError('internal', serverError?.message || 'internal error', {
139
+ status: 500,
140
+ code: INTERNAL_SERVER_ERROR_CODE,
141
+ ...serverError,
142
+ _error: undefined
143
+ });
157
144
  }
158
145
  function isFirebaseHttpsError(input) {
159
- return typeof input === 'object' && input.code != null && input.httpErrorCode != null && input.toJSON != null;
146
+ return typeof input === 'object' && input.code != null && input.httpErrorCode != null && input.toJSON != null;
160
147
  }
161
148
  function isFirebaseError(input) {
162
- return typeof input === 'object' && input.code != null && input.message != null && input.toJSON != null;
149
+ return typeof input === 'object' && input.code != null && input.message != null && input.toJSON != null;
163
150
  }
164
151
  /**
165
152
  * Creates a FirebaseServerErrorInfo from the input.
@@ -168,73 +155,74 @@ function isFirebaseError(input) {
168
155
  * @returns
169
156
  */
170
157
  function firebaseServerErrorInfo(e) {
171
- let type = 'unknown';
172
- let httpsError;
173
- let firebaseError;
174
- let firebaseErrorCode;
175
- let httpsErrorDetailsServerError;
176
- let serverErrorCode;
177
- if (e != null) {
178
- if (isFirebaseHttpsError(e)) {
179
- type = 'httpsError';
180
- httpsError = e;
181
- firebaseErrorCode = httpsError.code;
182
- if (httpsError.details && util.isServerError(httpsError.details)) {
183
- httpsErrorDetailsServerError = httpsError.details;
184
- serverErrorCode = httpsErrorDetailsServerError.code;
185
- }
186
- } else if (isFirebaseError(e)) {
187
- type = 'firebaseError';
188
- firebaseError = e;
189
- firebaseErrorCode = firebaseError.code;
190
- }
191
- }
192
- return {
193
- httpsError,
194
- firebaseError,
195
- firebaseErrorCode,
196
- httpsErrorDetailsServerError,
197
- serverErrorCode,
198
- type,
199
- e
200
- };
158
+ let type = 'unknown';
159
+ let httpsError;
160
+ let firebaseError;
161
+ let firebaseErrorCode;
162
+ let httpsErrorDetailsServerError;
163
+ let serverErrorCode;
164
+ if (e != null) {
165
+ if (isFirebaseHttpsError(e)) {
166
+ type = 'httpsError';
167
+ httpsError = e;
168
+ firebaseErrorCode = httpsError.code;
169
+ if (httpsError.details && util.isServerError(httpsError.details)) {
170
+ httpsErrorDetailsServerError = httpsError.details;
171
+ serverErrorCode = httpsErrorDetailsServerError.code;
172
+ }
173
+ }
174
+ else if (isFirebaseError(e)) {
175
+ type = 'firebaseError';
176
+ firebaseError = e;
177
+ firebaseErrorCode = firebaseError.code;
178
+ }
179
+ }
180
+ return {
181
+ httpsError,
182
+ firebaseError,
183
+ firebaseErrorCode,
184
+ httpsErrorDetailsServerError,
185
+ serverErrorCode,
186
+ type,
187
+ e
188
+ };
201
189
  }
202
190
  function firebaseServerErrorInfoCodePair(e) {
203
- const info = firebaseServerErrorInfo(e);
204
- return [info.firebaseErrorCode, info];
191
+ const info = firebaseServerErrorInfo(e);
192
+ return [info.firebaseErrorCode, info];
205
193
  }
206
194
  function firebaseServerErrorInfoServerErrorPair(e) {
207
- const info = firebaseServerErrorInfo(e);
208
- return [info.httpsErrorDetailsServerError, info];
195
+ const info = firebaseServerErrorInfo(e);
196
+ return [info.httpsErrorDetailsServerError, info];
209
197
  }
210
198
  function firebaseServerErrorInfoServerErrorCodePair(e) {
211
- const info = firebaseServerErrorInfo(e);
212
- return [info.serverErrorCode, info];
199
+ const info = firebaseServerErrorInfo(e);
200
+ return [info.serverErrorCode, info];
213
201
  }
214
202
  function handleFirebaseError(e, handleFirebaseErrorFn) {
215
- const firebaseError = e.code ? e : undefined;
216
- if (firebaseError) {
217
- handleFirebaseErrorFn(firebaseError);
218
- }
203
+ const firebaseError = e.code ? e : undefined;
204
+ if (firebaseError) {
205
+ handleFirebaseErrorFn(firebaseError);
206
+ }
219
207
  }
220
208
 
221
209
  function isContextWithAuthData(context) {
222
- return Boolean(context.auth !== null && context.auth?.uid);
210
+ return Boolean(context.auth !== null && context.auth?.uid);
223
211
  }
224
212
  function assertIsContextWithAuthData(context) {
225
- if (!isContextWithAuthData(context)) {
226
- throw unauthenticatedContextHasNoAuthData();
227
- }
213
+ if (!isContextWithAuthData(context)) {
214
+ throw unauthenticatedContextHasNoAuthData();
215
+ }
228
216
  }
229
217
 
230
218
  function firebaseAuthTokenFromDecodedIdToken(token) {
231
- return {
232
- email: token.email,
233
- emailVerified: token.email_verified,
234
- phoneNumber: token.phone_number,
235
- lastSignInTime: new Date(token.auth_time).toISOString(),
236
- lastRefreshTime: new Date(token.iat).toISOString()
237
- };
219
+ return {
220
+ email: token.email,
221
+ emailVerified: token.email_verified,
222
+ phoneNumber: token.phone_number,
223
+ lastSignInTime: new Date(token.auth_time).toISOString(),
224
+ lastRefreshTime: new Date(token.iat).toISOString()
225
+ };
238
226
  }
239
227
 
240
228
  /**
@@ -243,483 +231,458 @@ function firebaseAuthTokenFromDecodedIdToken(token) {
243
231
  * @returns
244
232
  */
245
233
  async function getAuthUserOrUndefined(promise) {
246
- try {
247
- return await promise;
248
- } catch (error) {
249
- if (error?.code === firebase.FIREBASE_AUTH_USER_NOT_FOUND_ERROR) {
250
- return undefined;
251
- } else {
252
- throw error;
234
+ try {
235
+ return await promise;
236
+ }
237
+ catch (error) {
238
+ if (error?.code === firebase.FIREBASE_AUTH_USER_NOT_FOUND_ERROR) {
239
+ return undefined;
240
+ }
241
+ else {
242
+ throw error;
243
+ }
253
244
  }
254
- }
255
245
  }
256
246
 
257
247
  /**
258
248
  * Thrown by sendSetupDetails() if the user has no setup configuration available, meaning they probably already have accepted their invite or is in an invalid state.
259
249
  */
260
250
  class FirebaseServerAuthNewUserSendSetupDetailsNoSetupConfigError extends makeError.BaseError {
261
- constructor() {
262
- super(`This user has no setup configuration available.`);
263
- }
251
+ constructor() {
252
+ super(`This user has no setup configuration available.`);
253
+ }
264
254
  }
265
255
  /**
266
256
  * Thrown by sendSetupDetails() if the user was recently sent details.
267
257
  */
268
258
  class FirebaseServerAuthNewUserSendSetupDetailsThrottleError extends makeError.BaseError {
269
- constructor(lastSentAt) {
270
- super(`This user was recently sent details. Try again later.`);
271
- this.lastSentAt = void 0;
272
- this.lastSentAt = lastSentAt;
273
- }
259
+ lastSentAt;
260
+ constructor(lastSentAt) {
261
+ super(`This user was recently sent details. Try again later.`);
262
+ this.lastSentAt = lastSentAt;
263
+ }
274
264
  }
275
265
  /**
276
266
  * Thrown by sendSetupDetails() if the user was recently sent details.
277
267
  */
278
268
  class FirebaseServerAuthNewUserSendSetupDetailsSendOnceError extends makeError.BaseError {
279
- constructor() {
280
- super(`The user has been sent details before and the sendSetupDetailsOnce configuration was true.`);
281
- }
269
+ constructor() {
270
+ super(`The user has been sent details before and the sendSetupDetailsOnce configuration was true.`);
271
+ }
282
272
  }
283
273
 
284
- const DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR = util.randomNumberFactory({
285
- min: 100000,
286
- max: 1000000,
287
- round: 'floor'
288
- }); // 6 digits
274
+ const DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR = util.randomNumberFactory({ min: 100000, max: 1000000, round: 'floor' }); // 6 digits
289
275
  class AbstractFirebaseServerAuthUserContext {
290
- constructor(service, uid) {
291
- this._service = void 0;
292
- this._uid = void 0;
293
- this._loadRecord = util.cachedGetter(() => this._service.auth.getUser(this._uid));
294
- this._service = service;
295
- this._uid = uid;
296
- }
297
- get service() {
298
- return this._service;
299
- }
300
- get uid() {
301
- return this._uid;
302
- }
303
- async exists() {
304
- return getAuthUserOrUndefined(this._loadRecord()).then(x => Boolean(x));
305
- }
306
- loadRecord() {
307
- return this._loadRecord();
308
- }
309
- loadDetails() {
310
- return this.loadRecord().then(record => this.service.authDetailsForRecord(record));
311
- }
312
- _generateResetPasswordKey() {
313
- return String(DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR());
314
- }
315
- async beginResetPassword() {
316
- const password = this._generateResetPasswordKey();
317
- const passwordClaimsData = {
318
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_PASSWORD_KEY]: password,
319
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_LAST_COM_DATE_KEY]: date.toISODateString(new Date())
320
- };
321
- // set the claims
322
- await this.updateClaims(passwordClaimsData);
323
- // update the user
324
- await this.updateUser({
325
- password
326
- });
327
- return passwordClaimsData;
328
- }
329
- async loadResetPasswordClaims() {
330
- const claims = await this.loadClaims();
331
- if (claims.resetPassword != null) {
332
- return claims;
333
- } else {
334
- return undefined;
335
- }
336
- }
337
- /**
338
- * Sets the user's password.
339
- */
340
- async setPassword(password) {
341
- const record = await this.updateUser({
342
- password
343
- });
344
- // clear password reset claims
345
- await this.updateClaims({
346
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_PASSWORD_KEY]: null,
347
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_LAST_COM_DATE_KEY]: null
348
- });
349
- return record;
350
- }
351
- async updateUser(template) {
352
- return this.service.auth.updateUser(this.uid, template);
353
- }
354
- async loadRoles() {
355
- const claims = await this.loadClaims();
356
- return this.service.readRoles(claims);
357
- }
358
- async addRoles(roles) {
359
- const claims = this._claimsForRolesChange(roles);
360
- return this.updateClaims(claims);
361
- }
362
- async removeRoles(roles) {
363
- const baseClaims = this._claimsForRolesChange(roles);
364
- const claims = {};
365
- util.forEachKeyValue(baseClaims, {
366
- forEach: ([key]) => {
367
- claims[key] = null; // set null on every key
368
- },
369
- filter: util.KeyValueTypleValueFilter.NONE // don't skip any key/value
370
- });
371
- return this.updateClaims(claims);
372
- }
373
- /**
374
- * Sets the claims using the input roles and roles set.
375
- *
376
- * All other claims are cleared.
377
- *
378
- * Use the claimsToRetain input to retain other claims that are outside of the roles.
379
- *
380
- * @param roles
381
- * @param claimsToRetain
382
- * @returns
383
- */
384
- async setRoles(roles, claimsToRetain) {
385
- const claims = {
386
- ...claimsToRetain,
387
- ...this._claimsForRolesChange(Array.from(roles))
388
- };
389
- return this.setClaims(claims);
390
- }
391
- _claimsForRolesChange(roles) {
392
- // filter null/undefined since the claims will contain null values for claims that are not related.
393
- return util.filterNullAndUndefinedValues(this.service.claimsForRoles(util.asSet(roles)));
394
- }
395
- loadClaims() {
396
- return this.loadRecord().then(x => x.customClaims ?? {});
397
- }
398
- async updateClaims(claims) {
399
- const currentClaims = await this.loadClaims();
400
- let newClaims;
401
- if (currentClaims) {
402
- newClaims = {
403
- ...currentClaims,
404
- ...util.filterUndefinedValues(claims, false)
405
- };
406
- newClaims = util.filterNullAndUndefinedValues(newClaims);
407
- } else {
408
- newClaims = claims;
409
- }
410
- return this.setClaims(newClaims);
411
- }
412
- clearClaims() {
413
- return this.setClaims(null);
414
- }
415
- setClaims(claims) {
416
- return this.service.auth.setCustomUserClaims(this.uid, claims).then(() => {
417
- this._loadRecord.reset(); // reset the cache
418
- });
419
- }
276
+ _service;
277
+ _uid;
278
+ _loadRecord = util.cachedGetter(() => this._service.auth.getUser(this._uid));
279
+ constructor(service, uid) {
280
+ this._service = service;
281
+ this._uid = uid;
282
+ }
283
+ get service() {
284
+ return this._service;
285
+ }
286
+ get uid() {
287
+ return this._uid;
288
+ }
289
+ async exists() {
290
+ return getAuthUserOrUndefined(this._loadRecord()).then((x) => Boolean(x));
291
+ }
292
+ loadRecord() {
293
+ return this._loadRecord();
294
+ }
295
+ loadDetails() {
296
+ return this.loadRecord().then((record) => this.service.authDetailsForRecord(record));
297
+ }
298
+ _generateResetPasswordKey() {
299
+ return String(DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR());
300
+ }
301
+ async beginResetPassword() {
302
+ const password = this._generateResetPasswordKey();
303
+ const passwordClaimsData = {
304
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_PASSWORD_KEY]: password,
305
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_LAST_COM_DATE_KEY]: date.toISODateString(new Date())
306
+ };
307
+ // set the claims
308
+ await this.updateClaims(passwordClaimsData);
309
+ // update the user
310
+ await this.updateUser({ password });
311
+ return passwordClaimsData;
312
+ }
313
+ async loadResetPasswordClaims() {
314
+ const claims = await this.loadClaims();
315
+ if (claims.resetPassword != null) {
316
+ return claims;
317
+ }
318
+ else {
319
+ return undefined;
320
+ }
321
+ }
322
+ /**
323
+ * Sets the user's password.
324
+ */
325
+ async setPassword(password) {
326
+ const record = await this.updateUser({ password });
327
+ // clear password reset claims
328
+ await this.updateClaims({
329
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_PASSWORD_KEY]: null,
330
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_RESET_LAST_COM_DATE_KEY]: null
331
+ });
332
+ return record;
333
+ }
334
+ async updateUser(template) {
335
+ return this.service.auth.updateUser(this.uid, template);
336
+ }
337
+ async loadRoles() {
338
+ const claims = await this.loadClaims();
339
+ return this.service.readRoles(claims);
340
+ }
341
+ async addRoles(roles) {
342
+ const claims = this._claimsForRolesChange(roles);
343
+ return this.updateClaims(claims);
344
+ }
345
+ async removeRoles(roles) {
346
+ const baseClaims = this._claimsForRolesChange(roles);
347
+ const claims = {};
348
+ util.forEachKeyValue(baseClaims, {
349
+ forEach: ([key]) => {
350
+ claims[key] = null; // set null on every key
351
+ },
352
+ filter: util.KeyValueTypleValueFilter.NONE // don't skip any key/value
353
+ });
354
+ return this.updateClaims(claims);
355
+ }
356
+ /**
357
+ * Sets the claims using the input roles and roles set.
358
+ *
359
+ * All other claims are cleared.
360
+ *
361
+ * Use the claimsToRetain input to retain other claims that are outside of the roles.
362
+ *
363
+ * @param roles
364
+ * @param claimsToRetain
365
+ * @returns
366
+ */
367
+ async setRoles(roles, claimsToRetain) {
368
+ const claims = {
369
+ ...claimsToRetain,
370
+ ...this._claimsForRolesChange(Array.from(roles))
371
+ };
372
+ return this.setClaims(claims);
373
+ }
374
+ _claimsForRolesChange(roles) {
375
+ // filter null/undefined since the claims will contain null values for claims that are not related.
376
+ return util.filterNullAndUndefinedValues(this.service.claimsForRoles(util.asSet(roles)));
377
+ }
378
+ loadClaims() {
379
+ return this.loadRecord().then((x) => (x.customClaims ?? {}));
380
+ }
381
+ async updateClaims(claims) {
382
+ const currentClaims = await this.loadClaims();
383
+ let newClaims;
384
+ if (currentClaims) {
385
+ newClaims = {
386
+ ...currentClaims,
387
+ ...util.filterUndefinedValues(claims, false)
388
+ };
389
+ newClaims = util.filterNullAndUndefinedValues(newClaims);
390
+ }
391
+ else {
392
+ newClaims = claims;
393
+ }
394
+ return this.setClaims(newClaims);
395
+ }
396
+ clearClaims() {
397
+ return this.setClaims(null);
398
+ }
399
+ setClaims(claims) {
400
+ return this.service.auth.setCustomUserClaims(this.uid, claims).then(() => {
401
+ this._loadRecord.reset(); // reset the cache
402
+ });
403
+ }
420
404
  }
421
405
  class AbstractFirebaseServerAuthContext {
422
- constructor(service, context) {
423
- this._service = void 0;
424
- this._context = void 0;
425
- this._authRoles = util.cachedGetter(() => this.service.readRoles(this.claims));
426
- this._isAdmin = util.cachedGetter(() => this.service.isAdminInRoles(this._authRoles()));
427
- this._hasSignedTos = util.cachedGetter(() => this.service.hasSignedTosInRoles(this._authRoles()));
428
- this._userContext = util.cachedGetter(() => this.service.userContext(this.context.auth.uid));
429
- this._service = service;
430
- this._context = context;
431
- }
432
- get service() {
433
- return this._service;
434
- }
435
- get context() {
436
- return this._context;
437
- }
438
- get userContext() {
439
- return this._userContext();
440
- }
441
- get isAdmin() {
442
- return this._isAdmin();
443
- }
444
- get hasSignedTos() {
445
- return this._hasSignedTos();
446
- }
447
- get authRoles() {
448
- return this._authRoles();
449
- }
450
- get token() {
451
- return this.context.auth.token;
452
- }
453
- get claims() {
454
- return this.context.auth.token;
455
- }
456
- // MARK: FirebaseServerAuthUserContext
457
- get uid() {
458
- return this.userContext.uid;
459
- }
406
+ _service;
407
+ _context;
408
+ _authRoles = util.cachedGetter(() => this.service.readRoles(this.claims));
409
+ _isAdmin = util.cachedGetter(() => this.service.isAdminInRoles(this._authRoles()));
410
+ _hasSignedTos = util.cachedGetter(() => this.service.hasSignedTosInRoles(this._authRoles()));
411
+ _userContext = util.cachedGetter(() => this.service.userContext(this.context.auth.uid));
412
+ constructor(service, context) {
413
+ this._service = service;
414
+ this._context = context;
415
+ }
416
+ get service() {
417
+ return this._service;
418
+ }
419
+ get context() {
420
+ return this._context;
421
+ }
422
+ get userContext() {
423
+ return this._userContext();
424
+ }
425
+ get isAdmin() {
426
+ return this._isAdmin();
427
+ }
428
+ get hasSignedTos() {
429
+ return this._hasSignedTos();
430
+ }
431
+ get authRoles() {
432
+ return this._authRoles();
433
+ }
434
+ get token() {
435
+ return this.context.auth.token;
436
+ }
437
+ get claims() {
438
+ return this.context.auth.token;
439
+ }
440
+ // MARK: FirebaseServerAuthUserContext
441
+ get uid() {
442
+ return this.userContext.uid;
443
+ }
460
444
  }
461
445
  /**
462
446
  * 1 hour
463
447
  */
464
448
  const DEFAULT_SETUP_COM_THROTTLE_TIME = date.hoursToMs(1);
465
449
  function userContextFromUid(authService, userContextOrUid) {
466
- const userContext = typeof userContextOrUid === 'string' ? authService.userContext(userContextOrUid) : userContextOrUid;
467
- return userContext;
450
+ const userContext = typeof userContextOrUid === 'string' ? authService.userContext(userContextOrUid) : userContextOrUid;
451
+ return userContext;
468
452
  }
469
453
  class AbstractFirebaseServerNewUserService {
470
- constructor(authService) {
471
- this._authService = void 0;
472
- this.setupThrottleTime = DEFAULT_SETUP_COM_THROTTLE_TIME;
473
- this._authService = authService;
474
- }
475
- get authService() {
476
- return this._authService;
477
- }
478
- async initializeNewUser(input) {
479
- const {
480
- uid,
481
- email,
482
- phone,
483
- sendSetupContent,
484
- sendSetupContentIfUserExists,
485
- sendSetupDetailsOnce,
486
- sendSetupIgnoreThrottle,
487
- sendSetupThrowErrors,
488
- data,
489
- sendDetailsInTestEnvironment
490
- } = input;
491
- let userRecordPromise;
492
- if (uid) {
493
- userRecordPromise = this.authService.auth.getUser(uid);
494
- } else if (email) {
495
- userRecordPromise = this.authService.auth.getUserByEmail(email);
496
- } else if (phone) {
497
- userRecordPromise = this.authService.auth.getUserByPhoneNumber(phone);
498
- } else {
499
- throw new Error('email or phone is required to initialize a new user.');
500
- }
501
- let userRecord = await getAuthUserOrUndefined(userRecordPromise);
502
- let userRecordId;
503
- let createdUser = false;
504
- if (!userRecord) {
505
- const createResult = await this.createNewUser(input);
506
- // add the setup password to the user's credentials
507
- const userContext = this.authService.userContext(createResult.user.uid);
508
- await this.addNewUserSetupClaims(userContext, createResult.password);
509
- createdUser = true;
510
- userRecordId = userContext.uid;
511
- userRecord = await userContext.loadRecord();
512
- } else {
513
- userRecordId = userRecord.uid;
514
- }
515
- // send content if necessary
516
- if (createdUser && sendSetupContent === true || sendSetupContentIfUserExists) {
517
- const sentEmail = await this.sendSetupContent(userRecordId, {
518
- data,
519
- sendSetupDetailsOnce,
520
- ignoreSendThrottleTime: sendSetupIgnoreThrottle,
521
- throwErrors: sendSetupThrowErrors,
522
- sendDetailsInTestEnvironment
523
- });
524
- // reload the user record
525
- if (sentEmail) {
526
- const userContext = this.authService.userContext(userRecordId);
527
- userRecord = await userContext.loadRecord();
528
- }
529
- }
530
- return userRecord;
531
- }
532
- async addNewUserSetupClaims(userContextOrUid, setupPassword) {
533
- const password = setupPassword ?? this.generateRandomSetupPassword();
534
- const userContext = userContextFromUid(this.authService, userContextOrUid);
535
- await userContext.updateClaims({
536
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY]: password
537
- });
538
- return userContext;
539
- }
540
- async sendSetupContent(userContextOrUid, config) {
541
- const setupDetails = await this.loadSetupDetails(userContextOrUid, config);
542
- let sentContent = false;
543
- if (setupDetails) {
544
- const {
545
- setupCommunicationAt
546
- } = setupDetails.claims;
547
- const hasSentCommunication = Boolean(setupCommunicationAt);
548
- if (config?.sendSetupDetailsOnce && hasSentCommunication) {
549
- // do not send.
550
- if (config?.throwErrors) {
551
- throw new FirebaseServerAuthNewUserSendSetupDetailsSendOnceError();
552
- }
553
- } else {
554
- const lastSentAt = setupCommunicationAt ? new Date(setupCommunicationAt) : undefined;
555
- const sendIsThrottled = hasSentCommunication && !config?.ignoreSendThrottleTime && util.isThrottled(this.setupThrottleTime, lastSentAt);
556
- if (!sendIsThrottled) {
557
- await this.sendSetupContentToUser(setupDetails);
558
- await this.updateSetupContentSentTime(setupDetails);
559
- sentContent = true;
560
- } else if (config?.throwErrors) {
561
- throw new FirebaseServerAuthNewUserSendSetupDetailsThrottleError(lastSentAt);
562
- }
563
- }
564
- } else if (config?.throwErrors) {
565
- throw new FirebaseServerAuthNewUserSendSetupDetailsNoSetupConfigError();
566
- }
567
- return sentContent;
568
- }
569
- async loadSetupDetails(userContextOrUid, config) {
570
- const userContext = userContextFromUid(this.authService, userContextOrUid);
571
- const userExists = await userContext.exists();
572
- let details;
573
- if (userExists) {
574
- details = await this.loadSetupDetailsForUserContext(userContext, config);
575
- }
576
- return details;
577
- }
578
- async loadSetupDetailsForUserContext(userContext, config) {
579
- let details;
580
- const {
581
- setupPassword,
582
- setupCommunicationAt
583
- } = await userContext.loadClaims();
584
- if (setupPassword) {
585
- details = {
586
- userContext,
587
- claims: {
588
- setupPassword,
589
- setupCommunicationAt
590
- },
591
- data: config?.data,
592
- sendDetailsInTestEnvironment: config?.sendDetailsInTestEnvironment
593
- };
594
- }
595
- return details;
596
- }
597
- async updateSetupContentSentTime(details) {
598
- const setupCommunicationAt = date.toISODateString(new Date());
599
- await details.userContext.updateClaims({
600
- setupCommunicationAt
601
- });
602
- }
603
- /**
604
- * Update a user's claims to clear any setup-related content.
605
- *
606
- * Returns true if a user was updated.
607
- *
608
- * @param uid
609
- */
610
- async markUserSetupAsComplete(uid) {
611
- const userContext = this.authService.userContext(uid);
612
- const userExists = await userContext.exists();
613
- if (userExists) {
614
- await this.updateClaimsToClearUser(userContext);
615
- }
616
- return userExists;
617
- }
618
- async createNewUser(input) {
619
- const {
620
- uid,
621
- displayName,
622
- email,
623
- phone: phoneNumber,
624
- setupPassword: inputPassword
625
- } = input;
626
- const password = inputPassword ?? this.generateRandomSetupPassword();
627
- const user = await this.authService.auth.createUser({
628
- uid,
629
- displayName,
630
- email,
631
- phoneNumber,
632
- password
633
- });
634
- return {
635
- user,
636
- password
637
- };
638
- }
639
- generateRandomSetupPassword() {
640
- return `${DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR()}`;
641
- }
642
- async updateClaimsToClearUser(userContext) {
643
- await userContext.updateClaims({
644
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY]: null,
645
- [firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_LAST_COM_DATE_KEY]: null
646
- });
647
- }
454
+ _authService;
455
+ setupThrottleTime = DEFAULT_SETUP_COM_THROTTLE_TIME;
456
+ constructor(authService) {
457
+ this._authService = authService;
458
+ }
459
+ get authService() {
460
+ return this._authService;
461
+ }
462
+ async initializeNewUser(input) {
463
+ const { uid, email, phone, sendSetupContent, sendSetupContentIfUserExists, sendSetupDetailsOnce, sendSetupIgnoreThrottle, sendSetupThrowErrors, data, sendDetailsInTestEnvironment } = input;
464
+ let userRecordPromise;
465
+ if (uid) {
466
+ userRecordPromise = this.authService.auth.getUser(uid);
467
+ }
468
+ else if (email) {
469
+ userRecordPromise = this.authService.auth.getUserByEmail(email);
470
+ }
471
+ else if (phone) {
472
+ userRecordPromise = this.authService.auth.getUserByPhoneNumber(phone);
473
+ }
474
+ else {
475
+ throw new Error('email or phone is required to initialize a new user.');
476
+ }
477
+ let userRecord = await getAuthUserOrUndefined(userRecordPromise);
478
+ let userRecordId;
479
+ let createdUser = false;
480
+ if (!userRecord) {
481
+ const createResult = await this.createNewUser(input);
482
+ // add the setup password to the user's credentials
483
+ const userContext = this.authService.userContext(createResult.user.uid);
484
+ await this.addNewUserSetupClaims(userContext, createResult.password);
485
+ createdUser = true;
486
+ userRecordId = userContext.uid;
487
+ userRecord = await userContext.loadRecord();
488
+ }
489
+ else {
490
+ userRecordId = userRecord.uid;
491
+ }
492
+ // send content if necessary
493
+ if ((createdUser && sendSetupContent === true) || sendSetupContentIfUserExists) {
494
+ const sentEmail = await this.sendSetupContent(userRecordId, { data, sendSetupDetailsOnce, ignoreSendThrottleTime: sendSetupIgnoreThrottle, throwErrors: sendSetupThrowErrors, sendDetailsInTestEnvironment });
495
+ // reload the user record
496
+ if (sentEmail) {
497
+ const userContext = this.authService.userContext(userRecordId);
498
+ userRecord = await userContext.loadRecord();
499
+ }
500
+ }
501
+ return userRecord;
502
+ }
503
+ async addNewUserSetupClaims(userContextOrUid, setupPassword) {
504
+ const password = setupPassword ?? this.generateRandomSetupPassword();
505
+ const userContext = userContextFromUid(this.authService, userContextOrUid);
506
+ await userContext.updateClaims({
507
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY]: password
508
+ });
509
+ return userContext;
510
+ }
511
+ async sendSetupContent(userContextOrUid, config) {
512
+ const setupDetails = await this.loadSetupDetails(userContextOrUid, config);
513
+ let sentContent = false;
514
+ if (setupDetails) {
515
+ const { setupCommunicationAt } = setupDetails.claims;
516
+ const hasSentCommunication = Boolean(setupCommunicationAt);
517
+ if (config?.sendSetupDetailsOnce && hasSentCommunication) {
518
+ // do not send.
519
+ if (config?.throwErrors) {
520
+ throw new FirebaseServerAuthNewUserSendSetupDetailsSendOnceError();
521
+ }
522
+ }
523
+ else {
524
+ const lastSentAt = setupCommunicationAt ? new Date(setupCommunicationAt) : undefined;
525
+ const sendIsThrottled = hasSentCommunication && !config?.ignoreSendThrottleTime && util.isThrottled(this.setupThrottleTime, lastSentAt);
526
+ if (!sendIsThrottled) {
527
+ await this.sendSetupContentToUser(setupDetails);
528
+ await this.updateSetupContentSentTime(setupDetails);
529
+ sentContent = true;
530
+ }
531
+ else if (config?.throwErrors) {
532
+ throw new FirebaseServerAuthNewUserSendSetupDetailsThrottleError(lastSentAt);
533
+ }
534
+ }
535
+ }
536
+ else if (config?.throwErrors) {
537
+ throw new FirebaseServerAuthNewUserSendSetupDetailsNoSetupConfigError();
538
+ }
539
+ return sentContent;
540
+ }
541
+ async loadSetupDetails(userContextOrUid, config) {
542
+ const userContext = userContextFromUid(this.authService, userContextOrUid);
543
+ const userExists = await userContext.exists();
544
+ let details;
545
+ if (userExists) {
546
+ details = await this.loadSetupDetailsForUserContext(userContext, config);
547
+ }
548
+ return details;
549
+ }
550
+ async loadSetupDetailsForUserContext(userContext, config) {
551
+ let details;
552
+ const { setupPassword, setupCommunicationAt } = await userContext.loadClaims();
553
+ if (setupPassword) {
554
+ details = {
555
+ userContext,
556
+ claims: {
557
+ setupPassword,
558
+ setupCommunicationAt
559
+ },
560
+ data: config?.data,
561
+ sendDetailsInTestEnvironment: config?.sendDetailsInTestEnvironment
562
+ };
563
+ }
564
+ return details;
565
+ }
566
+ async updateSetupContentSentTime(details) {
567
+ const setupCommunicationAt = date.toISODateString(new Date());
568
+ await details.userContext.updateClaims({
569
+ setupCommunicationAt
570
+ });
571
+ }
572
+ /**
573
+ * Update a user's claims to clear any setup-related content.
574
+ *
575
+ * Returns true if a user was updated.
576
+ *
577
+ * @param uid
578
+ */
579
+ async markUserSetupAsComplete(uid) {
580
+ const userContext = this.authService.userContext(uid);
581
+ const userExists = await userContext.exists();
582
+ if (userExists) {
583
+ await this.updateClaimsToClearUser(userContext);
584
+ }
585
+ return userExists;
586
+ }
587
+ async createNewUser(input) {
588
+ const { uid, displayName, email, phone: phoneNumber, setupPassword: inputPassword } = input;
589
+ const password = inputPassword ?? this.generateRandomSetupPassword();
590
+ const user = await this.authService.auth.createUser({
591
+ uid,
592
+ displayName,
593
+ email,
594
+ phoneNumber,
595
+ password
596
+ });
597
+ return {
598
+ user,
599
+ password
600
+ };
601
+ }
602
+ generateRandomSetupPassword() {
603
+ return `${DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR()}`;
604
+ }
605
+ async updateClaimsToClearUser(userContext) {
606
+ await userContext.updateClaims({
607
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY]: null,
608
+ [firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_LAST_COM_DATE_KEY]: null
609
+ });
610
+ }
648
611
  }
649
612
  class NoSetupContentFirebaseServerNewUserService extends AbstractFirebaseServerNewUserService {
650
- async sendSetupContentToUser(user) {
651
- // send nothing.
652
- }
613
+ async sendSetupContentToUser(user) {
614
+ // send nothing.
615
+ }
653
616
  }
654
617
  /**
655
618
  * FirebaseServer auth service that provides accessors to auth-related components.
656
619
  */
657
- class FirebaseServerAuthService {}
620
+ class FirebaseServerAuthService {
621
+ }
658
622
  /**
659
623
  * Abstract FirebaseServerAuthService implementation.
660
624
  */
661
625
  class AbstractFirebaseServerAuthService {
662
- constructor(auth) {
663
- this._auth = void 0;
664
- this._auth = auth;
665
- }
666
- get auth() {
667
- return this._auth;
668
- }
669
- context(context) {
670
- assertIsContextWithAuthData(context);
671
- return this._context(context);
672
- }
673
- isAdmin(claims) {
674
- return this.isAdminInRoles(this.readRoles(claims));
675
- }
676
- isAdminInRoles(roles) {
677
- return roles.has(util.AUTH_ADMIN_ROLE);
678
- }
679
- hasSignedTos(claims) {
680
- return this.hasSignedTosInRoles(this.readRoles(claims));
681
- }
682
- hasSignedTosInRoles(roles) {
683
- return roles.has(util.AUTH_TOS_SIGNED_ROLE);
684
- }
685
- newUser() {
686
- return new NoSetupContentFirebaseServerNewUserService(this);
687
- }
688
- authContextInfo(context) {
689
- const {
690
- auth
691
- } = context;
692
- let result;
693
- if (auth) {
694
- const _roles = util.cachedGetter(() => this.readRoles(auth.token));
695
- const getClaims = () => auth.token;
696
- result = {
697
- uid: auth.uid,
698
- isAdmin: () => this.isAdminInRoles(_roles()),
699
- getClaims,
700
- getAuthRoles: _roles,
701
- token: firebaseAuthTokenFromDecodedIdToken(auth.token)
702
- };
703
- }
704
- return result;
705
- }
706
- authDetailsForRecord(record) {
707
- return {
708
- uid: record.uid,
709
- email: record.email,
710
- emailVerified: record.emailVerified,
711
- phoneNumber: record.phoneNumber,
712
- disabled: record.disabled,
713
- displayName: record.displayName,
714
- photoURL: record.photoURL,
715
- creationTime: record.metadata.creationTime ? new Date(record.metadata.creationTime).toISOString() : undefined,
716
- lastSignInTime: record.metadata.lastSignInTime ? new Date(record.metadata.lastSignInTime).toISOString() : undefined,
717
- lastRefreshTime: record.metadata.lastRefreshTime ? new Date(record.metadata.lastRefreshTime).toISOString() : undefined
718
- };
719
- }
626
+ _auth;
627
+ constructor(auth) {
628
+ this._auth = auth;
629
+ }
630
+ get auth() {
631
+ return this._auth;
632
+ }
633
+ context(context) {
634
+ assertIsContextWithAuthData(context);
635
+ return this._context(context);
636
+ }
637
+ isAdmin(claims) {
638
+ return this.isAdminInRoles(this.readRoles(claims));
639
+ }
640
+ isAdminInRoles(roles) {
641
+ return roles.has(util.AUTH_ADMIN_ROLE);
642
+ }
643
+ hasSignedTos(claims) {
644
+ return this.hasSignedTosInRoles(this.readRoles(claims));
645
+ }
646
+ hasSignedTosInRoles(roles) {
647
+ return roles.has(util.AUTH_TOS_SIGNED_ROLE);
648
+ }
649
+ newUser() {
650
+ return new NoSetupContentFirebaseServerNewUserService(this);
651
+ }
652
+ authContextInfo(context) {
653
+ const { auth } = context;
654
+ let result;
655
+ if (auth) {
656
+ const _roles = util.cachedGetter(() => this.readRoles(auth.token));
657
+ const getClaims = () => auth.token;
658
+ result = {
659
+ uid: auth.uid,
660
+ isAdmin: () => this.isAdminInRoles(_roles()),
661
+ getClaims,
662
+ getAuthRoles: _roles,
663
+ token: firebaseAuthTokenFromDecodedIdToken(auth.token)
664
+ };
665
+ }
666
+ return result;
667
+ }
668
+ authDetailsForRecord(record) {
669
+ return {
670
+ uid: record.uid,
671
+ email: record.email,
672
+ emailVerified: record.emailVerified,
673
+ phoneNumber: record.phoneNumber,
674
+ disabled: record.disabled,
675
+ displayName: record.displayName,
676
+ photoURL: record.photoURL,
677
+ creationTime: record.metadata.creationTime ? new Date(record.metadata.creationTime).toISOString() : undefined,
678
+ lastSignInTime: record.metadata.lastSignInTime ? new Date(record.metadata.lastSignInTime).toISOString() : undefined,
679
+ lastRefreshTime: record.metadata.lastRefreshTime ? new Date(record.metadata.lastRefreshTime).toISOString() : undefined
680
+ };
681
+ }
720
682
  }
721
683
 
722
- class FirebaseServerEnvService {}
684
+ class FirebaseServerEnvService {
685
+ }
723
686
 
724
687
  /**
725
688
  * Creates UpdateData corresponding to the input increment update.
@@ -728,9 +691,9 @@ class FirebaseServerEnvService {}
728
691
  * @returns
729
692
  */
730
693
  function firestoreServerIncrementUpdateToUpdateData(input) {
731
- return util.mapObjectMap(input, incrementValue => {
732
- return firestore.FieldValue.increment(incrementValue ?? 0);
733
- });
694
+ return util.mapObjectMap(input, (incrementValue) => {
695
+ return firestore.FieldValue.increment(incrementValue ?? 0);
696
+ });
734
697
  }
735
698
 
736
699
  /**
@@ -740,26 +703,26 @@ function firestoreServerIncrementUpdateToUpdateData(input) {
740
703
  * @returns
741
704
  */
742
705
  function firestoreServerArrayUpdateToUpdateData(input) {
743
- const union = input?.union;
744
- const remove = input?.remove;
745
- function createUpdatesWithArrayFunction(fieldUpdate, arrayUpdateFunction) {
746
- let result;
747
- if (fieldUpdate) {
748
- result = util.mapObjectMap(fieldUpdate, arrayUpdate => {
706
+ const union = input?.union;
707
+ const remove = input?.remove;
708
+ function createUpdatesWithArrayFunction(fieldUpdate, arrayUpdateFunction) {
749
709
  let result;
750
- if (arrayUpdate) {
751
- result = arrayUpdateFunction(...arrayUpdate); // use spread operator to insert each value as an argument, as "nested arrays" are not allowed in the Firestore
710
+ if (fieldUpdate) {
711
+ result = util.mapObjectMap(fieldUpdate, (arrayUpdate) => {
712
+ let result;
713
+ if (arrayUpdate) {
714
+ result = arrayUpdateFunction(...arrayUpdate); // use spread operator to insert each value as an argument, as "nested arrays" are not allowed in the Firestore
715
+ }
716
+ return result;
717
+ });
752
718
  }
753
719
  return result;
754
- });
755
720
  }
756
- return result;
757
- }
758
- const updateData = {
759
- ...createUpdatesWithArrayFunction(union, firestore.FieldValue.arrayUnion),
760
- ...createUpdatesWithArrayFunction(remove, firestore.FieldValue.arrayRemove)
761
- };
762
- return updateData;
721
+ const updateData = {
722
+ ...createUpdatesWithArrayFunction(union, firestore.FieldValue.arrayUnion),
723
+ ...createUpdatesWithArrayFunction(remove, firestore.FieldValue.arrayRemove)
724
+ };
725
+ return updateData;
763
726
  }
764
727
 
765
728
  // MARK: Accessor
@@ -767,53 +730,54 @@ function firestoreServerArrayUpdateToUpdateData(input) {
767
730
  * FirestoreDocumentDataAccessor implementation for a batch.
768
731
  */
769
732
  class WriteBatchFirestoreDocumentDataAccessor {
770
- constructor(batch, documentRef) {
771
- this.documentRef = void 0;
772
- this._batch = void 0;
773
- this.documentRef = documentRef;
774
- this._batch = batch;
775
- }
776
- get batch() {
777
- return this._batch;
778
- }
779
- stream() {
780
- return rxjs.from(this.get()); // todo
781
- }
782
- create(data) {
783
- this.batch.create(this.documentRef, data);
784
- return Promise.resolve();
785
- }
786
- exists() {
787
- return this.get().then(x => x.exists);
788
- }
789
- get() {
790
- return this.documentRef.get();
791
- }
792
- getWithConverter(converter) {
793
- return this.documentRef.withConverter(converter).get();
794
- }
795
- delete(params) {
796
- this.batch.delete(this.documentRef, params?.precondition);
797
- return Promise.resolve();
798
- }
799
- set(data) {
800
- this.batch.set(this.documentRef, data);
801
- return Promise.resolve();
802
- }
803
- increment(data, params) {
804
- return this.update(firestoreServerIncrementUpdateToUpdateData(data), params);
805
- }
806
- arrayUpdate(data, params) {
807
- return this.update(firestoreServerArrayUpdateToUpdateData(data), params);
808
- }
809
- update(data, params) {
810
- if (params?.precondition != null) {
811
- this.batch.update(this.documentRef, data, params?.precondition);
812
- } else {
813
- this.batch.update(this.documentRef, data);
814
- }
815
- return Promise.resolve();
816
- }
733
+ documentRef;
734
+ _batch;
735
+ constructor(batch, documentRef) {
736
+ this.documentRef = documentRef;
737
+ this._batch = batch;
738
+ }
739
+ get batch() {
740
+ return this._batch;
741
+ }
742
+ stream() {
743
+ return rxjs.from(this.get()); // todo
744
+ }
745
+ create(data) {
746
+ this.batch.create(this.documentRef, data);
747
+ return Promise.resolve();
748
+ }
749
+ exists() {
750
+ return this.get().then((x) => x.exists);
751
+ }
752
+ get() {
753
+ return this.documentRef.get();
754
+ }
755
+ getWithConverter(converter) {
756
+ return this.documentRef.withConverter(converter).get();
757
+ }
758
+ delete(params) {
759
+ this.batch.delete(this.documentRef, params?.precondition);
760
+ return Promise.resolve();
761
+ }
762
+ set(data) {
763
+ this.batch.set(this.documentRef, data);
764
+ return Promise.resolve();
765
+ }
766
+ increment(data, params) {
767
+ return this.update(firestoreServerIncrementUpdateToUpdateData(data), params);
768
+ }
769
+ arrayUpdate(data, params) {
770
+ return this.update(firestoreServerArrayUpdateToUpdateData(data), params);
771
+ }
772
+ update(data, params) {
773
+ if (params?.precondition != null) {
774
+ this.batch.update(this.documentRef, data, params?.precondition);
775
+ }
776
+ else {
777
+ this.batch.update(this.documentRef, data);
778
+ }
779
+ return Promise.resolve();
780
+ }
817
781
  }
818
782
  /**
819
783
  * Creates a new FirestoreDocumentDataAccessorFactory for a Batch.
@@ -822,81 +786,78 @@ class WriteBatchFirestoreDocumentDataAccessor {
822
786
  * @returns
823
787
  */
824
788
  function writeBatchAccessorFactory(writeBatch) {
825
- return {
826
- accessorFor: ref => new WriteBatchFirestoreDocumentDataAccessor(writeBatch, ref)
827
- };
789
+ return {
790
+ accessorFor: (ref) => new WriteBatchFirestoreDocumentDataAccessor(writeBatch, ref)
791
+ };
828
792
  }
829
793
  // MARK: Context
830
794
  class WriteBatchFirestoreDocumentContext {
831
- constructor(batch) {
832
- this._batch = void 0;
833
- this.contextType = firebase.FirestoreDocumentContextType.BATCH;
834
- this.accessorFactory = void 0;
835
- this._batch = batch;
836
- this.accessorFactory = writeBatchAccessorFactory(batch);
837
- }
838
- get batch() {
839
- return this._batch;
840
- }
795
+ _batch;
796
+ contextType = firebase.FirestoreDocumentContextType.BATCH;
797
+ accessorFactory;
798
+ constructor(batch) {
799
+ this._batch = batch;
800
+ this.accessorFactory = writeBatchAccessorFactory(batch);
801
+ }
802
+ get batch() {
803
+ return this._batch;
804
+ }
841
805
  }
842
806
  function writeBatchDocumentContext(batch) {
843
- return new WriteBatchFirestoreDocumentContext(batch);
807
+ return new WriteBatchFirestoreDocumentContext(batch);
844
808
  }
845
809
 
846
810
  // MARK: Accessor
847
811
  class DefaultFirestoreDocumentDataAccessor {
848
- constructor(documentRef) {
849
- this._documentRef = void 0;
850
- this._documentRef = documentRef;
851
- }
852
- get documentRef() {
853
- return this._documentRef;
854
- }
855
- stream() {
856
- return firebase.streamFromOnSnapshot(({
857
- next,
858
- error
859
- }) => this.documentRef.onSnapshot(next, error));
860
- }
861
- create(data) {
862
- return this.documentRef.create(data);
863
- }
864
- exists() {
865
- return this.get().then(x => x.exists);
866
- }
867
- get() {
868
- return this.documentRef.get();
869
- }
870
- getWithConverter(converter) {
871
- return this.documentRef.withConverter(converter).get();
872
- }
873
- delete(params) {
874
- return this.documentRef.delete(params?.precondition);
875
- }
876
- set(data, options) {
877
- return options ? this.documentRef.set(data, options) : this.documentRef.set(data);
878
- }
879
- increment(data, params) {
880
- return this.update(firestoreServerIncrementUpdateToUpdateData(data), params);
881
- }
882
- arrayUpdate(data, params) {
883
- return this.update(firestoreServerArrayUpdateToUpdateData(data), params);
884
- }
885
- update(data, params) {
886
- return params?.precondition ? this.documentRef.update(data, params.precondition) : this.documentRef.update(data);
887
- }
812
+ _documentRef;
813
+ constructor(documentRef) {
814
+ this._documentRef = documentRef;
815
+ }
816
+ get documentRef() {
817
+ return this._documentRef;
818
+ }
819
+ stream() {
820
+ return firebase.streamFromOnSnapshot(({ next, error }) => this.documentRef.onSnapshot(next, error));
821
+ }
822
+ create(data) {
823
+ return this.documentRef.create(data);
824
+ }
825
+ exists() {
826
+ return this.get().then((x) => x.exists);
827
+ }
828
+ get() {
829
+ return this.documentRef.get();
830
+ }
831
+ getWithConverter(converter) {
832
+ return this.documentRef.withConverter(converter).get();
833
+ }
834
+ delete(params) {
835
+ return this.documentRef.delete(params?.precondition);
836
+ }
837
+ set(data, options) {
838
+ return options ? this.documentRef.set(data, options) : this.documentRef.set(data);
839
+ }
840
+ increment(data, params) {
841
+ return this.update(firestoreServerIncrementUpdateToUpdateData(data), params);
842
+ }
843
+ arrayUpdate(data, params) {
844
+ return this.update(firestoreServerArrayUpdateToUpdateData(data), params);
845
+ }
846
+ update(data, params) {
847
+ return params?.precondition ? this.documentRef.update(data, params.precondition) : this.documentRef.update(data);
848
+ }
888
849
  }
889
850
  function defaultFirestoreAccessorFactory() {
890
- return {
891
- accessorFor: ref => new DefaultFirestoreDocumentDataAccessor(ref)
892
- };
851
+ return {
852
+ accessorFor: (ref) => new DefaultFirestoreDocumentDataAccessor(ref)
853
+ };
893
854
  }
894
855
  // MARK: Context
895
856
  function defaultFirestoreDocumentContext() {
896
- return {
897
- contextType: firebase.FirestoreDocumentContextType.NONE,
898
- accessorFactory: defaultFirestoreAccessorFactory()
899
- };
857
+ return {
858
+ contextType: firebase.FirestoreDocumentContextType.NONE,
859
+ accessorFactory: defaultFirestoreAccessorFactory()
860
+ };
900
861
  }
901
862
 
902
863
  // MARK: Accessor
@@ -904,56 +865,57 @@ function defaultFirestoreDocumentContext() {
904
865
  * FirestoreDocumentDataAccessor implementation for a transaction.
905
866
  */
906
867
  class TransactionFirestoreDocumentDataAccessor {
907
- constructor(transaction, documentRef) {
908
- this._transaction = void 0;
909
- this._documentRef = void 0;
910
- this._transaction = transaction;
911
- this._documentRef = documentRef;
912
- }
913
- get transaction() {
914
- return this._transaction;
915
- }
916
- get documentRef() {
917
- return this._documentRef;
918
- }
919
- stream() {
920
- return rxjs.from(this.get());
921
- }
922
- create(data) {
923
- this.transaction.create(this.documentRef, data);
924
- return Promise.resolve();
925
- }
926
- exists() {
927
- return this.get().then(x => x.exists);
928
- }
929
- get() {
930
- return this.transaction.get(this.documentRef);
931
- }
932
- getWithConverter(converter) {
933
- return this.transaction.get(this.documentRef.withConverter(converter));
934
- }
935
- delete() {
936
- this.transaction.delete(this.documentRef);
937
- return Promise.resolve();
938
- }
939
- set(data, options) {
940
- this.transaction.set(this.documentRef, data, options);
941
- return Promise.resolve();
942
- }
943
- increment(data, params) {
944
- return this.update(firestoreServerIncrementUpdateToUpdateData(data), params);
945
- }
946
- arrayUpdate(data, params) {
947
- return this.update(firestoreServerArrayUpdateToUpdateData(data), params);
948
- }
949
- update(data, params) {
950
- if (params?.precondition) {
951
- this.transaction.update(this.documentRef, data, params?.precondition);
952
- } else {
953
- this.transaction.update(this.documentRef, data);
954
- }
955
- return Promise.resolve();
956
- }
868
+ _transaction;
869
+ _documentRef;
870
+ constructor(transaction, documentRef) {
871
+ this._transaction = transaction;
872
+ this._documentRef = documentRef;
873
+ }
874
+ get transaction() {
875
+ return this._transaction;
876
+ }
877
+ get documentRef() {
878
+ return this._documentRef;
879
+ }
880
+ stream() {
881
+ return rxjs.from(this.get());
882
+ }
883
+ create(data) {
884
+ this.transaction.create(this.documentRef, data);
885
+ return Promise.resolve();
886
+ }
887
+ exists() {
888
+ return this.get().then((x) => x.exists);
889
+ }
890
+ get() {
891
+ return this.transaction.get(this.documentRef);
892
+ }
893
+ getWithConverter(converter) {
894
+ return this.transaction.get(this.documentRef.withConverter(converter));
895
+ }
896
+ delete() {
897
+ this.transaction.delete(this.documentRef);
898
+ return Promise.resolve();
899
+ }
900
+ set(data, options) {
901
+ this.transaction.set(this.documentRef, data, options);
902
+ return Promise.resolve();
903
+ }
904
+ increment(data, params) {
905
+ return this.update(firestoreServerIncrementUpdateToUpdateData(data), params);
906
+ }
907
+ arrayUpdate(data, params) {
908
+ return this.update(firestoreServerArrayUpdateToUpdateData(data), params);
909
+ }
910
+ update(data, params) {
911
+ if (params?.precondition) {
912
+ this.transaction.update(this.documentRef, data, params?.precondition);
913
+ }
914
+ else {
915
+ this.transaction.update(this.documentRef, data);
916
+ }
917
+ return Promise.resolve();
918
+ }
957
919
  }
958
920
  /**
959
921
  * Creates a new FirestoreDocumentDataAccessorFactory for a Transaction.
@@ -962,122 +924,123 @@ class TransactionFirestoreDocumentDataAccessor {
962
924
  * @returns
963
925
  */
964
926
  function transactionAccessorFactory(transaction) {
965
- return {
966
- accessorFor: ref => new TransactionFirestoreDocumentDataAccessor(transaction, ref)
967
- };
927
+ return {
928
+ accessorFor: (ref) => new TransactionFirestoreDocumentDataAccessor(transaction, ref)
929
+ };
968
930
  }
969
931
  // MARK: Context
970
932
  class TransactionFirestoreDocumentContext {
971
- constructor(transaction) {
972
- this._transaction = void 0;
973
- this.contextType = firebase.FirestoreDocumentContextType.TRANSACTION;
974
- this.accessorFactory = void 0;
975
- this._transaction = transaction;
976
- this.accessorFactory = transactionAccessorFactory(transaction);
977
- }
978
- get transaction() {
979
- return this._transaction;
980
- }
933
+ _transaction;
934
+ contextType = firebase.FirestoreDocumentContextType.TRANSACTION;
935
+ accessorFactory;
936
+ constructor(transaction) {
937
+ this._transaction = transaction;
938
+ this.accessorFactory = transactionAccessorFactory(transaction);
939
+ }
940
+ get transaction() {
941
+ return this._transaction;
942
+ }
981
943
  }
982
944
  function transactionDocumentContext(transaction) {
983
- return new TransactionFirestoreDocumentContext(transaction);
945
+ return new TransactionFirestoreDocumentContext(transaction);
984
946
  }
985
947
 
986
948
  function collectionRefForPath(start, path, pathSegments) {
987
- let ref = start.collection(path);
988
- if (pathSegments?.length) {
989
- if (pathSegments?.length % 2 !== 0) {
990
- throw new Error(`Invalid number of path segments provided for collection. Path: "${path}" + "${pathSegments}"`);
991
- }
992
- const batches = util.batch(pathSegments, 2); // batch to tuple [string, string]
993
- batches.forEach(x => {
994
- const [first, second] = x;
995
- ref = ref.doc(first).collection(second);
996
- });
997
- }
998
- return ref;
949
+ let ref = start.collection(path);
950
+ if (pathSegments?.length) {
951
+ if (pathSegments?.length % 2 !== 0) {
952
+ throw new Error(`Invalid number of path segments provided for collection. Path: "${path}" + "${pathSegments}"`);
953
+ }
954
+ const batches = util.batch(pathSegments, 2); // batch to tuple [string, string]
955
+ batches.forEach((x) => {
956
+ const [first, second] = x;
957
+ ref = ref.doc(first).collection(second);
958
+ });
959
+ }
960
+ return ref;
999
961
  }
1000
962
  function docRefForPath(start, path, pathSegments) {
1001
- let doc = path ? start.doc(path) : start.doc();
1002
- if (pathSegments?.length) {
1003
- const batches = util.batch(pathSegments, 2); // batch to tuple [string, string]
1004
- batches.forEach(x => {
1005
- const [first, second] = x;
1006
- const collection = doc.collection(first);
1007
- doc = second ? collection.doc(second) : collection.doc();
1008
- });
1009
- }
1010
- return doc;
963
+ let doc = (path ? start.doc(path) : start.doc());
964
+ if (pathSegments?.length) {
965
+ const batches = util.batch(pathSegments, 2); // batch to tuple [string, string]
966
+ batches.forEach((x) => {
967
+ const [first, second] = x;
968
+ const collection = doc.collection(first);
969
+ doc = second ? collection.doc(second) : collection.doc();
970
+ });
971
+ }
972
+ return doc;
1011
973
  }
1012
974
  function googleCloudFirestoreAccessorDriver() {
1013
- return {
1014
- doc: (collection, path, ...pathSegments) => docRefForPath(collection, path, pathSegments),
1015
- docAtPath: (firestore, fullPath) => firestore.doc(fullPath),
1016
- collectionGroup: (firestore, collectionId) => firestore.collectionGroup(collectionId),
1017
- collection: (firestore, path, ...pathSegments) => collectionRefForPath(firestore, path, pathSegments),
1018
- subcollection: (document, path, ...pathSegments) => collectionRefForPath(document, path, pathSegments),
1019
- transactionFactoryForFirestore: firestore => async fn => await firestore.runTransaction(fn),
1020
- writeBatchFactoryForFirestore: firestore => () => firestore.batch(),
1021
- defaultContextFactory: defaultFirestoreDocumentContext,
1022
- transactionContextFactory: transactionDocumentContext,
1023
- writeBatchContextFactory: writeBatchDocumentContext
1024
- };
975
+ return {
976
+ doc: (collection, path, ...pathSegments) => docRefForPath(collection, path, pathSegments),
977
+ docAtPath: (firestore, fullPath) => firestore.doc(fullPath),
978
+ collectionGroup: (firestore, collectionId) => firestore.collectionGroup(collectionId),
979
+ collection: (firestore, path, ...pathSegments) => collectionRefForPath(firestore, path, pathSegments),
980
+ subcollection: (document, path, ...pathSegments) => collectionRefForPath(document, path, pathSegments),
981
+ transactionFactoryForFirestore: (firestore) => async (fn) => await firestore.runTransaction(fn),
982
+ writeBatchFactoryForFirestore: (firestore) => () => firestore.batch(),
983
+ defaultContextFactory: defaultFirestoreDocumentContext,
984
+ transactionContextFactory: transactionDocumentContext,
985
+ writeBatchContextFactory: writeBatchDocumentContext
986
+ };
1025
987
  }
1026
988
 
1027
989
  const FIRESTORE_CLIENT_QUERY_CONSTRAINT_HANDLER_MAPPING = {
1028
- [firebase.FIRESTORE_LIMIT_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.limit(data.limit),
1029
- [firebase.FIRESTORE_LIMIT_TO_LAST_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.limitToLast(data.limit),
1030
- [firebase.FIRESTORE_ORDER_BY_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.orderBy(data.fieldPath, data.directionStr),
1031
- [firebase.FIRESTORE_ORDER_BY_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.orderBy(firestore.FieldPath.documentId(), data.directionStr),
1032
- [firebase.FIRESTORE_WHERE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.where(data.fieldPath, data.opStr, data.value),
1033
- [firebase.FIRESTORE_WHERE_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.where(firestore.FieldPath.documentId(), data.opStr, data.value),
1034
- [firebase.FIRESTORE_OFFSET_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.offset(data.offset),
1035
- [firebase.FIRESTORE_START_AT_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.startAt(data.snapshot),
1036
- [firebase.FIRESTORE_START_AT_VALUE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.startAt(...data.fieldValues),
1037
- [firebase.FIRESTORE_START_AFTER_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.startAfter(data.snapshot),
1038
- [firebase.FIRESTORE_END_AT_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.endAt(data.snapshot),
1039
- [firebase.FIRESTORE_END_AT_VALUE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.endAt(...data.fieldValues),
1040
- [firebase.FIRESTORE_END_BEFORE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.endBefore(data.snapshot)
990
+ [firebase.FIRESTORE_LIMIT_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.limit(data.limit),
991
+ [firebase.FIRESTORE_LIMIT_TO_LAST_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.limitToLast(data.limit),
992
+ [firebase.FIRESTORE_ORDER_BY_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.orderBy(data.fieldPath, data.directionStr),
993
+ [firebase.FIRESTORE_ORDER_BY_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.orderBy(firestore.FieldPath.documentId(), data.directionStr),
994
+ [firebase.FIRESTORE_WHERE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.where(data.fieldPath, data.opStr, data.value),
995
+ [firebase.FIRESTORE_WHERE_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.where(firestore.FieldPath.documentId(), data.opStr, data.value),
996
+ [firebase.FIRESTORE_OFFSET_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.offset(data.offset),
997
+ [firebase.FIRESTORE_START_AT_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.startAt(data.snapshot),
998
+ [firebase.FIRESTORE_START_AT_VALUE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.startAt(...data.fieldValues),
999
+ [firebase.FIRESTORE_START_AFTER_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.startAfter(data.snapshot),
1000
+ [firebase.FIRESTORE_END_AT_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.endAt(data.snapshot),
1001
+ [firebase.FIRESTORE_END_AT_VALUE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.endAt(...data.fieldValues),
1002
+ [firebase.FIRESTORE_END_BEFORE_QUERY_CONSTRAINT_TYPE]: (builder, data) => builder.endBefore(data.snapshot)
1041
1003
  };
1042
1004
  function firestoreClientQueryConstraintFunctionsDriver() {
1043
- return firebase.makeFirestoreQueryConstraintFunctionsDriver({
1044
- mapping: FIRESTORE_CLIENT_QUERY_CONSTRAINT_HANDLER_MAPPING,
1045
- init: query => query,
1046
- build: query => query,
1047
- documentIdFieldPath: () => firestore.FieldPath.documentId()
1048
- });
1005
+ return firebase.makeFirestoreQueryConstraintFunctionsDriver({
1006
+ mapping: FIRESTORE_CLIENT_QUERY_CONSTRAINT_HANDLER_MAPPING,
1007
+ init: (query) => query,
1008
+ build: (query) => query,
1009
+ documentIdFieldPath: () => firestore.FieldPath.documentId()
1010
+ });
1049
1011
  }
1050
1012
  function googleCloudFirestoreQueryDriver() {
1051
- return {
1052
- ...firestoreClientQueryConstraintFunctionsDriver(),
1053
- countDocs(query) {
1054
- return query.count().get().then(x => x.data().count);
1055
- },
1056
- getDocs(query, transaction) {
1057
- let result;
1058
- if (transaction) {
1059
- result = transaction.get(query);
1060
- } else {
1061
- result = query.get();
1062
- }
1063
- return result;
1064
- },
1065
- streamDocs(query) {
1066
- return firebase.streamFromOnSnapshot(({
1067
- next,
1068
- error
1069
- }) => query.onSnapshot(next, error));
1070
- }
1071
- };
1013
+ return {
1014
+ ...firestoreClientQueryConstraintFunctionsDriver(),
1015
+ countDocs(query) {
1016
+ return query
1017
+ .count()
1018
+ .get()
1019
+ .then((x) => x.data().count);
1020
+ },
1021
+ getDocs(query, transaction) {
1022
+ let result;
1023
+ if (transaction) {
1024
+ result = transaction.get(query);
1025
+ }
1026
+ else {
1027
+ result = query.get();
1028
+ }
1029
+ return result;
1030
+ },
1031
+ streamDocs(query) {
1032
+ return firebase.streamFromOnSnapshot(({ next, error }) => query.onSnapshot(next, error));
1033
+ }
1034
+ };
1072
1035
  }
1073
1036
 
1074
1037
  function googleCloudFirestoreDrivers() {
1075
- return {
1076
- firestoreDriverIdentifier: '@google-cloud/firestore',
1077
- firestoreDriverType: 'production',
1078
- firestoreAccessorDriver: googleCloudFirestoreAccessorDriver(),
1079
- firestoreQueryDriver: googleCloudFirestoreQueryDriver()
1080
- };
1038
+ return {
1039
+ firestoreDriverIdentifier: '@google-cloud/firestore',
1040
+ firestoreDriverType: 'production',
1041
+ firestoreAccessorDriver: googleCloudFirestoreAccessorDriver(),
1042
+ firestoreQueryDriver: googleCloudFirestoreQueryDriver()
1043
+ };
1081
1044
  }
1082
1045
 
1083
1046
  /**
@@ -1086,9 +1049,9 @@ function googleCloudFirestoreDrivers() {
1086
1049
  const googleCloudFirestoreContextFactory = firebase.firestoreContextFactory(googleCloudFirestoreDrivers());
1087
1050
 
1088
1051
  function assertContextHasAuth(context) {
1089
- if (!isContextWithAuthData(context)) {
1090
- throw unauthenticatedContextHasNoUidError();
1091
- }
1052
+ if (!isContextWithAuthData(context)) {
1053
+ throw unauthenticatedContextHasNoUidError();
1054
+ }
1092
1055
  }
1093
1056
  /**
1094
1057
  * Attempts to load data from the document. A modelNotAvailableError is thrown if the snapshot data is null/undefined (the document does not exist).
@@ -1098,13 +1061,13 @@ function assertContextHasAuth(context) {
1098
1061
  * @returns
1099
1062
  */
1100
1063
  async function assertSnapshotData(document, message) {
1101
- const data = await document.snapshotData();
1102
- if (data == null) {
1103
- throw modelNotAvailableError({
1104
- message: message ?? `The ${document.modelType} was unavailable.`
1105
- });
1106
- }
1107
- return data;
1064
+ const data = await document.snapshotData();
1065
+ if (data == null) {
1066
+ throw modelNotAvailableError({
1067
+ message: message ?? `The ${document.modelType} was unavailable.`
1068
+ });
1069
+ }
1070
+ return data;
1108
1071
  }
1109
1072
  /**
1110
1073
  * Convenience function for assertSnapshotData that also attaches the id and key of the document to the data.
@@ -1114,8 +1077,8 @@ async function assertSnapshotData(document, message) {
1114
1077
  * @returns
1115
1078
  */
1116
1079
  async function assertSnapshotDataWithKey(document, message) {
1117
- const data = await assertSnapshotData(document, message);
1118
- return firebase.setIdAndKeyFromKeyIdRefOnDocumentData(data, document);
1080
+ const data = await assertSnapshotData(document, message);
1081
+ return firebase.setIdAndKeyFromKeyIdRefOnDocumentData(data, document);
1119
1082
  }
1120
1083
  /**
1121
1084
  * Asserts that the document exists. A modelNotAvailableError is thrown if the document does not exist.
@@ -1125,10 +1088,10 @@ async function assertSnapshotDataWithKey(document, message) {
1125
1088
  * @returns
1126
1089
  */
1127
1090
  async function assertDocumentExists(document, message) {
1128
- const exists = await document.exists();
1129
- if (!exists) {
1130
- throw documentModelNotAvailableError(document, message);
1131
- }
1091
+ const exists = await document.exists();
1092
+ if (!exists) {
1093
+ throw documentModelNotAvailableError(document, message);
1094
+ }
1132
1095
  }
1133
1096
  /**
1134
1097
  * Error thrown by assertDocumentExists().
@@ -1138,28 +1101,28 @@ async function assertDocumentExists(document, message) {
1138
1101
  * @returns
1139
1102
  */
1140
1103
  function documentModelNotAvailableError(document, message) {
1141
- return modelNotAvailableError({
1142
- message: message ?? `The ${document.modelType} was unavailable.`
1143
- });
1104
+ return modelNotAvailableError({
1105
+ message: message ?? `The ${document.modelType} was unavailable.`
1106
+ });
1144
1107
  }
1145
1108
 
1146
1109
  const PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE = 'PHONE_NUMBER_ALREADY_EXISTS';
1147
1110
  function phoneNumberAlreadyExistsError() {
1148
- return preconditionConflictError({
1149
- code: PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE,
1150
- message: 'This phone number already exists in the system.'
1151
- });
1111
+ return preconditionConflictError({
1112
+ code: PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE,
1113
+ message: 'This phone number already exists in the system.'
1114
+ });
1152
1115
  }
1153
1116
  function handleFirebaseAuthError(e, handleUnknownCode) {
1154
- handleFirebaseError(e, firebaseError => {
1155
- switch (firebaseError.code) {
1156
- case 'auth/phone-number-already-exists':
1157
- throw phoneNumberAlreadyExistsError();
1158
- default:
1159
- handleUnknownCode?.(firebaseError);
1160
- break;
1161
- }
1162
- });
1117
+ handleFirebaseError(e, (firebaseError) => {
1118
+ switch (firebaseError.code) {
1119
+ case 'auth/phone-number-already-exists':
1120
+ throw phoneNumberAlreadyExistsError();
1121
+ default:
1122
+ handleUnknownCode?.(firebaseError);
1123
+ break;
1124
+ }
1125
+ });
1163
1126
  }
1164
1127
 
1165
1128
  /******************************************************************************
@@ -1206,10 +1169,10 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
1206
1169
  const FIREBASE_APP_TOKEN = 'FIREBASE_APP_TOKEN';
1207
1170
  // MARK: Firebase Admin Provider
1208
1171
  function firebaseServerAppTokenProvider(useFactory) {
1209
- return {
1210
- provide: FIREBASE_APP_TOKEN,
1211
- useFactory
1212
- };
1172
+ return {
1173
+ provide: FIREBASE_APP_TOKEN,
1174
+ useFactory
1175
+ };
1213
1176
  }
1214
1177
 
1215
1178
  // MARK: Tokens
@@ -1220,23 +1183,31 @@ const FIREBASE_AUTH_TOKEN = 'FIREBASE_AUTH_TOKEN';
1220
1183
  /**
1221
1184
  * Nest provider module for Firebase that provides a firestore, etc. from the firestore token.
1222
1185
  */
1223
- exports.FirebaseServerAuthModule = class FirebaseServerAuthModule {};
1224
- exports.FirebaseServerAuthModule = __decorate([common.Module({
1225
- providers: [{
1226
- provide: FIREBASE_AUTH_TOKEN,
1227
- useFactory: app => app.auth(),
1228
- inject: [FIREBASE_APP_TOKEN]
1229
- }],
1230
- exports: [FIREBASE_AUTH_TOKEN]
1231
- })], exports.FirebaseServerAuthModule);
1186
+ exports.FirebaseServerAuthModule = class FirebaseServerAuthModule {
1187
+ };
1188
+ exports.FirebaseServerAuthModule = __decorate([
1189
+ common.Module({
1190
+ providers: [
1191
+ {
1192
+ provide: FIREBASE_AUTH_TOKEN,
1193
+ useFactory: (app) => app.auth(),
1194
+ inject: [FIREBASE_APP_TOKEN]
1195
+ }
1196
+ ],
1197
+ exports: [FIREBASE_AUTH_TOKEN]
1198
+ })
1199
+ ], exports.FirebaseServerAuthModule);
1232
1200
  function provideFirebaseServerAuthService(provider) {
1233
- return [{
1234
- ...provider,
1235
- inject: provider.inject ?? [FIREBASE_AUTH_TOKEN]
1236
- }, {
1237
- provide: FirebaseServerAuthService,
1238
- useExisting: provider.provide
1239
- }];
1201
+ return [
1202
+ {
1203
+ ...provider,
1204
+ inject: provider.inject ?? [FIREBASE_AUTH_TOKEN]
1205
+ },
1206
+ {
1207
+ provide: FirebaseServerAuthService,
1208
+ useExisting: provider.provide
1209
+ }
1210
+ ];
1240
1211
  }
1241
1212
  /**
1242
1213
  * Convenience function used to generate ModuleMetadata for an app's Auth related modules and FirebaseServerAuthService provider.
@@ -1246,58 +1217,58 @@ function provideFirebaseServerAuthService(provider) {
1246
1217
  * @returns
1247
1218
  */
1248
1219
  function firebaseServerAuthModuleMetadata(config) {
1249
- return nestjs.mergeModuleMetadata({
1250
- imports: [exports.FirebaseServerAuthModule],
1251
- exports: [exports.FirebaseServerAuthModule, config.serviceProvider.provide],
1252
- providers: provideFirebaseServerAuthService(config.serviceProvider)
1253
- }, config);
1220
+ return nestjs.mergeModuleMetadata({
1221
+ imports: [exports.FirebaseServerAuthModule],
1222
+ exports: [exports.FirebaseServerAuthModule, config.serviceProvider.provide],
1223
+ providers: provideFirebaseServerAuthService(config.serviceProvider)
1224
+ }, config);
1254
1225
  }
1255
1226
 
1256
1227
  function assertIsAdminInRequest(request) {
1257
- if (!isAdminInRequest(request)) {
1258
- throw forbiddenError();
1259
- }
1228
+ if (!isAdminInRequest(request)) {
1229
+ throw forbiddenError();
1230
+ }
1260
1231
  }
1261
1232
  function isAdminInRequest(request) {
1262
- return request.nest.authService.context(request).isAdmin;
1233
+ return request.nest.authService.context(request).isAdmin;
1263
1234
  }
1264
1235
  function assertIsAdminOrTargetUserInRequestData(request, requireUid) {
1265
- if (!isAdminOrTargetUserInRequestData(request, requireUid)) {
1266
- throw forbiddenError();
1267
- }
1268
- return request.data.uid ?? request.auth?.uid;
1236
+ if (!isAdminOrTargetUserInRequestData(request, requireUid)) {
1237
+ throw forbiddenError();
1238
+ }
1239
+ return request.data.uid ?? request.auth?.uid;
1269
1240
  }
1270
1241
  function isAdminOrTargetUserInRequestData(request, requireUid = false) {
1271
- const uid = request.data.uid;
1272
- const authUid = request.auth?.uid;
1273
- let isAdminOrTargetUser = true;
1274
- if (requireUid && uid == null || uid != null && uid !== authUid) {
1275
- isAdminOrTargetUser = request.nest.authService.context(request).isAdmin;
1276
- }
1277
- return isAdminOrTargetUser;
1242
+ const uid = request.data.uid;
1243
+ const authUid = request.auth?.uid;
1244
+ let isAdminOrTargetUser = true;
1245
+ if ((requireUid && uid == null) || (uid != null && uid !== authUid)) {
1246
+ isAdminOrTargetUser = request.nest.authService.context(request).isAdmin;
1247
+ }
1248
+ return isAdminOrTargetUser;
1278
1249
  }
1279
1250
  function assertHasSignedTosInRequest(request) {
1280
- if (!hasSignedTosInRequest(request)) {
1281
- throw forbiddenError({
1282
- message: 'ToS has not been signed.'
1283
- });
1284
- }
1251
+ if (!hasSignedTosInRequest(request)) {
1252
+ throw forbiddenError({
1253
+ message: 'ToS has not been signed.'
1254
+ });
1255
+ }
1285
1256
  }
1286
1257
  function hasSignedTosInRequest(request) {
1287
- return request.nest.authService.context(request).hasSignedTos;
1258
+ return request.nest.authService.context(request).hasSignedTos;
1288
1259
  }
1289
1260
  function assertHasRolesInRequest(request, authRoles) {
1290
- if (!hasAuthRolesInRequest(request, authRoles)) {
1291
- throw forbiddenError({
1292
- message: 'Missing required auth roles.',
1293
- data: {
1294
- roles: util.asArray(authRoles)
1295
- }
1296
- });
1297
- }
1261
+ if (!hasAuthRolesInRequest(request, authRoles)) {
1262
+ throw forbiddenError({
1263
+ message: 'Missing required auth roles.',
1264
+ data: {
1265
+ roles: util.asArray(authRoles)
1266
+ }
1267
+ });
1268
+ }
1298
1269
  }
1299
1270
  function hasAuthRolesInRequest(request, authRoles) {
1300
- return util.containsAllValues(request.nest.authService.context(request).authRoles, authRoles);
1271
+ return util.containsAllValues(request.nest.authService.context(request).authRoles, authRoles);
1301
1272
  }
1302
1273
  /**
1303
1274
  * Returns true if the claims have a FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY claims value, indicating they are a newly invited user.
@@ -1307,8 +1278,8 @@ function hasAuthRolesInRequest(request, authRoles) {
1307
1278
  * @param request
1308
1279
  */
1309
1280
  function hasNewUserSetupPasswordInRequest(request) {
1310
- const claims = request.nest.authService.context(request).claims;
1311
- return claims[firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY] != null;
1281
+ const claims = request.nest.authService.context(request).claims;
1282
+ return claims[firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY] != null;
1312
1283
  }
1313
1284
 
1314
1285
  /**
@@ -1318,123 +1289,114 @@ function hasNewUserSetupPasswordInRequest(request) {
1318
1289
  * @returns
1319
1290
  */
1320
1291
  function onCallDevelopmentFunction(map, config = {}) {
1321
- const {
1322
- preAssert = () => undefined
1323
- } = config;
1324
- return request => {
1325
- const specifier = request.data.specifier;
1326
- const devFn = map[specifier];
1327
- if (devFn) {
1328
- preAssert({
1329
- request,
1330
- specifier
1331
- });
1332
- return devFn({
1333
- ...request,
1334
- specifier,
1335
- data: request.data.data
1336
- });
1337
- } else {
1338
- throw developmentUnknownSpecifierError(specifier);
1339
- }
1340
- };
1292
+ const { preAssert = () => undefined } = config;
1293
+ return (request) => {
1294
+ const specifier = request.data.specifier;
1295
+ const devFn = map[specifier];
1296
+ if (devFn) {
1297
+ preAssert({ request, specifier });
1298
+ return devFn({
1299
+ ...request,
1300
+ specifier,
1301
+ data: request.data.data
1302
+ });
1303
+ }
1304
+ else {
1305
+ throw developmentUnknownSpecifierError(specifier);
1306
+ }
1307
+ };
1341
1308
  }
1342
1309
  function developmentUnknownSpecifierError(specifier) {
1343
- return badRequestError(util.serverError({
1344
- status: 400,
1345
- code: 'UNKNOWN_SPECIFIER_ERROR',
1346
- message: `Invalid specifier "${specifier}" to run.`,
1347
- data: {
1348
- specifier
1349
- }
1350
- }));
1310
+ return badRequestError(util.serverError({
1311
+ status: 400,
1312
+ code: 'UNKNOWN_SPECIFIER_ERROR',
1313
+ message: `Invalid specifier "${specifier}" to run.`,
1314
+ data: {
1315
+ specifier
1316
+ }
1317
+ }));
1351
1318
  }
1352
1319
 
1353
1320
  const NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE = 'NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION';
1354
1321
  function noRunNameSpecifiedForScheduledFunctionDevelopmentFunction() {
1355
- return badRequestError({
1356
- code: NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE,
1357
- message: `Must specify run parameter.`
1358
- });
1322
+ return badRequestError({
1323
+ code: NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE,
1324
+ message: `Must specify run parameter.`
1325
+ });
1359
1326
  }
1360
1327
  const UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_NAME_CODE = 'UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_NAME';
1361
1328
  function unknownScheduledFunctionDevelopmentFunctionName(name) {
1362
- return badRequestError({
1363
- code: UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_NAME_CODE,
1364
- message: `Unknown function with name "${name}"`,
1365
- data: {
1366
- name
1367
- }
1368
- });
1329
+ return badRequestError({
1330
+ code: UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_NAME_CODE,
1331
+ message: `Unknown function with name "${name}"`,
1332
+ data: {
1333
+ name
1334
+ }
1335
+ });
1369
1336
  }
1370
1337
  const UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_TYPE_CODE = 'UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_TYPE';
1371
1338
  function unknownScheduledFunctionDevelopmentFunctionType(type) {
1372
- return badRequestError({
1373
- code: UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_TYPE_CODE,
1374
- message: `Unknown type "${type}"`,
1375
- data: {
1376
- type
1377
- }
1378
- });
1339
+ return badRequestError({
1340
+ code: UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_TYPE_CODE,
1341
+ message: `Unknown type "${type}"`,
1342
+ data: {
1343
+ type
1344
+ }
1345
+ });
1379
1346
  }
1380
1347
 
1381
1348
  function makeScheduledFunctionDevelopmentFunction(config) {
1382
- const {
1383
- allScheduledFunctions
1384
- } = config;
1385
- const getListValues = util.cachedGetter(() => {
1386
- const result = [];
1387
- util.forEachKeyValue(allScheduledFunctions, {
1388
- forEach: x => {
1389
- const [functionName, config] = x;
1390
- result.push({
1391
- name: functionName.toString()
1349
+ const { allScheduledFunctions } = config;
1350
+ const getListValues = util.cachedGetter(() => {
1351
+ const result = [];
1352
+ util.forEachKeyValue(allScheduledFunctions, {
1353
+ forEach: (x) => {
1354
+ const [functionName, config] = x;
1355
+ result.push({
1356
+ name: functionName.toString()
1357
+ });
1358
+ }
1392
1359
  });
1393
- }
1360
+ return result;
1394
1361
  });
1395
- return result;
1396
- });
1397
- return async request => {
1398
- const {
1399
- data
1400
- } = request;
1401
- const {
1402
- type
1403
- } = data;
1404
- switch (type) {
1405
- case 'run':
1406
- const targetRunName = data.run;
1407
- if (!targetRunName) {
1408
- throw noRunNameSpecifiedForScheduledFunctionDevelopmentFunction();
1409
- }
1410
- const targetFunction = allScheduledFunctions[targetRunName];
1411
- if (!targetFunction) {
1412
- throw unknownScheduledFunctionDevelopmentFunctionName(targetRunName);
1413
- }
1414
- try {
1415
- await targetFunction._runNow();
1416
- } catch (e) {
1417
- console.error(`Failed manually running task "${targetRunName}".`, e);
1418
- throw e;
1362
+ return async (request) => {
1363
+ const { data } = request;
1364
+ const { type } = data;
1365
+ switch (type) {
1366
+ case 'run':
1367
+ const targetRunName = data.run;
1368
+ if (!targetRunName) {
1369
+ throw noRunNameSpecifiedForScheduledFunctionDevelopmentFunction();
1370
+ }
1371
+ const targetFunction = allScheduledFunctions[targetRunName];
1372
+ if (!targetFunction) {
1373
+ throw unknownScheduledFunctionDevelopmentFunctionName(targetRunName);
1374
+ }
1375
+ try {
1376
+ await targetFunction._runNow();
1377
+ }
1378
+ catch (e) {
1379
+ console.error(`Failed manually running task "${targetRunName}".`, e);
1380
+ throw e;
1381
+ }
1382
+ return {
1383
+ type: 'run',
1384
+ success: true
1385
+ };
1386
+ case 'list':
1387
+ return {
1388
+ type: 'list',
1389
+ list: getListValues()
1390
+ };
1391
+ default:
1392
+ throw unknownScheduledFunctionDevelopmentFunctionType(type);
1419
1393
  }
1420
- return {
1421
- type: 'run',
1422
- success: true
1423
- };
1424
- case 'list':
1425
- return {
1426
- type: 'list',
1427
- list: getListValues()
1428
- };
1429
- default:
1430
- throw unknownScheduledFunctionDevelopmentFunctionType(type);
1431
- }
1432
- };
1394
+ };
1433
1395
  }
1434
1396
 
1435
1397
  function setNestContextOnRequest(makeNestContext, request) {
1436
- request.nest = makeNestContext(request.nestApplication);
1437
- return request;
1398
+ request.nest = makeNestContext(request.nestApplication);
1399
+ return request;
1438
1400
  }
1439
1401
  /**
1440
1402
  * Wraps the input OnCallWithNestContext function to flag it as optional to have auth data.
@@ -1443,9 +1405,9 @@ function setNestContextOnRequest(makeNestContext, request) {
1443
1405
  * @returns
1444
1406
  */
1445
1407
  function optionalAuthContext(fn) {
1446
- const fnWithOptionalAuth = request => fn(request);
1447
- fnWithOptionalAuth._requireAuth = false;
1448
- return fnWithOptionalAuth;
1408
+ const fnWithOptionalAuth = ((request) => fn(request));
1409
+ fnWithOptionalAuth._requireAuth = false;
1410
+ return fnWithOptionalAuth;
1449
1411
  }
1450
1412
  /**
1451
1413
  * Asserts that the input request has auth data if the inputOnCallWithAuthAwareNestRequireAuthRef object is flagged to require auth.
@@ -1454,9 +1416,9 @@ function optionalAuthContext(fn) {
1454
1416
  * @param request
1455
1417
  */
1456
1418
  function assertRequestRequiresAuthForFunction(fn, request) {
1457
- if (fn._requireAuth !== false) {
1458
- assertIsContextWithAuthData(request);
1459
- }
1419
+ if (fn._requireAuth !== false) {
1420
+ assertIsContextWithAuthData(request);
1421
+ }
1460
1422
  }
1461
1423
  /**
1462
1424
  * Creates an OnCallWithNestContext wrapper that validates the input CallableContext to assert the context has auth data before entering the function.
@@ -1465,64 +1427,59 @@ function assertRequestRequiresAuthForFunction(fn, request) {
1465
1427
  * @returns
1466
1428
  */
1467
1429
  function inAuthContext(fn) {
1468
- return request => {
1469
- assertIsContextWithAuthData(request);
1470
- return fn(request);
1471
- };
1430
+ return (request) => {
1431
+ assertIsContextWithAuthData(request);
1432
+ return fn(request);
1433
+ };
1472
1434
  }
1473
1435
 
1474
1436
  function firebaseServerDevFunctions(config) {
1475
- const {
1476
- enabled,
1477
- secure,
1478
- nest,
1479
- developerFunctionsMap,
1480
- onCallFactory,
1481
- allScheduledFunctions,
1482
- disableDevelopmentScheduleFunction
1483
- } = config;
1484
- let dev;
1485
- if (enabled) {
1486
- const fullFunctionsMap = {
1487
- ...developerFunctionsMap
1437
+ const { enabled, secure, nest, developerFunctionsMap, onCallFactory, allScheduledFunctions, disableDevelopmentScheduleFunction } = config;
1438
+ let dev;
1439
+ if (enabled) {
1440
+ const fullFunctionsMap = {
1441
+ ...developerFunctionsMap
1442
+ };
1443
+ if (allScheduledFunctions && disableDevelopmentScheduleFunction !== false) {
1444
+ fullFunctionsMap[firebase.SCHEDULED_FUNCTION_DEV_FUNCTION_SPECIFIER] = makeScheduledFunctionDevelopmentFunction({
1445
+ allScheduledFunctions
1446
+ });
1447
+ }
1448
+ let onCallFunction = onCallDevelopmentFunction(fullFunctionsMap);
1449
+ if (secure != false) {
1450
+ onCallFunction = inAuthContext(onCallFunction);
1451
+ }
1452
+ dev = onCallFactory(onCallFunction)(nest);
1453
+ }
1454
+ else {
1455
+ dev = onCallFactory(async (x) => {
1456
+ throw unavailableError({
1457
+ message: 'developer tools service is not enabled.'
1458
+ });
1459
+ })(nest);
1460
+ }
1461
+ return {
1462
+ dev
1488
1463
  };
1489
- if (allScheduledFunctions && disableDevelopmentScheduleFunction !== false) {
1490
- fullFunctionsMap[firebase.SCHEDULED_FUNCTION_DEV_FUNCTION_SPECIFIER] = makeScheduledFunctionDevelopmentFunction({
1491
- allScheduledFunctions
1492
- });
1493
- }
1494
- let onCallFunction = onCallDevelopmentFunction(fullFunctionsMap);
1495
- if (secure != false) {
1496
- onCallFunction = inAuthContext(onCallFunction);
1497
- }
1498
- dev = onCallFactory(onCallFunction)(nest);
1499
- } else {
1500
- dev = onCallFactory(async x => {
1501
- throw unavailableError({
1502
- message: 'developer tools service is not enabled.'
1503
- });
1504
- })(nest);
1505
- }
1506
- return {
1507
- dev
1508
- };
1509
1464
  }
1510
1465
 
1511
1466
  exports.DefaultFirebaseServerEnvService = class DefaultFirebaseServerEnvService extends nestjs.ServerEnvironmentService {
1512
- /**
1513
- * Enabled when not in production and not in a testing environment.
1514
- */
1515
- get developmentSchedulerEnabled() {
1516
- return !this.isProduction && !this.isTestingEnv;
1517
- }
1467
+ /**
1468
+ * Enabled when not in production and not in a testing environment.
1469
+ */
1470
+ get developmentSchedulerEnabled() {
1471
+ return !this.isProduction && !this.isTestingEnv;
1472
+ }
1518
1473
  };
1519
- exports.DefaultFirebaseServerEnvService = __decorate([common.Injectable()], exports.DefaultFirebaseServerEnvService);
1474
+ exports.DefaultFirebaseServerEnvService = __decorate([
1475
+ common.Injectable()
1476
+ ], exports.DefaultFirebaseServerEnvService);
1520
1477
 
1521
1478
  function nestAppIsProductionEnvironment(nest) {
1522
- return () => nest().then(x => x.get(FirebaseServerEnvService).isProduction);
1479
+ return () => nest().then((x) => x.get(FirebaseServerEnvService).isProduction);
1523
1480
  }
1524
1481
  function nestAppHasDevelopmentSchedulerEnabled(nest) {
1525
- return () => nest().then(x => x.get(FirebaseServerEnvService).developmentSchedulerEnabled);
1482
+ return () => nest().then((x) => x.get(FirebaseServerEnvService).developmentSchedulerEnabled);
1526
1483
  }
1527
1484
 
1528
1485
  // MARK: Tokens
@@ -1537,28 +1494,38 @@ const FIREBASE_FIRESTORE_CONTEXT_TOKEN = 'FIREBASE_FIRESTORE_CONTEXT_TOKEN';
1537
1494
  /**
1538
1495
  * Nest provider module for Firebase that provides a firestore, etc. from the firestore token.
1539
1496
  */
1540
- exports.FirebaseServerFirestoreModule = class FirebaseServerFirestoreModule {};
1541
- exports.FirebaseServerFirestoreModule = __decorate([common.Module({
1542
- providers: [{
1543
- provide: FIREBASE_FIRESTORE_TOKEN,
1544
- useFactory: app => app.firestore(),
1545
- inject: [FIREBASE_APP_TOKEN]
1546
- }],
1547
- exports: [FIREBASE_FIRESTORE_TOKEN]
1548
- })], exports.FirebaseServerFirestoreModule);
1497
+ exports.FirebaseServerFirestoreModule = class FirebaseServerFirestoreModule {
1498
+ };
1499
+ exports.FirebaseServerFirestoreModule = __decorate([
1500
+ common.Module({
1501
+ providers: [
1502
+ {
1503
+ provide: FIREBASE_FIRESTORE_TOKEN,
1504
+ useFactory: (app) => app.firestore(),
1505
+ inject: [FIREBASE_APP_TOKEN]
1506
+ }
1507
+ ],
1508
+ exports: [FIREBASE_FIRESTORE_TOKEN]
1509
+ })
1510
+ ], exports.FirebaseServerFirestoreModule);
1549
1511
  /**
1550
1512
  * Nest provider module for firebase that includes the FirebaseServerFirestoreModule and provides a value for FIRESTORE_CONTEXT_TOKEN using the googleCloudFirestoreContextFactory.
1551
1513
  */
1552
- exports.FirebaseServerFirestoreContextModule = class FirebaseServerFirestoreContextModule {};
1553
- exports.FirebaseServerFirestoreContextModule = __decorate([common.Module({
1554
- imports: [exports.FirebaseServerFirestoreModule],
1555
- providers: [{
1556
- provide: FIREBASE_FIRESTORE_CONTEXT_TOKEN,
1557
- useFactory: googleCloudFirestoreContextFactory,
1558
- inject: [FIREBASE_FIRESTORE_TOKEN]
1559
- }],
1560
- exports: [exports.FirebaseServerFirestoreModule, FIREBASE_FIRESTORE_CONTEXT_TOKEN]
1561
- })], exports.FirebaseServerFirestoreContextModule);
1514
+ exports.FirebaseServerFirestoreContextModule = class FirebaseServerFirestoreContextModule {
1515
+ };
1516
+ exports.FirebaseServerFirestoreContextModule = __decorate([
1517
+ common.Module({
1518
+ imports: [exports.FirebaseServerFirestoreModule],
1519
+ providers: [
1520
+ {
1521
+ provide: FIREBASE_FIRESTORE_CONTEXT_TOKEN,
1522
+ useFactory: googleCloudFirestoreContextFactory,
1523
+ inject: [FIREBASE_FIRESTORE_TOKEN]
1524
+ }
1525
+ ],
1526
+ exports: [exports.FirebaseServerFirestoreModule, FIREBASE_FIRESTORE_CONTEXT_TOKEN]
1527
+ })
1528
+ ], exports.FirebaseServerFirestoreContextModule);
1562
1529
  /**
1563
1530
  * Used to configure a Nestjs provider for a FirestoreCollections-type object that is initialized with a FirestoreContext.
1564
1531
  *
@@ -1566,15 +1533,14 @@ exports.FirebaseServerFirestoreContextModule = __decorate([common.Module({
1566
1533
  * @param useFactory
1567
1534
  * @returns
1568
1535
  */
1569
- function provideAppFirestoreCollections({
1570
- provide,
1571
- useFactory
1572
- }) {
1573
- return [{
1574
- provide,
1575
- useFactory,
1576
- inject: [FIREBASE_FIRESTORE_CONTEXT_TOKEN]
1577
- }];
1536
+ function provideAppFirestoreCollections({ provide, useFactory }) {
1537
+ return [
1538
+ {
1539
+ provide,
1540
+ useFactory,
1541
+ inject: [FIREBASE_FIRESTORE_CONTEXT_TOKEN]
1542
+ }
1543
+ ];
1578
1544
  }
1579
1545
  /**
1580
1546
  * Convenience function used to generate ModuleMetadata for an app's Firestore related modules and an appFirestoreCollection
@@ -1584,11 +1550,11 @@ function provideAppFirestoreCollections({
1584
1550
  * @returns
1585
1551
  */
1586
1552
  function appFirestoreModuleMetadata(config) {
1587
- return {
1588
- imports: [exports.FirebaseServerFirestoreContextModule, ...(config.imports ?? [])],
1589
- exports: [exports.FirebaseServerFirestoreContextModule, config.provide, ...(config.exports ?? [])],
1590
- providers: [...provideAppFirestoreCollections(config), ...(config.providers ?? [])]
1591
- };
1553
+ return {
1554
+ imports: [exports.FirebaseServerFirestoreContextModule, ...(config.imports ?? [])],
1555
+ exports: [exports.FirebaseServerFirestoreContextModule, config.provide, ...(config.exports ?? [])],
1556
+ providers: [...provideAppFirestoreCollections(config), ...(config.providers ?? [])]
1557
+ };
1592
1558
  }
1593
1559
 
1594
1560
  /**
@@ -1599,9 +1565,9 @@ function appFirestoreModuleMetadata(config) {
1599
1565
  * @returns
1600
1566
  */
1601
1567
  function makeBlockingFunctionWithHandler(blockingFunctionBuilder, handler, opts) {
1602
- const blockingFn = opts != null ? blockingFunctionBuilder(opts, handler) : blockingFunctionBuilder(handler);
1603
- blockingFn.__handler = handler;
1604
- return blockingFn;
1568
+ const blockingFn = opts != null ? blockingFunctionBuilder(opts, handler) : blockingFunctionBuilder(handler);
1569
+ blockingFn.__handler = handler;
1570
+ return blockingFn;
1605
1571
  }
1606
1572
  /**
1607
1573
  * Creates a BlockingFunctionHandlerWithNestContextFactory.
@@ -1611,18 +1577,18 @@ function makeBlockingFunctionWithHandler(blockingFunctionBuilder, handler, opts)
1611
1577
  * @returns
1612
1578
  */
1613
1579
  function blockingFunctionHandlerWithNestContextFactory(makeNestContext) {
1614
- return fn => {
1615
- return nestAppPromiseGetter => {
1616
- const handlerBuilder = handler => {
1617
- const fnHandler = event => nestAppPromiseGetter().then(nestApplication => handler({
1618
- ...event,
1619
- nest: makeNestContext(nestApplication)
1620
- }));
1621
- return fnHandler;
1622
- };
1623
- return fn(handlerBuilder);
1580
+ return (fn) => {
1581
+ return (nestAppPromiseGetter) => {
1582
+ const handlerBuilder = (handler) => {
1583
+ const fnHandler = (event) => nestAppPromiseGetter().then((nestApplication) => handler({
1584
+ ...event,
1585
+ nest: makeNestContext(nestApplication)
1586
+ }));
1587
+ return fnHandler;
1588
+ };
1589
+ return fn(handlerBuilder);
1590
+ };
1624
1591
  };
1625
- };
1626
1592
  }
1627
1593
 
1628
1594
  /**
@@ -1632,15 +1598,12 @@ function blockingFunctionHandlerWithNestContextFactory(makeNestContext) {
1632
1598
  * @returns
1633
1599
  */
1634
1600
  function onCallHandlerWithNestApplicationFactory(defaultOpts = {}) {
1635
- return (fn, opts) => {
1636
- return nestAppPromiseGetter => v2.https.onCall({
1637
- ...defaultOpts,
1638
- ...opts
1639
- }, request => nestAppPromiseGetter().then(nestApplication => fn({
1640
- ...request,
1641
- nestApplication
1642
- })));
1643
- };
1601
+ return (fn, opts) => {
1602
+ return (nestAppPromiseGetter) => v2.https.onCall({ ...defaultOpts, ...opts }, (request) => nestAppPromiseGetter().then((nestApplication) => fn({
1603
+ ...request,
1604
+ nestApplication
1605
+ })));
1606
+ };
1644
1607
  }
1645
1608
  /**
1646
1609
  * Creates a factory for generating OnCallWithNestContext functions with a nest context object that is generated by the input function.
@@ -1650,7 +1613,7 @@ function onCallHandlerWithNestApplicationFactory(defaultOpts = {}) {
1650
1613
  * @returns
1651
1614
  */
1652
1615
  function onCallHandlerWithNestContextFactory(appFactory, makeNestContext) {
1653
- return (fn, opts) => appFactory(request => fn(setNestContextOnRequest(makeNestContext, request)), opts);
1616
+ return (fn, opts) => appFactory((request) => fn(setNestContextOnRequest(makeNestContext, request)), opts);
1654
1617
  }
1655
1618
 
1656
1619
  /**
@@ -1661,30 +1624,30 @@ function onCallHandlerWithNestContextFactory(appFactory, makeNestContext) {
1661
1624
  * @returns
1662
1625
  */
1663
1626
  function cloudEventHandlerWithNestContextFactory(makeNestContext) {
1664
- return fn => {
1665
- return nestAppPromiseGetter => {
1666
- const handlerBuilder = handler => {
1667
- const fnHandler = event => nestAppPromiseGetter().then(nestApplication => handler({
1668
- ...event,
1669
- nest: makeNestContext(nestApplication)
1670
- }));
1671
- return fnHandler;
1672
- };
1673
- return fn(handlerBuilder);
1627
+ return (fn) => {
1628
+ return (nestAppPromiseGetter) => {
1629
+ const handlerBuilder = (handler) => {
1630
+ const fnHandler = (event) => nestAppPromiseGetter().then((nestApplication) => handler({
1631
+ ...event,
1632
+ nest: makeNestContext(nestApplication)
1633
+ }));
1634
+ return fnHandler;
1635
+ };
1636
+ return fn(handlerBuilder);
1637
+ };
1674
1638
  };
1675
- };
1676
1639
  }
1677
1640
 
1678
1641
  function setNestContextOnScheduleRequest(makeNestContext, request) {
1679
- request.nest = makeNestContext(request.nestApplication);
1680
- return request;
1642
+ request.nest = makeNestContext(request.nestApplication);
1643
+ return request;
1681
1644
  }
1682
1645
 
1683
1646
  function makeOnScheduleHandlerWithNestApplicationRequest(nestApplication, scheduleContext) {
1684
- return {
1685
- nestApplication,
1686
- scheduleContext
1687
- };
1647
+ return {
1648
+ nestApplication,
1649
+ scheduleContext
1650
+ };
1688
1651
  }
1689
1652
  /**
1690
1653
  * Creates a factory for generating OnCallWithNestApplication functions.
@@ -1693,27 +1656,29 @@ function makeOnScheduleHandlerWithNestApplicationRequest(nestApplication, schedu
1693
1656
  * @returns
1694
1657
  */
1695
1658
  function onScheduleHandlerWithNestApplicationFactory(baseScheduleConfig) {
1696
- return (inputSchedule, fn) => {
1697
- const schedule = util.mergeObjects([baseScheduleConfig, inputSchedule]);
1698
- if (!schedule.schedule) {
1699
- if (schedule.cron) {
1700
- if (typeof schedule.cron === 'number') {
1701
- schedule.schedule = util.cronExpressionRepeatingEveryNMinutes(schedule.cron);
1702
- } else {
1703
- schedule.schedule = schedule.cron;
1704
- }
1705
- } else {
1706
- throw new Error('Missing required "cron" or "schedule" variable for configuration.');
1707
- }
1708
- }
1709
- return nestAppPromiseGetter => {
1710
- const runNow = scheduleContext => nestAppPromiseGetter().then(x => fn(makeOnScheduleHandlerWithNestApplicationRequest(x, scheduleContext)));
1711
- const fnn = v2.scheduler.onSchedule(schedule, runNow);
1712
- fnn._schedule = schedule;
1713
- fnn._runNow = runNow;
1714
- return fnn;
1659
+ return (inputSchedule, fn) => {
1660
+ const schedule = util.mergeObjects([baseScheduleConfig, inputSchedule]);
1661
+ if (!schedule.schedule) {
1662
+ if (schedule.cron) {
1663
+ if (typeof schedule.cron === 'number') {
1664
+ schedule.schedule = util.cronExpressionRepeatingEveryNMinutes(schedule.cron);
1665
+ }
1666
+ else {
1667
+ schedule.schedule = schedule.cron;
1668
+ }
1669
+ }
1670
+ else {
1671
+ throw new Error('Missing required "cron" or "schedule" variable for configuration.');
1672
+ }
1673
+ }
1674
+ return (nestAppPromiseGetter) => {
1675
+ const runNow = (scheduleContext) => nestAppPromiseGetter().then((x) => fn(makeOnScheduleHandlerWithNestApplicationRequest(x, scheduleContext)));
1676
+ const fnn = v2.scheduler.onSchedule(schedule, runNow);
1677
+ fnn._schedule = schedule;
1678
+ fnn._runNow = runNow;
1679
+ return fnn;
1680
+ };
1715
1681
  };
1716
- };
1717
1682
  }
1718
1683
  /**
1719
1684
  * Creates a factory for generating OnCallWithNestContext functions with a nest context object that is generated by the input function.
@@ -1723,7 +1688,7 @@ function onScheduleHandlerWithNestApplicationFactory(baseScheduleConfig) {
1723
1688
  * @returns
1724
1689
  */
1725
1690
  function onScheduleHandlerWithNestContextFactory(appFactory, makeNestContext) {
1726
- return (schedule, fn) => appFactory(schedule, request => fn(setNestContextOnScheduleRequest(makeNestContext, request)));
1691
+ return (schedule, fn) => appFactory(schedule, (request) => fn(setNestContextOnScheduleRequest(makeNestContext, request)));
1727
1692
  }
1728
1693
 
1729
1694
  /**
@@ -1734,37 +1699,38 @@ function onScheduleHandlerWithNestContextFactory(appFactory, makeNestContext) {
1734
1699
  * @returns
1735
1700
  */
1736
1701
  function taskQueueFunctionHandlerWithNestContextFactory(makeNestContext) {
1737
- return fn => {
1738
- return nestAppPromiseGetter => {
1739
- const handlerBuilder = handler => {
1740
- const fnHandler = taskRequest => nestAppPromiseGetter().then(nestApplication => handler({
1741
- ...taskRequest,
1742
- nest: makeNestContext(nestApplication)
1743
- }));
1744
- return fnHandler;
1745
- };
1746
- return fn(handlerBuilder);
1702
+ return (fn) => {
1703
+ return (nestAppPromiseGetter) => {
1704
+ const handlerBuilder = (handler) => {
1705
+ const fnHandler = (taskRequest) => nestAppPromiseGetter().then((nestApplication) => handler({
1706
+ ...taskRequest,
1707
+ nest: makeNestContext(nestApplication)
1708
+ }));
1709
+ return fnHandler;
1710
+ };
1711
+ return fn(handlerBuilder);
1712
+ };
1747
1713
  };
1748
- };
1749
1714
  }
1750
1715
  // TODO(FUTURE): Add factory that also adds onTaskDispatched usage, as the above is incomplete for full usage and only sets up a function for the request.
1751
1716
 
1752
- class AbstractFirebaseServerActionsContext {}
1717
+ class AbstractFirebaseServerActionsContext {
1718
+ }
1753
1719
  function firebaseServerActionsContext(options) {
1754
- return {
1755
- ...firebaseServerActionsTransformContext(options)
1756
- };
1720
+ return {
1721
+ ...firebaseServerActionsTransformContext(options)
1722
+ };
1757
1723
  }
1758
- const defaultFirebaseServerActionsTransformFactoryLogErrorFunction = details => {
1759
- console.log('firebaseServerActionsTransformFactory() encountered validation error: ', details);
1724
+ const defaultFirebaseServerActionsTransformFactoryLogErrorFunction = (details) => {
1725
+ console.log('firebaseServerActionsTransformFactory() encountered validation error: ', details);
1760
1726
  };
1761
1727
  function firebaseServerActionsTransformContext(options) {
1762
- const firebaseServerActionTransformFactory = firebaseServerActionsTransformFactory(options);
1763
- const firebaseServerActionTransformFunctionFactory = model.toTransformAndValidateFunctionResultFactory(firebaseServerActionTransformFactory);
1764
- return {
1765
- firebaseServerActionTransformFactory,
1766
- firebaseServerActionTransformFunctionFactory
1767
- };
1728
+ const firebaseServerActionTransformFactory = firebaseServerActionsTransformFactory(options);
1729
+ const firebaseServerActionTransformFunctionFactory = model.toTransformAndValidateFunctionResultFactory(firebaseServerActionTransformFactory);
1730
+ return {
1731
+ firebaseServerActionTransformFactory,
1732
+ firebaseServerActionTransformFunctionFactory
1733
+ };
1768
1734
  }
1769
1735
  const FIREBASE_SERVER_VALIDATION_ERROR_CODE = 'VALIDATION_ERROR';
1770
1736
  /**
@@ -1773,16 +1739,16 @@ const FIREBASE_SERVER_VALIDATION_ERROR_CODE = 'VALIDATION_ERROR';
1773
1739
  * @returns
1774
1740
  */
1775
1741
  function firebaseServerValidationServerError(validationError) {
1776
- const nestValidationExceptionFactory = new common.ValidationPipe({
1777
- forbidUnknownValues: false
1778
- }).createExceptionFactory();
1779
- const nestError = nestValidationExceptionFactory(validationError);
1780
- const data = nestError.getResponse();
1781
- return {
1782
- message: 'One or more data/form validation errors occurred.',
1783
- code: FIREBASE_SERVER_VALIDATION_ERROR_CODE,
1784
- data
1785
- };
1742
+ const nestValidationExceptionFactory = new common.ValidationPipe({
1743
+ forbidUnknownValues: false
1744
+ }).createExceptionFactory();
1745
+ const nestError = nestValidationExceptionFactory(validationError);
1746
+ const data = nestError.getResponse();
1747
+ return {
1748
+ message: 'One or more data/form validation errors occurred.',
1749
+ code: FIREBASE_SERVER_VALIDATION_ERROR_CODE,
1750
+ data
1751
+ };
1786
1752
  }
1787
1753
  /**
1788
1754
  * Creates a new badRequestError with the validation error details as the response data.
@@ -1791,48 +1757,41 @@ function firebaseServerValidationServerError(validationError) {
1791
1757
  * @returns
1792
1758
  */
1793
1759
  function firebaseServerValidationError(validationError) {
1794
- const serverError = firebaseServerValidationServerError(validationError);
1795
- return badRequestError(serverError);
1760
+ const serverError = firebaseServerValidationServerError(validationError);
1761
+ return badRequestError(serverError);
1796
1762
  }
1797
1763
  function firebaseServerActionsTransformFactory(options) {
1798
- const {
1799
- logError,
1800
- defaultValidationOptions
1801
- } = options ?? {};
1802
- const logErrorFunction = logError !== false ? typeof logError === 'function' ? logError : defaultFirebaseServerActionsTransformFactoryLogErrorFunction : util.mapIdentityFunction;
1803
- return model.transformAndValidateObjectFactory({
1804
- handleValidationError: validationError => {
1805
- const serverError = firebaseServerValidationServerError(validationError);
1806
- const {
1807
- data
1808
- } = serverError;
1809
- logErrorFunction(data);
1810
- throw badRequestError(serverError);
1811
- },
1812
- defaultValidationOptions
1813
- });
1764
+ const { logError, defaultValidationOptions } = options ?? {};
1765
+ const logErrorFunction = logError !== false ? (typeof logError === 'function' ? logError : defaultFirebaseServerActionsTransformFactoryLogErrorFunction) : util.mapIdentityFunction;
1766
+ return model.transformAndValidateObjectFactory({
1767
+ handleValidationError: (validationError) => {
1768
+ const serverError = firebaseServerValidationServerError(validationError);
1769
+ const { data } = serverError;
1770
+ logErrorFunction(data);
1771
+ throw badRequestError(serverError);
1772
+ },
1773
+ defaultValidationOptions
1774
+ });
1814
1775
  }
1815
1776
 
1816
1777
  function injectNestIntoRequest(nest, request) {
1817
- return {
1818
- ...request,
1819
- nest
1820
- };
1778
+ return {
1779
+ ...request,
1780
+ nest
1781
+ };
1821
1782
  }
1822
1783
  function injectNestApplicationContextIntoRequest(nestContext, request) {
1823
- return {
1824
- ...request,
1825
- nestApplication: nestContext
1826
- };
1784
+ return {
1785
+ ...request,
1786
+ nestApplication: nestContext
1787
+ };
1827
1788
  }
1828
1789
 
1829
1790
  /**
1830
1791
  * Can be injected to retrieve information about the global prefix configured for the app.
1831
1792
  */
1832
1793
  class GlobalRoutePrefixConfig {
1833
- constructor() {
1834
- this.globalApiRoutePrefix = void 0;
1835
- }
1794
+ globalApiRoutePrefix;
1836
1795
  }
1837
1796
 
1838
1797
  /**
@@ -1841,33 +1800,38 @@ class GlobalRoutePrefixConfig {
1841
1800
  * It ignores all webhook paths by default.
1842
1801
  */
1843
1802
  exports.FirebaseAppCheckMiddleware = class FirebaseAppCheckMiddleware {
1844
- constructor(globalRoutePrefixConfig) {
1845
- this.globalRoutePrefixConfig = void 0;
1846
- this.logger = new common.Logger('FirebaseAppCheckMiddleware');
1847
- this._ignoredWebhookPath = void 0;
1848
- this.globalRoutePrefixConfig = globalRoutePrefixConfig;
1849
- this._ignoredWebhookPath = this.globalRoutePrefixConfig?.globalApiRoutePrefix ? `${this.globalRoutePrefixConfig.globalApiRoutePrefix}${nestjs.DEFAULT_BASE_WEBHOOK_PATH}` : nestjs.DEFAULT_BASE_WEBHOOK_PATH;
1850
- }
1851
- async use(req, res, next) {
1852
- const isIgnoredRoute = this.isIgnoredRequest(req);
1853
- let error;
1854
- if (!isIgnoredRoute) {
1855
- error = await verifyAppCheckInRequest(req);
1856
- if (error) {
1857
- this.logger.error('app check token failed verify');
1858
- }
1859
- }
1860
- next(error);
1861
- }
1862
- isIgnoredRequest(req) {
1863
- const isIgnoredRoute = req.skipAppCheck || this.isIgnoredPath(req.baseUrl);
1864
- return isIgnoredRoute;
1865
- }
1866
- isIgnoredPath(path) {
1867
- return path.startsWith(this._ignoredWebhookPath);
1868
- }
1803
+ globalRoutePrefixConfig;
1804
+ logger = new common.Logger('FirebaseAppCheckMiddleware');
1805
+ _ignoredWebhookPath;
1806
+ constructor(globalRoutePrefixConfig) {
1807
+ this.globalRoutePrefixConfig = globalRoutePrefixConfig;
1808
+ this._ignoredWebhookPath = this.globalRoutePrefixConfig?.globalApiRoutePrefix ? `${this.globalRoutePrefixConfig.globalApiRoutePrefix}${nestjs.DEFAULT_BASE_WEBHOOK_PATH}` : nestjs.DEFAULT_BASE_WEBHOOK_PATH;
1809
+ }
1810
+ async use(req, res, next) {
1811
+ const isIgnoredRoute = this.isIgnoredRequest(req);
1812
+ let error;
1813
+ if (!isIgnoredRoute) {
1814
+ error = await verifyAppCheckInRequest(req);
1815
+ if (error) {
1816
+ this.logger.error('app check token failed verify');
1817
+ }
1818
+ }
1819
+ next(error);
1820
+ }
1821
+ isIgnoredRequest(req) {
1822
+ const isIgnoredRoute = req.skipAppCheck || this.isIgnoredPath(req.baseUrl);
1823
+ return isIgnoredRoute;
1824
+ }
1825
+ isIgnoredPath(path) {
1826
+ return path.startsWith(this._ignoredWebhookPath);
1827
+ }
1869
1828
  };
1870
- exports.FirebaseAppCheckMiddleware = __decorate([common.Injectable(), __param(0, common.Optional()), __param(0, common.Inject(GlobalRoutePrefixConfig)), __metadata("design:paramtypes", [Object])], exports.FirebaseAppCheckMiddleware);
1829
+ exports.FirebaseAppCheckMiddleware = __decorate([
1830
+ common.Injectable(),
1831
+ __param(0, common.Optional()),
1832
+ __param(0, common.Inject(GlobalRoutePrefixConfig)),
1833
+ __metadata("design:paramtypes", [Object])
1834
+ ], exports.FirebaseAppCheckMiddleware);
1871
1835
  /**
1872
1836
  * Verifies the AppCheck parameter. If it fails, a value is returned.
1873
1837
  *
@@ -1877,50 +1841,54 @@ exports.FirebaseAppCheckMiddleware = __decorate([common.Injectable(), __param(0,
1877
1841
  * @returns
1878
1842
  */
1879
1843
  async function verifyAppCheckInRequest(req) {
1880
- const appCheckToken = req.header('X-Firebase-AppCheck');
1881
- let error;
1882
- if (!appCheckToken) {
1883
- error = new common.ForbiddenException();
1884
- } else {
1885
- // verify the token
1886
- try {
1887
- await admin.appCheck().verifyToken(appCheckToken);
1888
- } catch (e) {
1889
- error = new common.ForbiddenException();
1844
+ const appCheckToken = req.header('X-Firebase-AppCheck');
1845
+ let error;
1846
+ if (!appCheckToken) {
1847
+ error = new common.ForbiddenException();
1890
1848
  }
1891
- }
1892
- return error;
1849
+ else {
1850
+ // verify the token
1851
+ try {
1852
+ await admin.appCheck().verifyToken(appCheckToken);
1853
+ }
1854
+ catch (e) {
1855
+ error = new common.ForbiddenException();
1856
+ }
1857
+ }
1858
+ return error;
1893
1859
  }
1894
1860
 
1895
1861
  /**
1896
1862
  * Convenience class that mirrors the ConfigureAppCheckMiddlewareModule class in @dereekb/nestjs, but for Firebase apps.
1897
1863
  */
1898
1864
  exports.ConfigureFirebaseAppCheckMiddlewareModule = class ConfigureFirebaseAppCheckMiddlewareModule {
1899
- constructor() {
1900
- this.logger = new common.Logger('ConfigureFirebaseAppCheckMiddlewareModule');
1901
- }
1902
- configure(consumer) {
1903
- consumer.apply(exports.FirebaseAppCheckMiddleware).forRoutes('*');
1904
- this.logger.debug('Configured firebase webhook routes with proper middleware.');
1905
- }
1865
+ logger = new common.Logger('ConfigureFirebaseAppCheckMiddlewareModule');
1866
+ configure(consumer) {
1867
+ consumer.apply(exports.FirebaseAppCheckMiddleware).forRoutes('*');
1868
+ this.logger.debug('Configured firebase webhook routes with proper middleware.');
1869
+ }
1906
1870
  };
1907
- exports.ConfigureFirebaseAppCheckMiddlewareModule = __decorate([common.Module({})], exports.ConfigureFirebaseAppCheckMiddlewareModule);
1871
+ exports.ConfigureFirebaseAppCheckMiddlewareModule = __decorate([
1872
+ common.Module({})
1873
+ ], exports.ConfigureFirebaseAppCheckMiddlewareModule);
1908
1874
 
1909
1875
  /**
1910
1876
  * nestjs decorator that will instruct FirebaseAppCheckMiddleware to skip AppCheck for related requests.
1911
1877
  */
1912
1878
  const SkipAppCheck = common.createParamDecorator(async (_, context) => {
1913
- const req = context.switchToHttp().getRequest();
1914
- req.skipAppCheck = true;
1879
+ const req = context.switchToHttp().getRequest();
1880
+ req.skipAppCheck = true;
1915
1881
  });
1916
1882
 
1917
1883
  exports.FirebaseRawBodyMiddleware = class FirebaseRawBodyMiddleware {
1918
- use(req, res, next) {
1919
- req.body = req.rawBody;
1920
- next();
1921
- }
1884
+ use(req, res, next) {
1885
+ req.body = req.rawBody;
1886
+ next();
1887
+ }
1922
1888
  };
1923
- exports.FirebaseRawBodyMiddleware = __decorate([common.Injectable()], exports.FirebaseRawBodyMiddleware);
1889
+ exports.FirebaseRawBodyMiddleware = __decorate([
1890
+ common.Injectable()
1891
+ ], exports.FirebaseRawBodyMiddleware);
1924
1892
 
1925
1893
  /**
1926
1894
  * Convenience class that mirrors the ConfigureWebhookMiddlewareModule class in @dereekb/nestjs, but for Firebase apps.
@@ -1928,60 +1896,59 @@ exports.FirebaseRawBodyMiddleware = __decorate([common.Injectable()], exports.Fi
1928
1896
  * Requests to /webhook/* have their request.body value set to the rawBody.
1929
1897
  */
1930
1898
  exports.ConfigureFirebaseWebhookMiddlewareModule = class ConfigureFirebaseWebhookMiddlewareModule {
1931
- constructor() {
1932
- this.logger = new common.Logger('ConfigureFirebaseWebhookMiddlewareModule');
1933
- }
1934
- configure(consumer) {
1935
- consumer.apply(exports.FirebaseRawBodyMiddleware).forRoutes(nestjs.DEFAULT_WEBHOOK_MIDDLEWARE_ROUTE_INFO);
1936
- this.logger.debug('Configured firebase webhook routes with proper middleware.');
1937
- }
1899
+ logger = new common.Logger('ConfigureFirebaseWebhookMiddlewareModule');
1900
+ configure(consumer) {
1901
+ consumer.apply(exports.FirebaseRawBodyMiddleware).forRoutes(nestjs.DEFAULT_WEBHOOK_MIDDLEWARE_ROUTE_INFO);
1902
+ this.logger.debug('Configured firebase webhook routes with proper middleware.');
1903
+ }
1938
1904
  };
1939
- exports.ConfigureFirebaseWebhookMiddlewareModule = __decorate([common.Module({})], exports.ConfigureFirebaseWebhookMiddlewareModule);
1905
+ exports.ConfigureFirebaseWebhookMiddlewareModule = __decorate([
1906
+ common.Module({})
1907
+ ], exports.ConfigureFirebaseWebhookMiddlewareModule);
1940
1908
 
1941
- const nestFirebaseDoesNotExistError = firebaseContextGrantedModelRoles => {
1942
- return modelNotAvailableError({
1943
- data: {
1944
- id: firebaseContextGrantedModelRoles.data?.document.key,
1945
- type: firebaseContextGrantedModelRoles.data?.document.modelType
1946
- }
1947
- });
1909
+ const nestFirebaseDoesNotExistError = (firebaseContextGrantedModelRoles) => {
1910
+ return modelNotAvailableError({
1911
+ data: {
1912
+ id: firebaseContextGrantedModelRoles.data?.document.key,
1913
+ type: firebaseContextGrantedModelRoles.data?.document.modelType
1914
+ }
1915
+ });
1948
1916
  };
1949
1917
  const nestFirebaseForbiddenPermissionError = (firebaseContextGrantedModelRoles, roles) => {
1950
- return forbiddenError({
1951
- data: {
1952
- id: firebaseContextGrantedModelRoles.data?.document.key,
1953
- type: firebaseContextGrantedModelRoles.data?.document.modelType,
1954
- roles
1955
- }
1956
- });
1918
+ return forbiddenError({
1919
+ data: {
1920
+ id: firebaseContextGrantedModelRoles.data?.document.key,
1921
+ type: firebaseContextGrantedModelRoles.data?.document.modelType,
1922
+ roles
1923
+ }
1924
+ });
1957
1925
  };
1958
1926
 
1959
1927
  function onCallSpecifierHandler(config) {
1960
- const map = util.objectToMap(config);
1961
- const fn = request => {
1962
- const {
1963
- specifier = firebase.MODEL_FUNCTION_FIREBASE_CRUD_FUNCTION_SPECIFIER_DEFAULT
1964
- } = request;
1965
- const handler = map.get(specifier);
1966
- if (handler != null) {
1967
- assertRequestRequiresAuthForFunction(handler, request);
1968
- return handler(request);
1969
- } else {
1970
- throw unknownModelCrudFunctionSpecifierError(specifier);
1971
- }
1972
- };
1973
- fn._requireAuth = false;
1974
- return fn;
1928
+ const map = util.objectToMap(config);
1929
+ const fn = (request) => {
1930
+ const { specifier = firebase.MODEL_FUNCTION_FIREBASE_CRUD_FUNCTION_SPECIFIER_DEFAULT } = request;
1931
+ const handler = map.get(specifier);
1932
+ if (handler != null) {
1933
+ assertRequestRequiresAuthForFunction(handler, request);
1934
+ return handler(request);
1935
+ }
1936
+ else {
1937
+ throw unknownModelCrudFunctionSpecifierError(specifier);
1938
+ }
1939
+ };
1940
+ fn._requireAuth = false;
1941
+ return fn;
1975
1942
  }
1976
1943
  function unknownModelCrudFunctionSpecifierError(specifier) {
1977
- return badRequestError(util.serverError({
1978
- status: 400,
1979
- code: 'UNKNOWN_SPECIFIER_ERROR',
1980
- message: 'Invalid/unknown specifier for this function.',
1981
- data: {
1982
- specifier
1983
- }
1984
- }));
1944
+ return badRequestError(util.serverError({
1945
+ status: 400,
1946
+ code: 'UNKNOWN_SPECIFIER_ERROR',
1947
+ message: 'Invalid/unknown specifier for this function.',
1948
+ data: {
1949
+ specifier
1950
+ }
1951
+ }));
1985
1952
  }
1986
1953
 
1987
1954
  /**
@@ -1991,497 +1958,455 @@ function unknownModelCrudFunctionSpecifierError(specifier) {
1991
1958
  * @returns
1992
1959
  */
1993
1960
  function onCallModel(map, config = {}) {
1994
- const {
1995
- preAssert = () => undefined
1996
- } = config;
1997
- return request => {
1998
- const call = request.data?.call;
1999
- if (call) {
2000
- const callFn = map[call];
2001
- if (callFn) {
2002
- const {
2003
- specifier,
2004
- modelType
2005
- } = request.data;
2006
- preAssert({
2007
- call,
2008
- request,
2009
- modelType,
2010
- specifier
2011
- });
2012
- return callFn(request);
2013
- } else {
2014
- throw onCallModelUnknownCallTypeError(call);
2015
- }
2016
- } else {
2017
- throw onCallModelMissingCallTypeError();
2018
- }
2019
- };
1961
+ const { preAssert = () => undefined } = config;
1962
+ return (request) => {
1963
+ const call = request.data?.call;
1964
+ if (call) {
1965
+ const callFn = map[call];
1966
+ if (callFn) {
1967
+ const { specifier, modelType } = request.data;
1968
+ preAssert({ call, request, modelType, specifier });
1969
+ return callFn(request);
1970
+ }
1971
+ else {
1972
+ throw onCallModelUnknownCallTypeError(call);
1973
+ }
1974
+ }
1975
+ else {
1976
+ throw onCallModelMissingCallTypeError();
1977
+ }
1978
+ };
2020
1979
  }
2021
1980
  function onCallModelMissingCallTypeError() {
2022
- return badRequestError(util.serverError({
2023
- status: 400,
2024
- code: 'CALL_TYPE_MISSING_ERROR',
2025
- message: `The call type was missing from the request.`
2026
- }));
1981
+ return badRequestError(util.serverError({
1982
+ status: 400,
1983
+ code: 'CALL_TYPE_MISSING_ERROR',
1984
+ message: `The call type was missing from the request.`
1985
+ }));
2027
1986
  }
2028
1987
  function onCallModelUnknownCallTypeError(call) {
2029
- return badRequestError(util.serverError({
2030
- status: 400,
2031
- code: 'UNKNOWN_CALL_TYPE_ERROR',
2032
- message: `Unknown call type "${call}".`,
2033
- data: {
2034
- call
2035
- }
2036
- }));
1988
+ return badRequestError(util.serverError({
1989
+ status: 400,
1990
+ code: 'UNKNOWN_CALL_TYPE_ERROR',
1991
+ message: `Unknown call type "${call}".`,
1992
+ data: {
1993
+ call
1994
+ }
1995
+ }));
2037
1996
  }
2038
1997
  function _onCallWithCallTypeFunction(map, config) {
2039
- const {
2040
- callType,
2041
- crudType,
2042
- preAssert = () => undefined,
2043
- throwOnUnknownModelType
2044
- } = config;
2045
- return request => {
2046
- const modelType = request.data?.modelType;
2047
- const crudFn = map[modelType];
2048
- if (crudFn) {
2049
- const specifier = request.data.specifier;
2050
- assertRequestRequiresAuthForFunction(crudFn, request);
2051
- preAssert({
2052
- call: callType,
2053
- request,
2054
- modelType,
2055
- specifier
2056
- });
2057
- return crudFn({
2058
- ...request,
2059
- specifier,
2060
- data: request.data.data
2061
- });
2062
- } else {
2063
- throw throwOnUnknownModelType(modelType);
2064
- }
2065
- };
1998
+ const { callType, crudType, preAssert = () => undefined, throwOnUnknownModelType } = config;
1999
+ return (request) => {
2000
+ const modelType = request.data?.modelType;
2001
+ const crudFn = map[modelType];
2002
+ if (crudFn) {
2003
+ const specifier = request.data.specifier;
2004
+ assertRequestRequiresAuthForFunction(crudFn, request);
2005
+ preAssert({ call: callType, request, modelType, specifier });
2006
+ return crudFn({
2007
+ ...request,
2008
+ specifier,
2009
+ data: request.data.data
2010
+ });
2011
+ }
2012
+ else {
2013
+ throw throwOnUnknownModelType(modelType);
2014
+ }
2015
+ };
2066
2016
  }
2067
2017
 
2068
2018
  function onCallCreateModel(map, config = {}) {
2069
- const {
2070
- preAssert
2071
- } = config;
2072
- return _onCallWithCallTypeFunction(map, {
2073
- callType: 'create',
2074
- crudType: 'create',
2075
- preAssert,
2076
- throwOnUnknownModelType: createModelUnknownModelTypeError
2077
- });
2019
+ const { preAssert } = config;
2020
+ return _onCallWithCallTypeFunction(map, {
2021
+ callType: 'create',
2022
+ crudType: 'create',
2023
+ preAssert,
2024
+ throwOnUnknownModelType: createModelUnknownModelTypeError
2025
+ });
2078
2026
  }
2079
2027
  function createModelUnknownModelTypeError(modelType) {
2080
- return badRequestError(util.serverError({
2081
- status: 400,
2082
- code: 'UNKNOWN_TYPE_ERROR',
2083
- message: `Invalid type "${modelType}" to create.`,
2084
- data: {
2085
- modelType
2086
- }
2087
- }));
2028
+ return badRequestError(util.serverError({
2029
+ status: 400,
2030
+ code: 'UNKNOWN_TYPE_ERROR',
2031
+ message: `Invalid type "${modelType}" to create.`,
2032
+ data: {
2033
+ modelType
2034
+ }
2035
+ }));
2088
2036
  }
2089
2037
 
2090
2038
  function onCallReadModel(map, config = {}) {
2091
- const {
2092
- preAssert
2093
- } = config;
2094
- return _onCallWithCallTypeFunction(map, {
2095
- callType: 'read',
2096
- crudType: 'read',
2097
- preAssert,
2098
- throwOnUnknownModelType: readModelUnknownModelTypeError
2099
- });
2039
+ const { preAssert } = config;
2040
+ return _onCallWithCallTypeFunction(map, {
2041
+ callType: 'read',
2042
+ crudType: 'read',
2043
+ preAssert,
2044
+ throwOnUnknownModelType: readModelUnknownModelTypeError
2045
+ });
2100
2046
  }
2101
2047
  function readModelUnknownModelTypeError(modelType) {
2102
- return badRequestError(util.serverError({
2103
- status: 400,
2104
- code: 'UNKNOWN_TYPE_ERROR',
2105
- message: 'Invalid type to read.',
2106
- data: {
2107
- modelType
2108
- }
2109
- }));
2048
+ return badRequestError(util.serverError({
2049
+ status: 400,
2050
+ code: 'UNKNOWN_TYPE_ERROR',
2051
+ message: 'Invalid type to read.',
2052
+ data: {
2053
+ modelType
2054
+ }
2055
+ }));
2110
2056
  }
2111
2057
 
2112
2058
  function onCallUpdateModel(map, config = {}) {
2113
- const {
2114
- preAssert
2115
- } = config;
2116
- return _onCallWithCallTypeFunction(map, {
2117
- callType: 'update',
2118
- crudType: 'update',
2119
- preAssert,
2120
- throwOnUnknownModelType: updateModelUnknownModelTypeError
2121
- });
2059
+ const { preAssert } = config;
2060
+ return _onCallWithCallTypeFunction(map, {
2061
+ callType: 'update',
2062
+ crudType: 'update',
2063
+ preAssert,
2064
+ throwOnUnknownModelType: updateModelUnknownModelTypeError
2065
+ });
2122
2066
  }
2123
2067
  function updateModelUnknownModelTypeError(modelType) {
2124
- return badRequestError(util.serverError({
2125
- status: 400,
2126
- code: 'UNKNOWN_TYPE_ERROR',
2127
- message: 'Invalid type to update.',
2128
- data: {
2129
- modelType
2130
- }
2131
- }));
2068
+ return badRequestError(util.serverError({
2069
+ status: 400,
2070
+ code: 'UNKNOWN_TYPE_ERROR',
2071
+ message: 'Invalid type to update.',
2072
+ data: {
2073
+ modelType
2074
+ }
2075
+ }));
2132
2076
  }
2133
2077
 
2134
2078
  function onCallDeleteModel(map, config = {}) {
2135
- const {
2136
- preAssert
2137
- } = config;
2138
- return _onCallWithCallTypeFunction(map, {
2139
- callType: 'delete',
2140
- crudType: 'delete',
2141
- preAssert,
2142
- throwOnUnknownModelType: deleteModelUnknownModelTypeError
2143
- });
2079
+ const { preAssert } = config;
2080
+ return _onCallWithCallTypeFunction(map, {
2081
+ callType: 'delete',
2082
+ crudType: 'delete',
2083
+ preAssert,
2084
+ throwOnUnknownModelType: deleteModelUnknownModelTypeError
2085
+ });
2144
2086
  }
2145
2087
  function deleteModelUnknownModelTypeError(modelType) {
2146
- return badRequestError(util.serverError({
2147
- status: 400,
2148
- code: 'UNKNOWN_TYPE_ERROR',
2149
- message: 'Invalid type to delete.',
2150
- data: {
2151
- modelType
2152
- }
2153
- }));
2088
+ return badRequestError(util.serverError({
2089
+ status: 400,
2090
+ code: 'UNKNOWN_TYPE_ERROR',
2091
+ message: 'Invalid type to delete.',
2092
+ data: {
2093
+ modelType
2094
+ }
2095
+ }));
2154
2096
  }
2155
2097
 
2156
2098
  function googleCloudStorageBucketForStorageFilePath(storage, path) {
2157
- return storage.bucket(path.bucketId);
2099
+ return storage.bucket(path.bucketId);
2158
2100
  }
2159
2101
  function googleCloudStorageFileForStorageFilePath(storage, path) {
2160
- return googleCloudStorageBucketForStorageFilePath(storage, path).file(path.pathString);
2102
+ return googleCloudStorageBucketForStorageFilePath(storage, path).file(path.pathString);
2161
2103
  }
2162
2104
  function googleCloudFileMetadataToStorageMetadata(file, metadata) {
2163
- const fullPath = file.name;
2164
- const generation = String(metadata.generation ?? file.generation);
2165
- const metageneration = String(metadata.metageneration);
2166
- const size = Number(metadata.size);
2167
- const customMetadata = metadata.metadata;
2168
- return {
2169
- bucket: file.bucket.name,
2170
- fullPath,
2171
- generation,
2172
- metageneration,
2173
- name: file.name,
2174
- size,
2175
- timeCreated: metadata.timeCreated,
2176
- updated: metadata.updated,
2177
- md5Hash: metadata.md5Hash,
2178
- cacheControl: metadata.cacheControl,
2179
- contentDisposition: metadata.contentDisposition,
2180
- contentEncoding: metadata.contentEncoding,
2181
- contentLanguage: metadata.contentLanguage,
2182
- contentType: metadata.contentType,
2183
- customMetadata
2184
- };
2185
- }
2186
- function googleCloudStorageAccessorFile(storage$1, storagePath) {
2187
- const file = googleCloudStorageFileForStorageFilePath(storage$1, storagePath);
2188
- function makeDownloadOptions(maxDownloadSizeBytes) {
2105
+ const fullPath = file.name;
2106
+ const generation = String(metadata.generation ?? file.generation);
2107
+ const metageneration = String(metadata.metageneration);
2108
+ const size = Number(metadata.size);
2109
+ const customMetadata = metadata.metadata;
2189
2110
  return {
2190
- ...(maxDownloadSizeBytes ? {
2191
- // end is inclusive
2192
- end: maxDownloadSizeBytes - 1
2193
- } : undefined)
2111
+ bucket: file.bucket.name,
2112
+ fullPath,
2113
+ generation,
2114
+ metageneration,
2115
+ name: file.name,
2116
+ size,
2117
+ timeCreated: metadata.timeCreated,
2118
+ updated: metadata.updated,
2119
+ md5Hash: metadata.md5Hash,
2120
+ cacheControl: metadata.cacheControl,
2121
+ contentDisposition: metadata.contentDisposition,
2122
+ contentEncoding: metadata.contentEncoding,
2123
+ contentLanguage: metadata.contentLanguage,
2124
+ contentType: metadata.contentType,
2125
+ customMetadata
2194
2126
  };
2195
- }
2196
- function _configureMetadata(options) {
2197
- const customMetadata = util.filterUndefinedValues({
2198
- ...options.metadata?.customMetadata,
2199
- ...options?.customMetadata
2200
- });
2201
- return util.filterUndefinedValues({
2202
- cacheControl: options.metadata?.cacheControl,
2203
- contentDisposition: options.metadata?.contentDisposition,
2204
- contentEncoding: options.metadata?.contentEncoding,
2205
- contentLanguage: options.metadata?.contentLanguage,
2206
- contentType: options.metadata?.contentType,
2207
- metadata: !util.objectHasNoKeys(customMetadata) ? customMetadata : undefined
2208
- });
2209
- }
2210
- function makeUploadOptions(options) {
2211
- let metadata;
2212
- if (options != null) {
2213
- metadata = _configureMetadata({
2214
- metadata: {
2215
- ...options.metadata,
2216
- contentType: options.contentType ?? options.metadata?.contentType
2217
- },
2218
- customMetadata: options.customMetadata
2219
- });
2127
+ }
2128
+ function googleCloudStorageAccessorFile(storage$1, storagePath) {
2129
+ const file = googleCloudStorageFileForStorageFilePath(storage$1, storagePath);
2130
+ function makeDownloadOptions(maxDownloadSizeBytes) {
2131
+ return {
2132
+ ...(maxDownloadSizeBytes
2133
+ ? {
2134
+ // end is inclusive
2135
+ end: maxDownloadSizeBytes - 1
2136
+ }
2137
+ : undefined)
2138
+ };
2220
2139
  }
2221
- return {
2222
- // non-resumable
2223
- resumable: false,
2224
- // add content type and other custom metadata
2225
- ...(metadata ? {
2226
- metadata
2227
- } : undefined)
2140
+ function _configureMetadata(options) {
2141
+ const customMetadata = util.filterUndefinedValues({
2142
+ ...options.metadata?.customMetadata,
2143
+ ...options?.customMetadata
2144
+ });
2145
+ return util.filterUndefinedValues({
2146
+ cacheControl: options.metadata?.cacheControl,
2147
+ contentDisposition: options.metadata?.contentDisposition,
2148
+ contentEncoding: options.metadata?.contentEncoding,
2149
+ contentLanguage: options.metadata?.contentLanguage,
2150
+ contentType: options.metadata?.contentType,
2151
+ metadata: !util.objectHasNoKeys(customMetadata) ? customMetadata : undefined
2152
+ });
2153
+ }
2154
+ function makeUploadOptions(options) {
2155
+ let metadata;
2156
+ if (options != null) {
2157
+ metadata = _configureMetadata({
2158
+ metadata: {
2159
+ ...options.metadata,
2160
+ contentType: options.contentType ?? options.metadata?.contentType
2161
+ },
2162
+ customMetadata: options.customMetadata
2163
+ });
2164
+ }
2165
+ return {
2166
+ // non-resumable
2167
+ resumable: false,
2168
+ // add content type and other custom metadata
2169
+ ...(metadata ? { metadata } : undefined)
2170
+ };
2171
+ }
2172
+ function asFileMetadata(metadata) {
2173
+ return _configureMetadata({ metadata });
2174
+ }
2175
+ function makeStoragePathForPath(newPath) {
2176
+ let path;
2177
+ if (typeof newPath === 'string') {
2178
+ path = {
2179
+ bucketId: file.bucket.name,
2180
+ pathString: newPath
2181
+ };
2182
+ }
2183
+ else {
2184
+ path = newPath;
2185
+ }
2186
+ return path;
2187
+ }
2188
+ async function copy(newPath, options) {
2189
+ const newStoragePath = makeStoragePathForPath(newPath);
2190
+ const newFile = googleCloudStorageAccessorFile(storage$1, newStoragePath);
2191
+ return _copyWithFile(newFile, options);
2192
+ }
2193
+ async function _copyWithFile(newFile, options) {
2194
+ const copyOptions = {
2195
+ ...options
2196
+ };
2197
+ await file.copy(newFile.reference, copyOptions);
2198
+ return newFile;
2199
+ }
2200
+ /**
2201
+ * Configuration for the public ACL.
2202
+ */
2203
+ const PUBLIC_ACL = {
2204
+ entity: 'allUsers',
2205
+ role: 'READER'
2228
2206
  };
2229
- }
2230
- function asFileMetadata(metadata) {
2231
- return _configureMetadata({
2232
- metadata
2233
- });
2234
- }
2235
- function makeStoragePathForPath(newPath) {
2236
- let path;
2237
- if (typeof newPath === 'string') {
2238
- path = {
2239
- bucketId: file.bucket.name,
2240
- pathString: newPath
2241
- };
2242
- } else {
2243
- path = newPath;
2244
- }
2245
- return path;
2246
- }
2247
- async function copy(newPath, options) {
2248
- const newStoragePath = makeStoragePathForPath(newPath);
2249
- const newFile = googleCloudStorageAccessorFile(storage$1, newStoragePath);
2250
- return _copyWithFile(newFile, options);
2251
- }
2252
- async function _copyWithFile(newFile, options) {
2253
- const copyOptions = {
2254
- ...options
2207
+ const accessorFile = {
2208
+ reference: file,
2209
+ storagePath,
2210
+ exists: () => file.exists().then((x) => x[0]),
2211
+ getDownloadUrl: () => file.getMetadata().then(() => file.publicUrl()),
2212
+ getSignedUrl: async (input) => {
2213
+ const expires = input?.expiresAt ??
2214
+ (input?.expiresIn != null
2215
+ ? dateFns.addMilliseconds(new Date(), input.expiresIn) // use expiresIn if provided
2216
+ : dateFns.addHours(new Date(), 1)); // default expiration in 1 hour
2217
+ const config = {
2218
+ ...input,
2219
+ action: input?.action ?? 'read',
2220
+ expires,
2221
+ expiresIn: undefined, // clear from input
2222
+ expiresAt: undefined
2223
+ };
2224
+ return file
2225
+ .getSignedUrl(config)
2226
+ .then((x) => x[0])
2227
+ .catch((e) => {
2228
+ let publicUrlBackup;
2229
+ if (e && e.name === 'SigningError' && (nestjs.isTestNodeEnv() || process.env.FIREBASE_STORAGE_EMULATOR_HOST)) {
2230
+ // NOTE: Signing does not behave properly in the emulator as it is not supported.
2231
+ // https://github.com/firebase/firebase-tools/issues/3400
2232
+ // we can return the public url instead.
2233
+ // This is fine, as in production this file url is protected by ACLs anyways.
2234
+ publicUrlBackup = file.publicUrl();
2235
+ }
2236
+ else {
2237
+ throw e;
2238
+ }
2239
+ return publicUrlBackup;
2240
+ });
2241
+ },
2242
+ getMetadata: () => file.getMetadata().then((x) => googleCloudFileMetadataToStorageMetadata(file, x[0])),
2243
+ setMetadata: (metadata) => file.setMetadata(asFileMetadata(metadata)).then((x) => googleCloudFileMetadataToStorageMetadata(file, x[0])),
2244
+ getBytes: (maxDownloadSizeBytes) => file.download(makeDownloadOptions(maxDownloadSizeBytes)).then((x) => x[0]),
2245
+ getStream: (maxDownloadSizeBytes) => file.createReadStream(makeDownloadOptions(maxDownloadSizeBytes)),
2246
+ upload: async (input, options) => {
2247
+ let dataToUpload;
2248
+ if (typeof input === 'string') {
2249
+ const parsedStringFormat = firebase.assertStorageUploadOptionsStringFormat(options);
2250
+ const stringFormat = parsedStringFormat === 'raw' ? 'utf-8' : parsedStringFormat;
2251
+ if (stringFormat === 'data_url') {
2252
+ // TODO(FUTURE): support this later if necessary. Server should really never see this type.
2253
+ throw new Error('"data_url" is unsupported.');
2254
+ }
2255
+ dataToUpload = Buffer.from(input, stringFormat);
2256
+ }
2257
+ else {
2258
+ if (Buffer.isBuffer(input)) {
2259
+ dataToUpload = input;
2260
+ }
2261
+ else if (types.isUint8Array(input)) {
2262
+ dataToUpload = Buffer.from(input);
2263
+ }
2264
+ else {
2265
+ // NOTE: these values shouldn't ever be encountered in the NodeJS environment. May remove later.
2266
+ if (types.isArrayBuffer(input)) {
2267
+ dataToUpload = Buffer.from(input);
2268
+ }
2269
+ else {
2270
+ dataToUpload = input.arrayBuffer().then((x) => Buffer.from(x));
2271
+ }
2272
+ }
2273
+ }
2274
+ const data = await dataToUpload;
2275
+ return file.save(data, makeUploadOptions(options));
2276
+ },
2277
+ uploadStream: (options) => file.createWriteStream(makeUploadOptions(options)),
2278
+ move: async (newPath, options) => {
2279
+ const newStoragePath = makeStoragePathForPath(newPath);
2280
+ const newFile = googleCloudStorageAccessorFile(storage$1, newStoragePath);
2281
+ const moveOptions = {
2282
+ ...options
2283
+ };
2284
+ await file.moveFileAtomic(newFile.reference, moveOptions).catch(async (e) => {
2285
+ if (e instanceof storage.ApiError && e.response?.statusMessage === 'Not Implemented') {
2286
+ // NOTE: This is not implemented in storage emulator, so it will fail with this error in testing.
2287
+ // https://github.com/firebase/firebase-tools/issues/3751
2288
+ // we can perform the same task using copy and then deleting this file.
2289
+ await copy(newPath, moveOptions);
2290
+ await accessorFile.delete();
2291
+ }
2292
+ else {
2293
+ throw e;
2294
+ }
2295
+ });
2296
+ return newFile;
2297
+ },
2298
+ copy,
2299
+ delete: (options) => file.delete(options).then((x) => undefined),
2300
+ isPublic: () => file.isPublic().then((x) => x[0]),
2301
+ makePublic: (setPublic) => (setPublic !== false ? file.acl.add(PUBLIC_ACL) : file.acl.delete({ entity: PUBLIC_ACL.entity })).then(() => undefined),
2302
+ makePrivate: (options) => file.makePrivate(options).then(() => undefined),
2303
+ getAcls: (options) => file.acl.get(options).then((x) => ({ acls: x[0], metadata: x[1] }))
2255
2304
  };
2256
- await file.copy(newFile.reference, copyOptions);
2257
- return newFile;
2258
- }
2259
- /**
2260
- * Configuration for the public ACL.
2261
- */
2262
- const PUBLIC_ACL = {
2263
- entity: 'allUsers',
2264
- role: 'READER'
2265
- };
2266
- const accessorFile = {
2267
- reference: file,
2268
- storagePath,
2269
- exists: () => file.exists().then(x => x[0]),
2270
- getDownloadUrl: () => file.getMetadata().then(() => file.publicUrl()),
2271
- getSignedUrl: async input => {
2272
- const expires = input?.expiresAt ?? (input?.expiresIn != null ? dateFns.addMilliseconds(new Date(), input.expiresIn) // use expiresIn if provided
2273
- : dateFns.addHours(new Date(), 1)); // default expiration in 1 hour
2274
- const config = {
2275
- ...input,
2276
- action: input?.action ?? 'read',
2277
- expires,
2278
- expiresIn: undefined,
2279
- // clear from input
2280
- expiresAt: undefined
2281
- };
2282
- return file.getSignedUrl(config).then(x => x[0]).catch(e => {
2283
- let publicUrlBackup;
2284
- if (e && e.name === 'SigningError' && (nestjs.isTestNodeEnv() || process.env.FIREBASE_STORAGE_EMULATOR_HOST)) {
2285
- // NOTE: Signing does not behave properly in the emulator as it is not supported.
2286
- // https://github.com/firebase/firebase-tools/issues/3400
2287
- // we can return the public url instead.
2288
- // This is fine, as in production this file url is protected by ACLs anyways.
2289
- publicUrlBackup = file.publicUrl();
2290
- } else {
2291
- throw e;
2292
- }
2293
- return publicUrlBackup;
2294
- });
2305
+ return accessorFile;
2306
+ }
2307
+ const googleCloudStorageListFilesResultFactory = firebase.storageListFilesResultFactory({
2308
+ hasItems(result) {
2309
+ return Boolean(result.apiResponse.items || result.apiResponse.prefixes);
2295
2310
  },
2296
- getMetadata: () => file.getMetadata().then(x => googleCloudFileMetadataToStorageMetadata(file, x[0])),
2297
- setMetadata: metadata => file.setMetadata(asFileMetadata(metadata)).then(x => googleCloudFileMetadataToStorageMetadata(file, x[0])),
2298
- getBytes: maxDownloadSizeBytes => file.download(makeDownloadOptions(maxDownloadSizeBytes)).then(x => x[0]),
2299
- getStream: maxDownloadSizeBytes => file.createReadStream(makeDownloadOptions(maxDownloadSizeBytes)),
2300
- upload: async (input, options) => {
2301
- let dataToUpload;
2302
- if (typeof input === 'string') {
2303
- const parsedStringFormat = firebase.assertStorageUploadOptionsStringFormat(options);
2304
- const stringFormat = parsedStringFormat === 'raw' ? 'utf-8' : parsedStringFormat;
2305
- if (stringFormat === 'data_url') {
2306
- // TODO(FUTURE): support this later if necessary. Server should really never see this type.
2307
- throw new Error('"data_url" is unsupported.');
2308
- }
2309
- dataToUpload = Buffer.from(input, stringFormat);
2310
- } else {
2311
- if (Buffer.isBuffer(input)) {
2312
- dataToUpload = input;
2313
- } else if (types.isUint8Array(input)) {
2314
- dataToUpload = Buffer.from(input);
2315
- } else {
2316
- // NOTE: these values shouldn't ever be encountered in the NodeJS environment. May remove later.
2317
- if (types.isArrayBuffer(input)) {
2318
- dataToUpload = Buffer.from(input);
2319
- } else {
2320
- dataToUpload = input.arrayBuffer().then(x => Buffer.from(x));
2321
- }
2322
- }
2323
- }
2324
- const data = await dataToUpload;
2325
- return file.save(data, makeUploadOptions(options));
2311
+ hasNext: (result) => {
2312
+ return result.nextQuery != null;
2326
2313
  },
2327
- uploadStream: options => file.createWriteStream(makeUploadOptions(options)),
2328
- move: async (newPath, options) => {
2329
- const newStoragePath = makeStoragePathForPath(newPath);
2330
- const newFile = googleCloudStorageAccessorFile(storage$1, newStoragePath);
2331
- const moveOptions = {
2332
- ...options
2333
- };
2334
- await file.moveFileAtomic(newFile.reference, moveOptions).catch(async e => {
2335
- if (e instanceof storage.ApiError && e.response?.statusMessage === 'Not Implemented') {
2336
- // NOTE: This is not implemented in storage emulator, so it will fail with this error in testing.
2337
- // https://github.com/firebase/firebase-tools/issues/3751
2338
- // we can perform the same task using copy and then deleting this file.
2339
- await copy(newPath, moveOptions);
2340
- await accessorFile.delete();
2341
- } else {
2342
- throw e;
2343
- }
2344
- });
2345
- return newFile;
2314
+ nextPageTokenFromResult(result) {
2315
+ return result.nextQuery?.pageToken;
2346
2316
  },
2347
- copy,
2348
- delete: options => file.delete(options).then(x => undefined),
2349
- isPublic: () => file.isPublic().then(x => x[0]),
2350
- makePublic: setPublic => (setPublic !== false ? file.acl.add(PUBLIC_ACL) : file.acl.delete({
2351
- entity: PUBLIC_ACL.entity
2352
- })).then(() => undefined),
2353
- makePrivate: options => file.makePrivate(options).then(() => undefined),
2354
- getAcls: options => file.acl.get(options).then(x => ({
2355
- acls: x[0],
2356
- metadata: x[1]
2357
- }))
2358
- };
2359
- return accessorFile;
2360
- }
2361
- const googleCloudStorageListFilesResultFactory = firebase.storageListFilesResultFactory({
2362
- hasItems(result) {
2363
- return Boolean(result.apiResponse.items || result.apiResponse.prefixes);
2364
- },
2365
- hasNext: result => {
2366
- return result.nextQuery != null;
2367
- },
2368
- nextPageTokenFromResult(result) {
2369
- return result.nextQuery?.pageToken;
2370
- },
2371
- next(storage, options, folder, result) {
2372
- return folder.list({
2373
- ...options,
2374
- ...result.nextQuery
2375
- });
2376
- },
2377
- file(storage, fileResult) {
2378
- return googleCloudStorageAccessorFile(storage, fileResult.storagePath);
2379
- },
2380
- folder(storage, folderResult) {
2381
- return googleCloudStorageAccessorFolder(storage, folderResult.storagePath);
2382
- },
2383
- filesFromResult(result) {
2384
- const items = result.apiResponse?.items ?? [];
2385
- return items.map(x => ({
2386
- raw: x,
2387
- name: util.slashPathName(x.name),
2388
- storagePath: {
2389
- bucketId: x.bucket,
2390
- pathString: x.name
2391
- }
2392
- }));
2393
- },
2394
- foldersFromResult(result, folder) {
2395
- const items = result.apiResponse?.prefixes ?? [];
2396
- return items.map(prefix => ({
2397
- raw: prefix,
2398
- name: util.slashPathName(prefix),
2399
- storagePath: {
2400
- bucketId: folder.storagePath.bucketId,
2401
- pathString: prefix
2402
- }
2403
- }));
2404
- }
2317
+ next(storage, options, folder, result) {
2318
+ return folder.list({ ...options, ...result.nextQuery });
2319
+ },
2320
+ file(storage, fileResult) {
2321
+ return googleCloudStorageAccessorFile(storage, fileResult.storagePath);
2322
+ },
2323
+ folder(storage, folderResult) {
2324
+ return googleCloudStorageAccessorFolder(storage, folderResult.storagePath);
2325
+ },
2326
+ filesFromResult(result) {
2327
+ const items = result.apiResponse?.items ?? [];
2328
+ return items.map((x) => ({ raw: x, name: util.slashPathName(x.name), storagePath: { bucketId: x.bucket, pathString: x.name } }));
2329
+ },
2330
+ foldersFromResult(result, folder) {
2331
+ const items = result.apiResponse?.prefixes ?? [];
2332
+ return items.map((prefix) => ({ raw: prefix, name: util.slashPathName(prefix), storagePath: { bucketId: folder.storagePath.bucketId, pathString: prefix } }));
2333
+ }
2405
2334
  });
2406
2335
  function googleCloudStorageAccessorFolder(storage, storagePath) {
2407
- const bucket = googleCloudStorageBucketForStorageFilePath(storage, storagePath);
2408
- const file = bucket.file(storagePath.pathString);
2409
- const folder = {
2410
- reference: file,
2411
- storagePath,
2412
- exists: async () => folder.list({
2413
- maxResults: 1
2414
- }).then(x => x.hasItems()),
2415
- list: options => {
2416
- const {
2417
- maxResults,
2418
- pageToken,
2419
- includeNestedResults: listAll
2420
- } = options ?? {};
2421
- const listOptions = {
2422
- maxResults,
2423
- pageToken,
2424
- autoPaginate: false,
2425
- versions: false,
2426
- ...(listAll ? {
2427
- prefix: util.toRelativeSlashPathStartType(util.fixMultiSlashesInSlashPath(storagePath.pathString + '/'))
2428
- } : {
2429
- // includeTrailingDelimiter: true,
2430
- delimiter: util.SLASH_PATH_SEPARATOR,
2431
- prefix: util.toRelativeSlashPathStartType(util.fixMultiSlashesInSlashPath(storagePath.pathString + '/')) // make sure the folder always ends with a slash
2432
- })
2433
- };
2434
- return bucket.getFiles(listOptions).then(x => {
2435
- const files = x[0];
2436
- const nextQuery = x[1];
2437
- const apiResponse = x[2];
2438
- const result = {
2439
- files: files,
2440
- nextQuery,
2441
- apiResponse: apiResponse
2442
- };
2443
- return googleCloudStorageListFilesResultFactory(storage, folder, options, result);
2444
- });
2445
- }
2446
- };
2447
- return folder;
2336
+ const bucket = googleCloudStorageBucketForStorageFilePath(storage, storagePath);
2337
+ const file = bucket.file(storagePath.pathString);
2338
+ const folder = {
2339
+ reference: file,
2340
+ storagePath,
2341
+ exists: async () => folder.list({ maxResults: 1 }).then((x) => x.hasItems()),
2342
+ list: (options) => {
2343
+ const { maxResults, pageToken, includeNestedResults: listAll } = options ?? {};
2344
+ const listOptions = {
2345
+ maxResults,
2346
+ pageToken,
2347
+ autoPaginate: false,
2348
+ versions: false,
2349
+ ...(listAll
2350
+ ? {
2351
+ prefix: util.toRelativeSlashPathStartType(util.fixMultiSlashesInSlashPath(storagePath.pathString + '/'))
2352
+ }
2353
+ : {
2354
+ // includeTrailingDelimiter: true,
2355
+ delimiter: util.SLASH_PATH_SEPARATOR,
2356
+ prefix: util.toRelativeSlashPathStartType(util.fixMultiSlashesInSlashPath(storagePath.pathString + '/')) // make sure the folder always ends with a slash
2357
+ })
2358
+ };
2359
+ return bucket.getFiles(listOptions).then((x) => {
2360
+ const files = x[0];
2361
+ const nextQuery = x[1];
2362
+ const apiResponse = x[2];
2363
+ const result = {
2364
+ files: files,
2365
+ nextQuery,
2366
+ apiResponse: apiResponse
2367
+ };
2368
+ return googleCloudStorageListFilesResultFactory(storage, folder, options, result);
2369
+ });
2370
+ }
2371
+ };
2372
+ return folder;
2448
2373
  }
2449
2374
  function googleCloudStorageFirebaseStorageAccessorDriver() {
2450
- return {
2451
- type: 'server',
2452
- file: (storage, path) => googleCloudStorageAccessorFile(storage, path),
2453
- folder: (storage, path) => googleCloudStorageAccessorFolder(storage, path)
2454
- };
2375
+ return {
2376
+ type: 'server',
2377
+ file: (storage, path) => googleCloudStorageAccessorFile(storage, path),
2378
+ folder: (storage, path) => googleCloudStorageAccessorFolder(storage, path)
2379
+ };
2455
2380
  }
2456
2381
 
2457
2382
  function googleCloudFirebaseStorageDrivers() {
2458
- return {
2459
- storageDriverIdentifier: '@google-cloud/storage',
2460
- storageDriverType: 'production',
2461
- storageAccessorDriver: googleCloudStorageFirebaseStorageAccessorDriver()
2462
- };
2383
+ return {
2384
+ storageDriverIdentifier: '@google-cloud/storage',
2385
+ storageDriverType: 'production',
2386
+ storageAccessorDriver: googleCloudStorageFirebaseStorageAccessorDriver()
2387
+ };
2463
2388
  }
2464
2389
 
2465
2390
  /**
2466
2391
  * Basic service that implements FirebaseStorageAccessor and provides a FirebaseStorageContext.
2467
2392
  */
2468
2393
  class FirebaseServerStorageService {
2469
- constructor(storageContext) {
2470
- this._storageContext = void 0;
2471
- this._storageContext = storageContext;
2472
- }
2473
- get storageContext() {
2474
- return this._storageContext;
2475
- }
2476
- defaultBucket() {
2477
- return this.storageContext.defaultBucket();
2478
- }
2479
- file(path) {
2480
- return this.storageContext.file(path);
2481
- }
2482
- folder(path) {
2483
- return this.storageContext.folder(path);
2484
- }
2394
+ _storageContext;
2395
+ constructor(storageContext) {
2396
+ this._storageContext = storageContext;
2397
+ }
2398
+ get storageContext() {
2399
+ return this._storageContext;
2400
+ }
2401
+ defaultBucket() {
2402
+ return this.storageContext.defaultBucket();
2403
+ }
2404
+ file(path) {
2405
+ return this.storageContext.file(path);
2406
+ }
2407
+ folder(path) {
2408
+ return this.storageContext.folder(path);
2409
+ }
2485
2410
  }
2486
2411
 
2487
2412
  /**
@@ -2495,7 +2420,7 @@ const googleCloudFirebaseStorageContextFactory = firebase.firebaseStorageContext
2495
2420
  * @returns
2496
2421
  */
2497
2422
  function googleCloudStorageFromFirebaseAdminStorage(storage) {
2498
- return storage.storageClient;
2423
+ return storage.storageClient;
2499
2424
  }
2500
2425
 
2501
2426
  // MARK: Tokens
@@ -2514,59 +2439,69 @@ const FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN = 'FIREBASE_STORAGE_CONTEXT_
2514
2439
  /**
2515
2440
  * Nest provider module for Firebase that provides a firestore, etc. from the firestore token.
2516
2441
  */
2517
- exports.FirebaseServerStorageModule = class FirebaseServerStorageModule {};
2518
- exports.FirebaseServerStorageModule = __decorate([common.Module({
2519
- providers: [{
2520
- provide: FIREBASE_STORAGE_TOKEN,
2521
- useFactory: app => googleCloudStorageFromFirebaseAdminStorage(app.storage()),
2522
- inject: [FIREBASE_APP_TOKEN]
2523
- }],
2524
- exports: [FIREBASE_STORAGE_TOKEN]
2525
- })], exports.FirebaseServerStorageModule);
2442
+ exports.FirebaseServerStorageModule = class FirebaseServerStorageModule {
2443
+ };
2444
+ exports.FirebaseServerStorageModule = __decorate([
2445
+ common.Module({
2446
+ providers: [
2447
+ {
2448
+ provide: FIREBASE_STORAGE_TOKEN,
2449
+ useFactory: (app) => googleCloudStorageFromFirebaseAdminStorage(app.storage()),
2450
+ inject: [FIREBASE_APP_TOKEN]
2451
+ }
2452
+ ],
2453
+ exports: [FIREBASE_STORAGE_TOKEN]
2454
+ })
2455
+ ], exports.FirebaseServerStorageModule);
2526
2456
  /**
2527
2457
  * Nest provider module for firebase that includes the FirebaseServerStorageModule and provides a value for STORAGE_CONTEXT_TOKEN using the googleCloudStorageContextFactory.
2528
2458
  */
2529
- exports.FirebaseServerStorageContextModule = class FirebaseServerStorageContextModule {};
2530
- exports.FirebaseServerStorageContextModule = __decorate([common.Module({
2531
- imports: [exports.FirebaseServerStorageModule],
2532
- providers: [{
2533
- provide: FIREBASE_STORAGE_CONTEXT_TOKEN,
2534
- useFactory: googleCloudFirebaseStorageContextFactory,
2535
- inject: [FIREBASE_STORAGE_TOKEN, FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN]
2536
- }],
2537
- exports: [exports.FirebaseServerStorageModule, FIREBASE_STORAGE_CONTEXT_TOKEN]
2538
- })], exports.FirebaseServerStorageContextModule);
2459
+ exports.FirebaseServerStorageContextModule = class FirebaseServerStorageContextModule {
2460
+ };
2461
+ exports.FirebaseServerStorageContextModule = __decorate([
2462
+ common.Module({
2463
+ imports: [exports.FirebaseServerStorageModule],
2464
+ providers: [
2465
+ {
2466
+ provide: FIREBASE_STORAGE_CONTEXT_TOKEN,
2467
+ useFactory: googleCloudFirebaseStorageContextFactory,
2468
+ inject: [FIREBASE_STORAGE_TOKEN, FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN]
2469
+ }
2470
+ ],
2471
+ exports: [exports.FirebaseServerStorageModule, FIREBASE_STORAGE_CONTEXT_TOKEN]
2472
+ })
2473
+ ], exports.FirebaseServerStorageContextModule);
2539
2474
  // MARK: Token Configuration
2540
2475
  function firebaseServerStorageDefaultBucketIdTokenProvider(input) {
2541
- const config = typeof input === 'string' ? {
2542
- defaultBucketId: input
2543
- } : input;
2544
- if (!config.defaultBucketId) {
2545
- throw new Error('Non-empty defaultBucketId is required.');
2546
- }
2547
- return {
2548
- provide: FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN,
2549
- useValue: config
2550
- };
2476
+ const config = typeof input === 'string' ? { defaultBucketId: input } : input;
2477
+ if (!config.defaultBucketId) {
2478
+ throw new Error('Non-empty defaultBucketId is required.');
2479
+ }
2480
+ return {
2481
+ provide: FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN,
2482
+ useValue: config
2483
+ };
2551
2484
  }
2552
2485
  function defaultProvideFirebaseServerStorageServiceSimple() {
2553
- return {
2554
- provide: FirebaseServerStorageService,
2555
- useFactory: context => new FirebaseServerStorageService(context)
2556
- };
2486
+ return {
2487
+ provide: FirebaseServerStorageService,
2488
+ useFactory: (context) => new FirebaseServerStorageService(context)
2489
+ };
2557
2490
  }
2558
2491
  function provideFirebaseServerStorageService(provider) {
2559
- const providers = [{
2560
- ...provider,
2561
- inject: provider.inject ?? [FIREBASE_STORAGE_CONTEXT_TOKEN]
2562
- }];
2563
- if (provider.provide !== FirebaseServerStorageService) {
2564
- providers.push({
2565
- provide: FirebaseServerStorageService,
2566
- useExisting: provider.provide
2567
- });
2568
- }
2569
- return providers;
2492
+ const providers = [
2493
+ {
2494
+ ...provider,
2495
+ inject: provider.inject ?? [FIREBASE_STORAGE_CONTEXT_TOKEN]
2496
+ }
2497
+ ];
2498
+ if (provider.provide !== FirebaseServerStorageService) {
2499
+ providers.push({
2500
+ provide: FirebaseServerStorageService,
2501
+ useExisting: provider.provide
2502
+ });
2503
+ }
2504
+ return providers;
2570
2505
  }
2571
2506
  /**
2572
2507
  * Convenience function used to generate ModuleMetadata for an app's Auth related modules and FirebaseServerStorageService provider.
@@ -2576,145 +2511,133 @@ function provideFirebaseServerStorageService(provider) {
2576
2511
  * @returns
2577
2512
  */
2578
2513
  function firebaseServerStorageModuleMetadata(config) {
2579
- const serviceProvider = config && config.serviceProvider ? config.serviceProvider : defaultProvideFirebaseServerStorageServiceSimple();
2580
- const providers = provideFirebaseServerStorageService(serviceProvider);
2581
- const tokensToExport = nestjs.injectionTokensFromProviders(providers);
2582
- return nestjs.mergeModuleMetadata({
2583
- imports: [exports.FirebaseServerStorageContextModule],
2584
- exports: [exports.FirebaseServerStorageContextModule, ...tokensToExport],
2585
- providers
2586
- }, config);
2514
+ const serviceProvider = config && config.serviceProvider ? config.serviceProvider : defaultProvideFirebaseServerStorageServiceSimple();
2515
+ const providers = provideFirebaseServerStorageService(serviceProvider);
2516
+ const tokensToExport = nestjs.injectionTokensFromProviders(providers);
2517
+ return nestjs.mergeModuleMetadata({
2518
+ imports: [exports.FirebaseServerStorageContextModule],
2519
+ exports: [exports.FirebaseServerStorageContextModule, ...tokensToExport],
2520
+ providers
2521
+ }, config);
2587
2522
  }
2588
2523
 
2589
- class FirebaseNestServerRootModule {}
2524
+ class FirebaseNestServerRootModule {
2525
+ }
2590
2526
  function nestServerInstance(config) {
2591
- const {
2592
- moduleClass,
2593
- providers: additionalProviders,
2594
- defaultStorageBucket: inputDefaultStorageBucket,
2595
- forceStorageBucket,
2596
- globalApiRoutePrefix,
2597
- configureNestServerInstance
2598
- } = config;
2599
- const serversCache = new Map();
2600
- const initNestServer = (firebaseApp, env) => {
2601
- const appName = firebaseApp.name;
2602
- const defaultStorageBucket = inputDefaultStorageBucket ?? firebaseApp.options.storageBucket;
2603
- let nestServer = serversCache.get(appName);
2604
- if (!nestServer) {
2605
- const server = express();
2606
- const createNestServer = async expressInstance => {
2607
- const providers = [firebaseServerAppTokenProvider(util.asGetter(firebaseApp))];
2608
- // configure environment providers
2609
- if (env?.environment != null) {
2610
- providers.push(nestjs.serverEnvTokenProvider(env.environment));
2611
- if (config.configureEnvService !== false) {
2612
- providers.push({
2613
- provide: FirebaseServerEnvService,
2614
- useClass: exports.DefaultFirebaseServerEnvService
2615
- }, {
2616
- provide: nestjs.ServerEnvironmentService,
2617
- useExisting: FirebaseServerEnvService
2527
+ const { moduleClass, providers: additionalProviders, defaultStorageBucket: inputDefaultStorageBucket, forceStorageBucket, globalApiRoutePrefix, configureNestServerInstance } = config;
2528
+ const serversCache = new Map();
2529
+ const initNestServer = (firebaseApp, env) => {
2530
+ const appName = firebaseApp.name;
2531
+ const defaultStorageBucket = inputDefaultStorageBucket ?? firebaseApp.options.storageBucket;
2532
+ let nestServer = serversCache.get(appName);
2533
+ if (!nestServer) {
2534
+ const server = express();
2535
+ const createNestServer = async (expressInstance) => {
2536
+ const providers = [firebaseServerAppTokenProvider(util.asGetter(firebaseApp))];
2537
+ // configure environment providers
2538
+ if (env?.environment != null) {
2539
+ providers.push(nestjs.serverEnvTokenProvider(env.environment));
2540
+ if (config.configureEnvService !== false) {
2541
+ providers.push({
2542
+ provide: FirebaseServerEnvService,
2543
+ useClass: exports.DefaultFirebaseServerEnvService
2544
+ }, {
2545
+ provide: nestjs.ServerEnvironmentService,
2546
+ useExisting: FirebaseServerEnvService
2547
+ });
2548
+ }
2549
+ }
2550
+ if (additionalProviders) {
2551
+ util.pushItemOrArrayItemsIntoArray(providers, additionalProviders);
2552
+ }
2553
+ const imports = [moduleClass];
2554
+ // NOTE: https://cloud.google.com/functions/docs/writing/http#parsing_http_requests
2555
+ const options = { bodyParser: false }; // firebase already parses the requests
2556
+ if (config.configureWebhooks) {
2557
+ imports.push(exports.ConfigureFirebaseWebhookMiddlewareModule);
2558
+ }
2559
+ if (config.appCheckEnabled != false) {
2560
+ imports.push(exports.ConfigureFirebaseAppCheckMiddlewareModule);
2561
+ }
2562
+ if (defaultStorageBucket) {
2563
+ providers.push(firebaseServerStorageDefaultBucketIdTokenProvider({
2564
+ defaultBucketId: defaultStorageBucket,
2565
+ forceBucket: forceStorageBucket
2566
+ }));
2567
+ }
2568
+ // provide the global prefix config to the app
2569
+ providers.push({
2570
+ provide: GlobalRoutePrefixConfig,
2571
+ useValue: {
2572
+ globalApiRoutePrefix
2573
+ }
2574
+ });
2575
+ const providersModule = {
2576
+ module: FirebaseNestServerRootModule,
2577
+ imports,
2578
+ providers,
2579
+ exports: providers,
2580
+ global: true
2581
+ };
2582
+ let nestApp = await core.NestFactory.create(providersModule, new platformExpress.ExpressAdapter(expressInstance), options);
2583
+ if (globalApiRoutePrefix) {
2584
+ nestApp = nestApp.setGlobalPrefix(globalApiRoutePrefix);
2585
+ }
2586
+ if (configureNestServerInstance) {
2587
+ nestApp = configureNestServerInstance(nestApp) || nestApp;
2588
+ }
2589
+ return nestApp.init();
2590
+ };
2591
+ const nest = createNestServer(server).catch((err) => {
2592
+ console.error('Nest failed startup.', err);
2593
+ throw err;
2618
2594
  });
2619
- }
2620
- }
2621
- if (additionalProviders) {
2622
- util.pushItemOrArrayItemsIntoArray(providers, additionalProviders);
2623
- }
2624
- const imports = [moduleClass];
2625
- // NOTE: https://cloud.google.com/functions/docs/writing/http#parsing_http_requests
2626
- const options = {
2627
- bodyParser: false
2628
- }; // firebase already parses the requests
2629
- if (config.configureWebhooks) {
2630
- imports.push(exports.ConfigureFirebaseWebhookMiddlewareModule);
2595
+ nestServer = { server, nest: util.makeGetter(nest) };
2596
+ serversCache.set(appName, nestServer);
2631
2597
  }
2632
- if (config.appCheckEnabled != false) {
2633
- imports.push(exports.ConfigureFirebaseAppCheckMiddlewareModule);
2598
+ return nestServer;
2599
+ };
2600
+ const removeNestServer = async (firebaseApp) => {
2601
+ const appName = firebaseApp.name;
2602
+ const nestServer = serversCache.get(appName);
2603
+ let removed;
2604
+ if (nestServer) {
2605
+ removed = nestServer.nest().then((x) => {
2606
+ serversCache.delete(appName);
2607
+ return x.close().then(() => true);
2608
+ });
2634
2609
  }
2635
- if (defaultStorageBucket) {
2636
- providers.push(firebaseServerStorageDefaultBucketIdTokenProvider({
2637
- defaultBucketId: defaultStorageBucket,
2638
- forceBucket: forceStorageBucket
2639
- }));
2610
+ else {
2611
+ removed = Promise.resolve(false);
2640
2612
  }
2641
- // provide the global prefix config to the app
2642
- providers.push({
2643
- provide: GlobalRoutePrefixConfig,
2644
- useValue: {
2645
- globalApiRoutePrefix
2646
- }
2647
- });
2648
- const providersModule = {
2649
- module: FirebaseNestServerRootModule,
2650
- imports,
2651
- providers,
2652
- exports: providers,
2653
- global: true
2654
- };
2655
- let nestApp = await core.NestFactory.create(providersModule, new platformExpress.ExpressAdapter(expressInstance), options);
2656
- if (globalApiRoutePrefix) {
2657
- nestApp = nestApp.setGlobalPrefix(globalApiRoutePrefix);
2658
- }
2659
- if (configureNestServerInstance) {
2660
- nestApp = configureNestServerInstance(nestApp) || nestApp;
2661
- }
2662
- return nestApp.init();
2663
- };
2664
- const nest = createNestServer(server).catch(err => {
2665
- console.error('Nest failed startup.', err);
2666
- throw err;
2667
- });
2668
- nestServer = {
2669
- server,
2670
- nest: util.makeGetter(nest)
2671
- };
2672
- serversCache.set(appName, nestServer);
2673
- }
2674
- return nestServer;
2675
- };
2676
- const removeNestServer = async firebaseApp => {
2677
- const appName = firebaseApp.name;
2678
- const nestServer = serversCache.get(appName);
2679
- let removed;
2680
- if (nestServer) {
2681
- removed = nestServer.nest().then(x => {
2682
- serversCache.delete(appName);
2683
- return x.close().then(() => true);
2684
- });
2685
- } else {
2686
- removed = Promise.resolve(false);
2687
- }
2688
- return removed;
2689
- };
2690
- return {
2691
- moduleClass,
2692
- initNestServer,
2693
- removeNestServer
2694
- };
2613
+ return removed;
2614
+ };
2615
+ return {
2616
+ moduleClass,
2617
+ initNestServer,
2618
+ removeNestServer
2619
+ };
2695
2620
  }
2696
2621
 
2697
2622
  /**
2698
2623
  * Abstract class that wraps an INestApplicationContext value.
2699
2624
  */
2700
2625
  class AbstractNestContext {
2701
- constructor(nest) {
2702
- this._nest = void 0;
2703
- this._nest = nest;
2704
- }
2705
- get nest() {
2706
- return this._nest;
2707
- }
2626
+ _nest;
2627
+ constructor(nest) {
2628
+ this._nest = nest;
2629
+ }
2630
+ get nest() {
2631
+ return this._nest;
2632
+ }
2708
2633
  }
2709
2634
  class AbstractFirebaseNestContext extends AbstractNestContext {
2710
- constructor(...args) {
2711
- super(...args);
2712
2635
  /**
2713
2636
  * FirebasePermissionErrorContextErrorFunction to use with makeModelContext().
2714
2637
  *
2715
2638
  * Defaults to nestFirebaseForbiddenPermissionError().
2716
2639
  */
2717
- this.makePermissionError = nestFirebaseForbiddenPermissionError;
2640
+ makePermissionError = nestFirebaseForbiddenPermissionError;
2718
2641
  /**
2719
2642
  * FirebaseDoesNotExistErrorContextErrorFunction to use with makeModelContext().
2720
2643
  *
@@ -2723,55 +2646,56 @@ class AbstractFirebaseNestContext extends AbstractNestContext {
2723
2646
  * Some configurations may prefer to use nestFirebaseForbiddenPermissionError instead, which returns a forbidden error instead.
2724
2647
  * This prevents the leaking of information about the existence of an object.
2725
2648
  */
2726
- this.makeDoesNotExistError = nestFirebaseDoesNotExistError;
2727
- }
2728
- get envService() {
2729
- return this.nest.get(FirebaseServerEnvService);
2730
- }
2731
- get storageService() {
2732
- return this.nest.get(FirebaseServerStorageService);
2733
- }
2734
- /**
2735
- * Creates a FirebaseAppModelContext instance.
2736
- *
2737
- * @param auth
2738
- * @param buildFn
2739
- * @returns
2740
- */
2741
- makeModelContext(auth, buildFn) {
2742
- const base = {
2743
- auth: this.authService.authContextInfo(auth),
2744
- app: this.app,
2745
- makePermissionError: this.makePermissionError,
2746
- makeDoesNotExistError: this.makeDoesNotExistError
2747
- };
2748
- return buildFn ? util.build({
2749
- base,
2750
- build: buildFn
2751
- }) : base;
2752
- }
2753
- /**
2754
- * Creates a InContextFirebaseModelsService given the input context and parameters.
2755
- *
2756
- * @param context
2757
- * @param buildFn
2758
- * @returns
2759
- */
2760
- model(context, buildFn) {
2761
- const firebaseModelContext = this.makeModelContext(context, buildFn);
2762
- return firebase.inContextFirebaseModelsServiceFactory(this.firebaseModelsService)(firebaseModelContext);
2763
- }
2764
- async useModel(type, select) {
2765
- const context = this.makeModelContext(select.request, select.buildFn);
2766
- const usePromise = firebase.useFirebaseModelsService(this.firebaseModelsService, type, {
2767
- context,
2768
- key: select.key,
2769
- roles: select.roles,
2770
- rolesSetIncludes: select.rolesSetIncludes
2771
- });
2772
- const use = select.use ?? (x => x);
2773
- return usePromise(use);
2774
- }
2649
+ makeDoesNotExistError = nestFirebaseDoesNotExistError;
2650
+ get envService() {
2651
+ return this.nest.get(FirebaseServerEnvService);
2652
+ }
2653
+ get storageService() {
2654
+ return this.nest.get(FirebaseServerStorageService);
2655
+ }
2656
+ /**
2657
+ * Creates a FirebaseAppModelContext instance.
2658
+ *
2659
+ * @param auth
2660
+ * @param buildFn
2661
+ * @returns
2662
+ */
2663
+ makeModelContext(auth, buildFn) {
2664
+ const base = {
2665
+ auth: this.authService.authContextInfo(auth),
2666
+ app: this.app,
2667
+ makePermissionError: this.makePermissionError,
2668
+ makeDoesNotExistError: this.makeDoesNotExistError
2669
+ };
2670
+ return buildFn
2671
+ ? util.build({
2672
+ base,
2673
+ build: buildFn
2674
+ })
2675
+ : base;
2676
+ }
2677
+ /**
2678
+ * Creates a InContextFirebaseModelsService given the input context and parameters.
2679
+ *
2680
+ * @param context
2681
+ * @param buildFn
2682
+ * @returns
2683
+ */
2684
+ model(context, buildFn) {
2685
+ const firebaseModelContext = this.makeModelContext(context, buildFn);
2686
+ return firebase.inContextFirebaseModelsServiceFactory(this.firebaseModelsService)(firebaseModelContext);
2687
+ }
2688
+ async useModel(type, select) {
2689
+ const context = this.makeModelContext(select.request, select.buildFn);
2690
+ const usePromise = firebase.useFirebaseModelsService(this.firebaseModelsService, type, {
2691
+ context,
2692
+ key: select.key,
2693
+ roles: select.roles,
2694
+ rolesSetIncludes: select.rolesSetIncludes
2695
+ });
2696
+ const use = select.use ?? ((x) => x);
2697
+ return usePromise(use);
2698
+ }
2775
2699
  }
2776
2700
 
2777
2701
  exports.ALREADY_EXISTS_ERROR_CODE = ALREADY_EXISTS_ERROR_CODE;
@@ -2806,9 +2730,7 @@ exports.FirebaseServerStorageService = FirebaseServerStorageService;
2806
2730
  exports.INTERNAL_SERVER_ERROR_CODE = INTERNAL_SERVER_ERROR_CODE;
2807
2731
  exports.MODEL_NOT_AVAILABLE_ERROR_CODE = MODEL_NOT_AVAILABLE_ERROR_CODE;
2808
2732
  exports.NOT_FOUND_ERROR_CODE = NOT_FOUND_ERROR_CODE;
2809
- exports.NO_AUTH_ERROR_CODE = NO_AUTH_ERROR_CODE;
2810
2733
  exports.NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE = NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE;
2811
- exports.NO_UID_ERROR_CODE = NO_UID_ERROR_CODE;
2812
2734
  exports.NoSetupContentFirebaseServerNewUserService = NoSetupContentFirebaseServerNewUserService;
2813
2735
  exports.PERMISSION_DENIED_ERROR_CODE = PERMISSION_DENIED_ERROR_CODE;
2814
2736
  exports.PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE = PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE;