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