@data-weave/backend-firestore 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/lib/FirestoreDataManager.ts +8 -3
- package/lib/FirestoreList.ts +12 -0
- package/lib/FirestoreReference.ts +18 -1
- package/lib/firestoreTypes.ts +35 -15
- package/lib/utils.ts +39 -105
- package/lib/version.js +1 -1
- package/package.json +4 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,35 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.4.0](https://github.com/data-weave/datamanager/compare/v0.3.8...v0.4.0) (2025-10-15)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- add error interceptor ([dde95c8](https://github.com/data-weave/datamanager/commit/dde95c8dba3d02d7861d132314db4d1cf23bec37))
|
|
11
|
+
- add new typing, snapshot options and sane type defaults ([7095568](https://github.com/data-weave/datamanager/commit/7095568892048dc75cccc284e2dd2ba23793a152))
|
|
12
|
+
- create shim for modular firebase as well ([591b25a](https://github.com/data-weave/datamanager/commit/591b25a8cbcf89687b3880cc3ca1cd95a735e11d))
|
|
13
|
+
- move firebase-admin shim to it's own package ([ac9f861](https://github.com/data-weave/datamanager/commit/ac9f861ca810a2a14706e10e87674b1b1f14a964))
|
|
14
|
+
|
|
15
|
+
## [0.3.8](https://github.com/data-weave/datamanager/compare/v0.3.7...v0.3.8) (2025-09-28)
|
|
16
|
+
|
|
17
|
+
**Note:** Version bump only for package @data-weave/backend-firestore
|
|
18
|
+
|
|
19
|
+
## [0.3.7](https://github.com/data-weave/datamanager/compare/v0.3.6...v0.3.7) (2025-09-28)
|
|
20
|
+
|
|
21
|
+
**Note:** Version bump only for package @data-weave/backend-firestore
|
|
22
|
+
|
|
23
|
+
## [0.3.6](https://github.com/data-weave/datamanager/compare/v0.3.5...v0.3.6) (2025-09-28)
|
|
24
|
+
|
|
25
|
+
**Note:** Version bump only for package @data-weave/backend-firestore
|
|
26
|
+
|
|
27
|
+
## [0.3.5](https://github.com/data-weave/datamanager/compare/v0.3.4...v0.3.5) (2025-09-28)
|
|
28
|
+
|
|
29
|
+
**Note:** Version bump only for package @data-weave/backend-firestore
|
|
30
|
+
|
|
31
|
+
## [0.3.4](https://github.com/data-weave/datamanager/compare/v0.3.3...v0.3.4) (2025-09-28)
|
|
32
|
+
|
|
33
|
+
**Note:** Version bump only for package @data-weave/backend-firestore
|
|
34
|
+
|
|
6
35
|
## [0.3.3](https://github.com/data-weave/datamanager/compare/v0.3.2...v0.3.3) (2025-09-28)
|
|
7
36
|
|
|
8
37
|
**Note:** Version bump only for package @data-weave/backend-firestore
|
|
@@ -4,14 +4,14 @@ import { Cache, MapCache } from '@data-weave/datamanager/lib/Cache'
|
|
|
4
4
|
import { CreateOptions, DataManager, Metadata, WithMetadata } from '@data-weave/datamanager/lib/DataManager'
|
|
5
5
|
import { List, ListPaginationParams } from '@data-weave/datamanager/lib/List'
|
|
6
6
|
import { IdentifiableReference, WithoutId } from '@data-weave/datamanager/lib/Reference'
|
|
7
|
-
import { FirestoreList } from './FirestoreList'
|
|
7
|
+
import { FirestoreList, FirestoreListContext } from './FirestoreList'
|
|
8
8
|
import {
|
|
9
9
|
FIRESTORE_KEYS,
|
|
10
10
|
FirestoreMetadataConverter,
|
|
11
11
|
FirestoreSerializedMetadata,
|
|
12
12
|
queryNotDeleted,
|
|
13
13
|
} from './FirestoreMetadata'
|
|
14
|
-
import { FirestoreReference } from './FirestoreReference'
|
|
14
|
+
import { FirestoreReference, FirestoreReferenceContext } from './FirestoreReference'
|
|
15
15
|
import {
|
|
16
16
|
DocumentData,
|
|
17
17
|
FilterBy,
|
|
@@ -35,6 +35,8 @@ export interface FirebaseDataManagerOptions {
|
|
|
35
35
|
readonly deleteMode?: FirebaseDataManagerDeleteMode
|
|
36
36
|
readonly readMode?: FirestoreReadMode
|
|
37
37
|
readonly preventOverwriteOnCreate?: boolean
|
|
38
|
+
readonly errorInterceptor?: (error: unknown, ctx: FirestoreReferenceContext | FirestoreListContext) => void
|
|
39
|
+
readonly snapshotOptions?: FirestoreTypes.SnapshotOptions
|
|
38
40
|
// TODO: Add preventUpdateIfNotExists?
|
|
39
41
|
readonly Reference?: typeof FirestoreReference
|
|
40
42
|
readonly List?: typeof FirestoreList
|
|
@@ -58,7 +60,7 @@ export interface QueryParams<T extends FirestoreTypes.DocumentData> {
|
|
|
58
60
|
@injectable()
|
|
59
61
|
export class FirestoreDataManager<
|
|
60
62
|
T extends FirestoreTypes.DocumentData,
|
|
61
|
-
SerializedT extends FirestoreTypes.DocumentData,
|
|
63
|
+
SerializedT extends FirestoreTypes.DocumentData = T,
|
|
62
64
|
> implements DataManager<T>
|
|
63
65
|
{
|
|
64
66
|
private mergedConverter: InternalFirestoreDataConverter<T & Metadata, SerializedT & FirestoreSerializedMetadata>
|
|
@@ -195,6 +197,8 @@ export class FirestoreDataManager<
|
|
|
195
197
|
|
|
196
198
|
const newRef = new this.managerOptions.Reference(this.firestore, this.firestore.doc(this.collection, id), {
|
|
197
199
|
readMode: this.managerOptions.readMode,
|
|
200
|
+
errorInterceptor: this.managerOptions.errorInterceptor,
|
|
201
|
+
snapshotOptions: this.managerOptions.snapshotOptions,
|
|
198
202
|
})
|
|
199
203
|
this.refCache.set(id, newRef)
|
|
200
204
|
return newRef
|
|
@@ -225,6 +229,7 @@ export class FirestoreDataManager<
|
|
|
225
229
|
}
|
|
226
230
|
const newList = new this.managerOptions.List(this.firestore, compoundQuery, {
|
|
227
231
|
readMode: this.managerOptions.readMode,
|
|
232
|
+
errorInterceptor: this.managerOptions.errorInterceptor,
|
|
228
233
|
...params,
|
|
229
234
|
})
|
|
230
235
|
this.listCache.set(key, newList)
|
package/lib/FirestoreList.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { ListPaginationParams, LiveList, LiveListOptions } from '@data-weave/datamanager'
|
|
2
2
|
import { DocumentData, Firestore, FirestoreReadMode, FirestoreTypes } from './firestoreTypes'
|
|
3
3
|
|
|
4
|
+
export interface FirestoreListContext {
|
|
5
|
+
query: FirestoreTypes.Query<unknown>
|
|
6
|
+
readMode?: FirestoreReadMode
|
|
7
|
+
type: 'list'
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
export interface FirestoreListOptions<T> extends LiveListOptions<T> {
|
|
5
11
|
readMode?: FirestoreReadMode
|
|
12
|
+
errorInterceptor?: (error: unknown, ctx: FirestoreListContext) => void
|
|
6
13
|
}
|
|
7
14
|
|
|
8
15
|
export class FirestoreList<T extends DocumentData, S extends DocumentData> extends LiveList<T> {
|
|
@@ -79,6 +86,11 @@ export class FirestoreList<T extends DocumentData, S extends DocumentData> exten
|
|
|
79
86
|
// Try to provide useful collection details using internal properties
|
|
80
87
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
88
|
console.error(`FirestoreList Collection: ${(this.query as any)?._collectionPath?.id} error`, error)
|
|
89
|
+
this.options?.errorInterceptor?.(error, {
|
|
90
|
+
query: this.query,
|
|
91
|
+
readMode: this.options?.readMode,
|
|
92
|
+
type: 'list',
|
|
93
|
+
})
|
|
82
94
|
super.onError(error)
|
|
83
95
|
}
|
|
84
96
|
}
|
|
@@ -2,8 +2,18 @@ import { LiveReference, LiveReferenceOptions } from '@data-weave/datamanager'
|
|
|
2
2
|
import { DocumentData, Firestore, FirestoreReadMode, FirestoreTypes } from './firestoreTypes'
|
|
3
3
|
import { checkIfReferenceExists } from './utils'
|
|
4
4
|
|
|
5
|
+
export interface FirestoreReferenceContext {
|
|
6
|
+
path: string
|
|
7
|
+
id: string
|
|
8
|
+
readMode?: FirestoreReadMode
|
|
9
|
+
snapshotOptions?: FirestoreTypes.SnapshotOptions
|
|
10
|
+
type: 'reference'
|
|
11
|
+
}
|
|
12
|
+
|
|
5
13
|
export interface FirestoreReferenceOptions<T> extends LiveReferenceOptions<T> {
|
|
6
14
|
readMode?: FirestoreReadMode
|
|
15
|
+
snapshotOptions?: FirestoreTypes.SnapshotOptions
|
|
16
|
+
errorInterceptor?: (error: unknown, ctx: FirestoreReferenceContext) => void
|
|
7
17
|
}
|
|
8
18
|
|
|
9
19
|
export class FirestoreReference<T extends DocumentData, S extends DocumentData> extends LiveReference<T> {
|
|
@@ -60,6 +70,13 @@ export class FirestoreReference<T extends DocumentData, S extends DocumentData>
|
|
|
60
70
|
|
|
61
71
|
protected onError(error: unknown): void {
|
|
62
72
|
console.error(`FirestoreReference error ${this.docRef.path}`, error)
|
|
73
|
+
this.options?.errorInterceptor?.(error, {
|
|
74
|
+
path: this.docRef.path,
|
|
75
|
+
id: this.docRef.id,
|
|
76
|
+
readMode: this.options?.readMode,
|
|
77
|
+
snapshotOptions: this.options?.snapshotOptions,
|
|
78
|
+
type: 'reference',
|
|
79
|
+
})
|
|
63
80
|
super.onError(error)
|
|
64
81
|
}
|
|
65
82
|
|
|
@@ -70,6 +87,6 @@ export class FirestoreReference<T extends DocumentData, S extends DocumentData>
|
|
|
70
87
|
|
|
71
88
|
private parseDocumentSnapshot(docSnapshot: FirestoreTypes.DocumentSnapshot<T, S>): T | undefined {
|
|
72
89
|
if (!checkIfReferenceExists(docSnapshot)) throw new Error(`Document does not exist ${this.docRef.path}`)
|
|
73
|
-
return docSnapshot.data()
|
|
90
|
+
return docSnapshot.data(this.options?.snapshotOptions)
|
|
74
91
|
}
|
|
75
92
|
}
|
package/lib/firestoreTypes.ts
CHANGED
|
@@ -28,23 +28,38 @@ export declare interface InternalFirestoreDataConverter<
|
|
|
28
28
|
): T
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export type WithTimestamps<T> = {
|
|
32
|
+
[K in keyof T]: T[K] extends Date
|
|
33
|
+
? FirestoreTypes.Timestamp
|
|
34
|
+
: T[K] extends Date | null
|
|
35
|
+
? FirestoreTypes.Timestamp | null
|
|
36
|
+
: T[K] extends Date | undefined
|
|
37
|
+
? FirestoreTypes.Timestamp | undefined
|
|
38
|
+
: T[K] extends Date | null | undefined
|
|
39
|
+
? FirestoreTypes.Timestamp | null | undefined
|
|
40
|
+
: T[K] extends object
|
|
41
|
+
? T[K] extends any[]
|
|
42
|
+
? T[K] extends (infer U)[]
|
|
43
|
+
? WithTimestamps<U>[]
|
|
44
|
+
: T[K]
|
|
45
|
+
: WithTimestamps<T[K]>
|
|
46
|
+
: T[K]
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
/**
|
|
32
50
|
* Converts data between model and serialized data. Differs from InternalFirestoreDataConverter
|
|
33
51
|
* by using `OptionallyUndefined` and `Required` to ensure that all fields are included in de/serialization
|
|
34
52
|
* even if some model defined properties are optional.
|
|
35
53
|
*/
|
|
36
|
-
export declare interface FirestoreDataConverter<
|
|
37
|
-
T extends DocumentData,
|
|
38
|
-
SerializedT extends DocumentData = DocumentData,
|
|
39
|
-
> {
|
|
54
|
+
export declare interface FirestoreDataConverter<ModelObject, SerializedModelObject = ModelObject> {
|
|
40
55
|
toFirestore(
|
|
41
|
-
modelObject: WithoutId<
|
|
56
|
+
modelObject: WithoutId<ModelObject>,
|
|
42
57
|
options?: FirestoreTypes.SetOptions
|
|
43
|
-
): OptionallyUndefined<Required<WithoutId<WithFieldValue<
|
|
58
|
+
): OptionallyUndefined<Required<WithoutId<WithFieldValue<SerializedModelObject>>>>
|
|
44
59
|
fromFirestore(
|
|
45
|
-
snapshot: FirestoreTypes.QueryDocumentSnapshot<
|
|
60
|
+
snapshot: FirestoreTypes.QueryDocumentSnapshot<WithTimestamps<SerializedModelObject>>,
|
|
46
61
|
options?: FirestoreTypes.SnapshotOptions
|
|
47
|
-
):
|
|
62
|
+
): ModelObject
|
|
48
63
|
}
|
|
49
64
|
|
|
50
65
|
export type FirestoreQuery<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> = (
|
|
@@ -83,12 +98,15 @@ export type FilterableFields<
|
|
|
83
98
|
? // Handle firebase timestamp fields
|
|
84
99
|
T[K] extends FirestoreTypes.Timestamp
|
|
85
100
|
? `${K}`
|
|
86
|
-
: //
|
|
87
|
-
T[K] extends
|
|
88
|
-
?
|
|
89
|
-
:
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
: // Handle Date fields
|
|
102
|
+
T[K] extends Date
|
|
103
|
+
? `${K}`
|
|
104
|
+
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
T[K] extends any[]
|
|
106
|
+
? GenNode<K, IsRoot>
|
|
107
|
+
: T[K] extends object
|
|
108
|
+
? `${GenNode<K, IsRoot>}${FilterableFields<T[K], false>}`
|
|
109
|
+
: GenNode<K, IsRoot>
|
|
92
110
|
: never
|
|
93
111
|
|
|
94
112
|
type GetValue<T, K extends string> = K extends `${infer L}.${infer R}`
|
|
@@ -96,7 +114,9 @@ type GetValue<T, K extends string> = K extends `${infer L}.${infer R}`
|
|
|
96
114
|
? GetValue<T[L], R>
|
|
97
115
|
: never
|
|
98
116
|
: K extends keyof T
|
|
99
|
-
? T[K]
|
|
117
|
+
? T[K] extends Date
|
|
118
|
+
? Date | FirestoreTypes.Timestamp
|
|
119
|
+
: T[K]
|
|
100
120
|
: K extends string
|
|
101
121
|
? string | number | boolean
|
|
102
122
|
: never
|
package/lib/utils.ts
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
import { WithoutId } from '@data-weave/datamanager'
|
|
2
2
|
import {
|
|
3
3
|
DocumentData,
|
|
4
|
-
FieldValues,
|
|
5
4
|
Firestore,
|
|
6
|
-
FirestoreApp,
|
|
7
5
|
FirestoreTypes,
|
|
8
6
|
InternalFirestoreDataConverter,
|
|
9
7
|
Transaction,
|
|
10
8
|
WithFieldValue,
|
|
11
9
|
} from './firestoreTypes'
|
|
12
10
|
|
|
11
|
+
import {
|
|
12
|
+
Firestore as FirebaseFirestore,
|
|
13
|
+
collection,
|
|
14
|
+
deleteDoc,
|
|
15
|
+
doc,
|
|
16
|
+
getDoc,
|
|
17
|
+
getDocs,
|
|
18
|
+
increment,
|
|
19
|
+
limit,
|
|
20
|
+
onSnapshot,
|
|
21
|
+
orderBy,
|
|
22
|
+
query,
|
|
23
|
+
runTransaction,
|
|
24
|
+
serverTimestamp,
|
|
25
|
+
setDoc,
|
|
26
|
+
updateDoc,
|
|
27
|
+
where,
|
|
28
|
+
} from 'firebase/firestore'
|
|
29
|
+
|
|
13
30
|
export class MergeConverters<
|
|
14
31
|
T extends DocumentData,
|
|
15
32
|
SerializedT extends DocumentData,
|
|
@@ -50,111 +67,28 @@ export class MergeConverters<
|
|
|
50
67
|
}
|
|
51
68
|
}
|
|
52
69
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return reference.collection(path)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public getDocs(reference: any) {
|
|
77
|
-
return reference.get()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public getDoc(reference: any, path?: string) {
|
|
81
|
-
return reference.get(path)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public serverTimestamp() {
|
|
85
|
-
return this.fieldValues.serverTimestamp()
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public increment(n: number) {
|
|
89
|
-
return this.fieldValues.increment(n)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public query(reference: any, filter: any) {
|
|
93
|
-
if (filter.type === 'where') {
|
|
94
|
-
return reference.where(filter.field, filter.op, filter.value)
|
|
95
|
-
}
|
|
96
|
-
if (filter.type === 'orderBy') {
|
|
97
|
-
return reference.orderBy(filter.field, filter.direction)
|
|
98
|
-
}
|
|
99
|
-
if (filter.type === 'limit') {
|
|
100
|
-
return reference.limit(filter.limit)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
public where(field: string | FirestoreTypes.FieldPath, op: string, value: unknown): any {
|
|
105
|
-
return {
|
|
106
|
-
type: 'where',
|
|
107
|
-
field,
|
|
108
|
-
op,
|
|
109
|
-
value,
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public limit(limit: number) {
|
|
114
|
-
return {
|
|
115
|
-
type: 'limit',
|
|
116
|
-
limit,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
public orderBy(orderBy: string, direction: FirestoreTypes.OrderByDirection) {
|
|
121
|
-
return {
|
|
122
|
-
type: 'orderBy',
|
|
123
|
-
orderBy,
|
|
124
|
-
direction,
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
public setDoc(reference: any, data: any, options?: FirestoreTypes.SetOptions) {
|
|
129
|
-
return reference.set(data, options)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
public updateDoc(reference: any, data: any) {
|
|
133
|
-
return reference.update(data)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
public deleteDoc(reference: any) {
|
|
137
|
-
return reference.delete()
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
public doc(reference: any, path?: string) {
|
|
141
|
-
if (!path) return reference.doc()
|
|
142
|
-
return reference.doc(path)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
public onSnapshot(reference: any, onNext: (snapshot: any) => void, onError?: (error: Error) => void) {
|
|
146
|
-
return reference.onSnapshot(onNext, onError)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public runTransaction<T>(
|
|
150
|
-
firestore: FirestoreApp,
|
|
151
|
-
transaction: (transaction: Transaction) => Promise<T>,
|
|
152
|
-
options?: FirestoreTypes.TransactionOptions
|
|
153
|
-
) {
|
|
154
|
-
return firestore.runTransaction!(transaction, options)
|
|
70
|
+
export function createModularFirestoreAdapter(firestore: FirebaseFirestore): Firestore {
|
|
71
|
+
return {
|
|
72
|
+
app: firestore,
|
|
73
|
+
collection,
|
|
74
|
+
getDocs,
|
|
75
|
+
getDoc,
|
|
76
|
+
serverTimestamp,
|
|
77
|
+
query,
|
|
78
|
+
where,
|
|
79
|
+
limit,
|
|
80
|
+
orderBy,
|
|
81
|
+
setDoc,
|
|
82
|
+
updateDoc,
|
|
83
|
+
deleteDoc,
|
|
84
|
+
doc,
|
|
85
|
+
onSnapshot,
|
|
86
|
+
increment,
|
|
87
|
+
// TODO: fix this
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
+
runTransaction: runTransaction as any,
|
|
155
90
|
}
|
|
156
91
|
}
|
|
157
|
-
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
158
92
|
|
|
159
93
|
// Value can be anything
|
|
160
94
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/lib/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
module.exports = '0.
|
|
2
|
+
module.exports = '0.4.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-weave/backend-firestore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"author": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -17,12 +17,9 @@
|
|
|
17
17
|
"access": "public",
|
|
18
18
|
"registry": "https://registry.npmjs.org/"
|
|
19
19
|
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"firebase": "^11.9.0",
|
|
22
|
-
"firebase-admin": "^13.0.2"
|
|
23
|
-
},
|
|
24
20
|
"peerDependencies": {
|
|
25
|
-
"@data-weave/datamanager": "0.3.
|
|
21
|
+
"@data-weave/datamanager": "0.3.8",
|
|
22
|
+
"firebase": ">=11.0.0"
|
|
26
23
|
},
|
|
27
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "c5e5355cae5d39e7a91e17d4d30bb1e07cddedc8"
|
|
28
25
|
}
|