@data-weave/backend-firestore 0.7.1 → 0.7.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.
|
@@ -24,6 +24,7 @@ export declare class FirestoreDataManager<T extends FirestoreTypes.DocumentData,
|
|
|
24
24
|
private readonly converter;
|
|
25
25
|
private readonly opts?;
|
|
26
26
|
private mergedConverter;
|
|
27
|
+
private metadataConverter;
|
|
27
28
|
private collection;
|
|
28
29
|
private collectionQuery;
|
|
29
30
|
private managerOptions;
|
|
@@ -35,6 +36,15 @@ export declare class FirestoreDataManager<T extends FirestoreTypes.DocumentData,
|
|
|
35
36
|
read(id: string, options?: FirestoreReadOptions): Promise<WithMetadata<T> | undefined>;
|
|
36
37
|
create(data: WithFieldValue<WithoutId<T>>, options?: FirebaseCreateOptions): Promise<IdentifiableReference<WithMetadata<T>>>;
|
|
37
38
|
private _update;
|
|
39
|
+
/**
|
|
40
|
+
* Update only the internal metadata fields of a document.
|
|
41
|
+
*
|
|
42
|
+
* Unlike {@link _update}, this bypasses the user-provided converter so it never re-serializes
|
|
43
|
+
* (and therefore never clobbers) user data. This matters because the user converter rebuilds the
|
|
44
|
+
* full document shape, which turns absent fields into `undefined` and can overwrite existing map
|
|
45
|
+
* fields with empty objects when Firestore strips the undefined values.
|
|
46
|
+
*/
|
|
47
|
+
private _updateMetadata;
|
|
38
48
|
update(id: string, data: WithoutId<Partial<WithFieldValue<T>>>, options?: FirestoreWriteOptions): Promise<void>;
|
|
39
49
|
upsert(id: string, data: WithFieldValue<WithoutId<T>>, options?: FirestoreWriteOptions): Promise<void>;
|
|
40
50
|
count(params?: QueryParams<SerializedT>): Promise<number>;
|
|
@@ -18,6 +18,7 @@ class FirestoreDataManager {
|
|
|
18
18
|
converter;
|
|
19
19
|
opts;
|
|
20
20
|
mergedConverter;
|
|
21
|
+
metadataConverter;
|
|
21
22
|
collection;
|
|
22
23
|
collectionQuery;
|
|
23
24
|
managerOptions;
|
|
@@ -29,8 +30,9 @@ class FirestoreDataManager {
|
|
|
29
30
|
this.collectionPath = collectionPath;
|
|
30
31
|
this.converter = converter;
|
|
31
32
|
this.opts = opts;
|
|
33
|
+
this.metadataConverter = new FirestoreMetadata_1.FirestoreMetadataConverter();
|
|
32
34
|
// @ts-expect-error - Force merge FirestoreDataConverter and InternalFirestoreDataConverter
|
|
33
|
-
this.mergedConverter = new utils_1.MergeConverters(this.converter,
|
|
35
|
+
this.mergedConverter = new utils_1.MergeConverters(this.converter, this.metadataConverter);
|
|
34
36
|
this.managerOptions = this.validateOptions({ ...defaultFirebaseDataManagerOptions, ...this.opts });
|
|
35
37
|
this.refCache = this.managerOptions.refCache || new datamanager_1.MapCache(100);
|
|
36
38
|
this.listCache = this.managerOptions.listCache || new datamanager_1.MapCache(100);
|
|
@@ -109,6 +111,25 @@ class FirestoreDataManager {
|
|
|
109
111
|
}
|
|
110
112
|
return this.firestore.updateDoc(ref, serializedData);
|
|
111
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Update only the internal metadata fields of a document.
|
|
116
|
+
*
|
|
117
|
+
* Unlike {@link _update}, this bypasses the user-provided converter so it never re-serializes
|
|
118
|
+
* (and therefore never clobbers) user data. This matters because the user converter rebuilds the
|
|
119
|
+
* full document shape, which turns absent fields into `undefined` and can overwrite existing map
|
|
120
|
+
* fields with empty objects when Firestore strips the undefined values.
|
|
121
|
+
*/
|
|
122
|
+
async _updateMetadata(id, metadata, options) {
|
|
123
|
+
const serializedData = this.metadataConverter.toFirestore({
|
|
124
|
+
...metadata,
|
|
125
|
+
[FirestoreMetadata_1.FIRESTORE_KEYS.UPDATED_AT]: this.firestore.serverTimestamp(),
|
|
126
|
+
});
|
|
127
|
+
const ref = this.firestore.doc(this.collection, id);
|
|
128
|
+
if (options?.transaction) {
|
|
129
|
+
return options.transaction.update(ref, serializedData);
|
|
130
|
+
}
|
|
131
|
+
return this.firestore.updateDoc(ref, serializedData);
|
|
132
|
+
}
|
|
112
133
|
async update(id, data, options) {
|
|
113
134
|
await this._update(id, data, options);
|
|
114
135
|
}
|
|
@@ -183,10 +204,7 @@ class FirestoreDataManager {
|
|
|
183
204
|
}
|
|
184
205
|
async delete(id, options) {
|
|
185
206
|
if (this.managerOptions.deleteMode === 'soft') {
|
|
186
|
-
await this.
|
|
187
|
-
...{},
|
|
188
|
-
[FirestoreMetadata_1.FIRESTORE_KEYS.DELETED]: true,
|
|
189
|
-
}, options);
|
|
207
|
+
await this._updateMetadata(id, { [FirestoreMetadata_1.FIRESTORE_KEYS.DELETED]: true }, options);
|
|
190
208
|
return;
|
|
191
209
|
}
|
|
192
210
|
if (options?.transaction) {
|
|
@@ -16,8 +16,8 @@ export type FirestoreSerializedMetadata = {
|
|
|
16
16
|
[FIRESTORE_INTERAL_KEYS.UPDATED_AT]: FirestoreTypes.Timestamp;
|
|
17
17
|
};
|
|
18
18
|
export declare class FirestoreMetadataConverter implements InternalFirestoreDataConverter<Metadata, FirestoreSerializedMetadata> {
|
|
19
|
-
toFirestore(data: WithFieldValue<WithoutId<Metadata
|
|
20
|
-
__deleted:
|
|
19
|
+
toFirestore(data: Partial<WithFieldValue<WithoutId<Metadata>>>): {
|
|
20
|
+
__deleted: boolean;
|
|
21
21
|
__createdAt: FirestoreTypes.Timestamp;
|
|
22
22
|
__updatedAt: FirestoreTypes.Timestamp;
|
|
23
23
|
};
|
|
@@ -16,6 +16,7 @@ var FIRESTORE_KEYS;
|
|
|
16
16
|
class FirestoreMetadataConverter {
|
|
17
17
|
toFirestore(data) {
|
|
18
18
|
return {
|
|
19
|
+
// Cast: value may be absent on partial metadata writes; Firestore strips undefined fields
|
|
19
20
|
[FIRESTORE_INTERAL_KEYS.DELETED]: data[FIRESTORE_KEYS.DELETED],
|
|
20
21
|
// Cast: Firestore handles conversion from Date to Timestamp internally
|
|
21
22
|
[FIRESTORE_INTERAL_KEYS.CREATED_AT]: data[FIRESTORE_KEYS.CREATED_AT],
|
|
@@ -70,7 +70,8 @@ class FirestoreReference extends datamanager_1.LiveReference {
|
|
|
70
70
|
if (!(0, utils_1.checkIfReferenceExists)(docSnapshot))
|
|
71
71
|
throw new Error(`Document does not exist ${this.docRef.path}`);
|
|
72
72
|
const data = docSnapshot.data(this.options?.snapshotOptions);
|
|
73
|
-
|
|
73
|
+
const deletedFlag = data?.[FirestoreMetadata_1.FIRESTORE_KEYS.DELETED];
|
|
74
|
+
if (this.options?.filterDeleted && deletedFlag === true) {
|
|
74
75
|
return undefined;
|
|
75
76
|
}
|
|
76
77
|
return data;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-weave/backend-firestore",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"author": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"registry": "https://registry.npmjs.org/"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@data-weave/datamanager": "~0.7.
|
|
26
|
+
"@data-weave/datamanager": "~0.7.2",
|
|
27
27
|
"@firebase/firestore": "^4.7.8",
|
|
28
28
|
"@firebase/functions-types": "^0.6.3",
|
|
29
29
|
"@google-cloud/firestore": "^7.11.1",
|