firetender-admin 0.10.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.
Files changed (43) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +349 -0
  3. package/dist/FiretenderCollection.d.ts +116 -0
  4. package/dist/FiretenderCollection.js +225 -0
  5. package/dist/FiretenderCollection.js.map +1 -0
  6. package/dist/FiretenderDoc.d.ts +172 -0
  7. package/dist/FiretenderDoc.js +361 -0
  8. package/dist/FiretenderDoc.js.map +1 -0
  9. package/dist/errors.d.ts +30 -0
  10. package/dist/errors.js +49 -0
  11. package/dist/errors.js.map +1 -0
  12. package/dist/firestore-deps-admin.d.ts +26 -0
  13. package/dist/firestore-deps-admin.js +62 -0
  14. package/dist/firestore-deps-admin.js.map +1 -0
  15. package/dist/firestore-deps-web.d.ts +10 -0
  16. package/dist/firestore-deps-web.js +29 -0
  17. package/dist/firestore-deps-web.js.map +1 -0
  18. package/dist/firestore-deps.d.ts +26 -0
  19. package/dist/firestore-deps.js +62 -0
  20. package/dist/firestore-deps.js.map +1 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.js +18 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/proxies.d.ts +62 -0
  25. package/dist/proxies.js +243 -0
  26. package/dist/proxies.js.map +1 -0
  27. package/dist/timestamps.d.ts +37 -0
  28. package/dist/timestamps.js +58 -0
  29. package/dist/timestamps.js.map +1 -0
  30. package/dist/ts-helpers.d.ts +14 -0
  31. package/dist/ts-helpers.js +19 -0
  32. package/dist/ts-helpers.js.map +1 -0
  33. package/package.json +72 -0
  34. package/src/FiretenderCollection.ts +311 -0
  35. package/src/FiretenderDoc.ts +483 -0
  36. package/src/errors.ts +47 -0
  37. package/src/firestore-deps-admin.ts +111 -0
  38. package/src/firestore-deps-web.ts +14 -0
  39. package/src/firestore-deps.ts +111 -0
  40. package/src/index.ts +29 -0
  41. package/src/proxies.ts +286 -0
  42. package/src/timestamps.ts +62 -0
  43. package/src/ts-helpers.ts +39 -0
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ /**
3
+ * Provides all dependencies normally imported from "firebase/firestore".
4
+ *
5
+ * For web clients, the "firebase/firestore" API is simply re-exported.
6
+ *
7
+ * For the server client API, ...
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.updateDoc = exports.setDoc = exports.query = exports.getDocs = exports.getDoc = exports.doc = exports.deleteDoc = exports.collectionGroup = exports.collection = exports.addDoc = exports.isServerTimestamp = exports.serverTimestamp = exports.deleteField = exports.arrayRemove = exports.where = exports.Timestamp = exports.QuerySnapshot = exports.Query = exports.Firestore = exports.DocumentSnapshot = exports.DocumentReference = exports.CollectionReference = exports.FIRESTORE_DEPS_TYPE = void 0;
11
+ const firestore_1 = require("@google-cloud/firestore");
12
+ Object.defineProperty(exports, "CollectionReference", { enumerable: true, get: function () { return firestore_1.CollectionReference; } });
13
+ Object.defineProperty(exports, "DocumentReference", { enumerable: true, get: function () { return firestore_1.DocumentReference; } });
14
+ Object.defineProperty(exports, "DocumentSnapshot", { enumerable: true, get: function () { return firestore_1.DocumentSnapshot; } });
15
+ Object.defineProperty(exports, "Firestore", { enumerable: true, get: function () { return firestore_1.Firestore; } });
16
+ Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return firestore_1.Query; } });
17
+ Object.defineProperty(exports, "QuerySnapshot", { enumerable: true, get: function () { return firestore_1.QuerySnapshot; } });
18
+ Object.defineProperty(exports, "Timestamp", { enumerable: true, get: function () { return firestore_1.Timestamp; } });
19
+ exports.FIRESTORE_DEPS_TYPE = "admin";
20
+ exports.where = firestore_1.Filter.where;
21
+ exports.arrayRemove = firestore_1.FieldValue.arrayRemove;
22
+ exports.deleteField = firestore_1.FieldValue.delete;
23
+ exports.serverTimestamp = firestore_1.FieldValue.serverTimestamp;
24
+ const isServerTimestamp = (x) => x instanceof firestore_1.FieldValue;
25
+ exports.isServerTimestamp = isServerTimestamp;
26
+ const addDoc = (ref, data) => ref.add(data);
27
+ exports.addDoc = addDoc;
28
+ const collection = (firestoreOrRef, path, ...pathSegments) => firestoreOrRef instanceof firestore_1.Firestore
29
+ ? firestoreOrRef.collection([path, ...pathSegments].join("/"))
30
+ : firestoreOrRef.firestore.collection([firestoreOrRef.path, path, ...pathSegments].join("/"));
31
+ exports.collection = collection;
32
+ const collectionGroup = (firestore, collectionID) => firestore.collectionGroup(collectionID);
33
+ exports.collectionGroup = collectionGroup;
34
+ const deleteDoc = async (ref) => {
35
+ await ref.delete();
36
+ };
37
+ exports.deleteDoc = deleteDoc;
38
+ const doc = (firestoreOrRef, path, ...pathSegments) => firestoreOrRef instanceof firestore_1.Firestore
39
+ ? firestoreOrRef.doc([path, ...pathSegments].join("/"))
40
+ : path
41
+ ? firestoreOrRef.doc([path, ...pathSegments].join("/"))
42
+ : firestoreOrRef.doc();
43
+ exports.doc = doc;
44
+ const getDoc = (ref) => ref.get();
45
+ exports.getDoc = getDoc;
46
+ const getDocs = (query) => query.get();
47
+ exports.getDocs = getDocs;
48
+ const query = (ref, ...queryConstraints) => queryConstraints.length === 0
49
+ ? ref
50
+ : queryConstraints.length === 1
51
+ ? ref.where(queryConstraints[0])
52
+ : ref.where(firestore_1.Filter.and(...queryConstraints));
53
+ exports.query = query;
54
+ const setDoc = async (ref, data) => {
55
+ await ref.set(data);
56
+ };
57
+ exports.setDoc = setDoc;
58
+ const updateDoc = async (ref, data) => {
59
+ await ref.update(data);
60
+ };
61
+ exports.updateDoc = updateDoc;
62
+ //# sourceMappingURL=firestore-deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firestore-deps.js","sourceRoot":"","sources":["../src/firestore-deps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { FiretenderError, FiretenderInternalError, FiretenderIOError, FiretenderUsageError } from "./errors";
2
+ import { FiretenderCollection } from "./FiretenderCollection";
3
+ import type { FiretenderDocOptions } from "./FiretenderDoc";
4
+ import { FiretenderDoc } from "./FiretenderDoc";
5
+ import { futureTimestampDays, serverTimestamp, serverTimestampWithClientTime, timestampSchema } from "./timestamps";
6
+ export { FiretenderCollection, FiretenderDoc, FiretenderDocOptions, FiretenderError, FiretenderInternalError, FiretenderIOError, FiretenderUsageError, futureTimestampDays, serverTimestamp, serverTimestampWithClientTime, timestampSchema, };
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timestampSchema = exports.serverTimestampWithClientTime = exports.serverTimestamp = exports.futureTimestampDays = exports.FiretenderUsageError = exports.FiretenderIOError = exports.FiretenderInternalError = exports.FiretenderError = exports.FiretenderDoc = exports.FiretenderCollection = void 0;
4
+ const errors_1 = require("./errors");
5
+ Object.defineProperty(exports, "FiretenderError", { enumerable: true, get: function () { return errors_1.FiretenderError; } });
6
+ Object.defineProperty(exports, "FiretenderInternalError", { enumerable: true, get: function () { return errors_1.FiretenderInternalError; } });
7
+ Object.defineProperty(exports, "FiretenderIOError", { enumerable: true, get: function () { return errors_1.FiretenderIOError; } });
8
+ Object.defineProperty(exports, "FiretenderUsageError", { enumerable: true, get: function () { return errors_1.FiretenderUsageError; } });
9
+ const FiretenderCollection_1 = require("./FiretenderCollection");
10
+ Object.defineProperty(exports, "FiretenderCollection", { enumerable: true, get: function () { return FiretenderCollection_1.FiretenderCollection; } });
11
+ const FiretenderDoc_1 = require("./FiretenderDoc");
12
+ Object.defineProperty(exports, "FiretenderDoc", { enumerable: true, get: function () { return FiretenderDoc_1.FiretenderDoc; } });
13
+ const timestamps_1 = require("./timestamps");
14
+ Object.defineProperty(exports, "futureTimestampDays", { enumerable: true, get: function () { return timestamps_1.futureTimestampDays; } });
15
+ Object.defineProperty(exports, "serverTimestamp", { enumerable: true, get: function () { return timestamps_1.serverTimestamp; } });
16
+ Object.defineProperty(exports, "serverTimestampWithClientTime", { enumerable: true, get: function () { return timestamps_1.serverTimestampWithClientTime; } });
17
+ Object.defineProperty(exports, "timestampSchema", { enumerable: true, get: function () { return timestamps_1.timestampSchema; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAKkB;AAehB,gGAnBA,wBAAe,OAmBA;AACf,wGAnBA,gCAAuB,OAmBA;AACvB,kGAnBA,0BAAiB,OAmBA;AACjB,qGAnBA,6BAAoB,OAmBA;AAjBtB,iEAA8D;AAW5D,qGAXO,2CAAoB,OAWP;AATtB,mDAAgD;AAU9C,8FAVO,6BAAa,OAUP;AATf,6CAKsB;AAUpB,oGAdA,gCAAmB,OAcA;AACnB,gGAdA,4BAAe,OAcA;AACf,8GAdA,0CAA6B,OAcA;AAC7B,gGAdA,4BAAe,OAcA"}
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Wraps a top-level array, its elements, or its elements' subfields in a proxy
4
+ * that watches for changes.
5
+ *
6
+ * Firestore supports limited modification of arrays; see the 2018 blog entry at
7
+ * https://firebase.blog/posts/2018/08/better-arrays-in-cloud-firestore for
8
+ * details and some history. The tl;dr is that we can't update array entries;
9
+ * we can only append or remove them.
10
+ *
11
+ * For this reason, this proxy only works with top-level arrays: the wrapped
12
+ * array cannot be inside a parent array, though it may be in a record or nested
13
+ * records. Child proxies maintain a link to the top-level array and trigger a
14
+ * rewrite of the whole thing if there are any changes to the contents. As a
15
+ * consequence, the watchFieldForChanges proxy (below) can produce child
16
+ * watchArrayForChanges proxies, but all children of watchArrayForChanges will
17
+ * always use the watchArrayForChanges proxy to maintain a reference to the
18
+ * top-level array.
19
+ *
20
+ * Appending an element to the top-level array could in theory be supported, but
21
+ * Firestore's arrayUnion operator only appends entries that don't already
22
+ * exist. That is not how Javascript arrays work, so to reduce logical overhead
23
+ * we don't bother with it.
24
+ *
25
+ * Deletion of entries in the top-level array are handled using Firestore's
26
+ * arrayRemove operator. The deleted element gets removed entirely, so the
27
+ * resulting array remains dense. Note that this behavior differs from how
28
+ * Javascript's delete operator normally works with arrays, but here we favor
29
+ * Firestore's array semantics.
30
+ *
31
+ * @param arrayPath the dot-delimited path of the top-level array.
32
+ * @param array a reference to the top-level array.
33
+ * @param fieldSchema schema of the array element or a field nested within it.
34
+ * @param field reference to the array element or one of its subfields.
35
+ * @param addToUpdateList callback to register modifications to this array.
36
+ */
37
+ export declare function watchArrayForChanges<ArrayElementType, FieldSchemaType extends z.ZodTypeAny>(arrayPath: string[], array: ArrayElementType[], fieldSchema: FieldSchemaType, field: z.infer<FieldSchemaType>, addToUpdateList: (path: string[], newValue: any) => void): z.infer<FieldSchemaType>;
38
+ /**
39
+ * Wraps an object based on a Zod schema in a proxy that watches for changes.
40
+ *
41
+ * Nested fields are monitored by creating a chain of proxies. Consider this
42
+ * case:
43
+ *
44
+ * testDoc.w.record1.record2.someStringValue = "foo";
45
+ *
46
+ * There is a top-level proxy (call it proxy 0) for the ".w" accessor. Getting
47
+ * ".record1" from it returns a child proxy (1) wrapping that field. Getting
48
+ * ".record2" from that returns another child proxy (2) wrapping that subfield.
49
+ * Finally, setting ".someStringValue" uses the setter of proxy 2 to set the new
50
+ * value locally and register an update to be sent to Firestore.
51
+ *
52
+ * The proxy returned by watchFieldForChanges is used for fields and subfields
53
+ * when no parent is an array. If a field or subfield is an array, the proxy
54
+ * returned by watchArrayForChanges is used for it and all of its children,
55
+ * regardless of whether they are arrays.
56
+ *
57
+ * @param fieldPath the dot-delimited path of the object being wrapped.
58
+ * @param fieldSchema schema of the object's field.
59
+ * @param field reference to the field in the local document data.
60
+ * @param addToUpdateList callback to register modifications to this field.
61
+ */
62
+ export declare function watchFieldForChanges<FieldSchemaType extends z.ZodTypeAny>(fieldPath: string[], fieldSchema: FieldSchemaType, field: z.infer<FieldSchemaType>, addToUpdateList: (path: string[], newValue: any) => void): z.infer<FieldSchemaType>;
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.watchFieldForChanges = exports.watchArrayForChanges = void 0;
4
+ const zod_1 = require("zod");
5
+ const firestore_deps_1 = require("./firestore-deps");
6
+ const ts_helpers_1 = require("./ts-helpers");
7
+ /**
8
+ * Given a Zod schema representing a collection, returns the sub-schema of the
9
+ * specified property.
10
+ */
11
+ function getPropertySchema(parent, parentSchema, propertyKey) {
12
+ let schema = parentSchema;
13
+ // eslint-disable-next-line no-constant-condition
14
+ while (true) {
15
+ switch (schema._def.typeName) {
16
+ // If the schema object is wrapped (e.g., by being optional or having a
17
+ // default), unwrap it until we get to the underlying collection type.
18
+ case zod_1.z.ZodFirstPartyTypeKind.ZodOptional:
19
+ case zod_1.z.ZodFirstPartyTypeKind.ZodNullable:
20
+ schema = schema.unwrap();
21
+ continue;
22
+ case zod_1.z.ZodFirstPartyTypeKind.ZodDefault:
23
+ schema = schema.removeDefault();
24
+ continue;
25
+ case zod_1.z.ZodFirstPartyTypeKind.ZodEffects:
26
+ schema = schema.innerType();
27
+ continue;
28
+ // Return the sub-schemas of supported collection types.
29
+ case zod_1.z.ZodFirstPartyTypeKind.ZodRecord:
30
+ if (schema.keySchema._def.typeName !== zod_1.z.ZodFirstPartyTypeKind.ZodString) {
31
+ throw TypeError(`The ZodRecord for property ${propertyKey} has keys of type ${schema.keySchema._def.typeName}. Only strings are supported.`);
32
+ }
33
+ return schema.valueSchema;
34
+ case zod_1.z.ZodFirstPartyTypeKind.ZodArray:
35
+ return schema.element;
36
+ case zod_1.z.ZodFirstPartyTypeKind.ZodObject:
37
+ return schema.shape[propertyKey];
38
+ case zod_1.z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion:
39
+ return schema.optionsMap.get(parent[schema.discriminator]);
40
+ // If the parent is of type ZodAny, so are its properties.
41
+ case zod_1.z.ZodFirstPartyTypeKind.ZodAny:
42
+ return zod_1.z.any();
43
+ default:
44
+ throw TypeError(`Unsupported schema type for property "${propertyKey}": ${schema._def.typeName}`);
45
+ }
46
+ }
47
+ }
48
+ /**
49
+ * Getting this symbol from one of our proxies returns the proxy's target.
50
+ */
51
+ const PROXY_TARGET_SYMBOL = Symbol("proxy_target");
52
+ /**
53
+ * Wraps a top-level array, its elements, or its elements' subfields in a proxy
54
+ * that watches for changes.
55
+ *
56
+ * Firestore supports limited modification of arrays; see the 2018 blog entry at
57
+ * https://firebase.blog/posts/2018/08/better-arrays-in-cloud-firestore for
58
+ * details and some history. The tl;dr is that we can't update array entries;
59
+ * we can only append or remove them.
60
+ *
61
+ * For this reason, this proxy only works with top-level arrays: the wrapped
62
+ * array cannot be inside a parent array, though it may be in a record or nested
63
+ * records. Child proxies maintain a link to the top-level array and trigger a
64
+ * rewrite of the whole thing if there are any changes to the contents. As a
65
+ * consequence, the watchFieldForChanges proxy (below) can produce child
66
+ * watchArrayForChanges proxies, but all children of watchArrayForChanges will
67
+ * always use the watchArrayForChanges proxy to maintain a reference to the
68
+ * top-level array.
69
+ *
70
+ * Appending an element to the top-level array could in theory be supported, but
71
+ * Firestore's arrayUnion operator only appends entries that don't already
72
+ * exist. That is not how Javascript arrays work, so to reduce logical overhead
73
+ * we don't bother with it.
74
+ *
75
+ * Deletion of entries in the top-level array are handled using Firestore's
76
+ * arrayRemove operator. The deleted element gets removed entirely, so the
77
+ * resulting array remains dense. Note that this behavior differs from how
78
+ * Javascript's delete operator normally works with arrays, but here we favor
79
+ * Firestore's array semantics.
80
+ *
81
+ * @param arrayPath the dot-delimited path of the top-level array.
82
+ * @param array a reference to the top-level array.
83
+ * @param fieldSchema schema of the array element or a field nested within it.
84
+ * @param field reference to the array element or one of its subfields.
85
+ * @param addToUpdateList callback to register modifications to this array.
86
+ */
87
+ function watchArrayForChanges(arrayPath, array, fieldSchema, field, addToUpdateList) {
88
+ return new Proxy(field, {
89
+ get(target, propertyKey) {
90
+ const property = target[propertyKey];
91
+ if (property instanceof Function) {
92
+ // All methods of an array or its children are presumed to make
93
+ // modifications, thus triggering an update of the full array.
94
+ // TODO: #11 Only mark the change for mutating function calls.
95
+ const result = (...args) => property.apply(field, args);
96
+ addToUpdateList(arrayPath, array);
97
+ return result;
98
+ }
99
+ if (typeof propertyKey === "symbol") {
100
+ if (propertyKey === PROXY_TARGET_SYMBOL) {
101
+ return target;
102
+ }
103
+ // Allow all other symbols to pass through.
104
+ return property;
105
+ }
106
+ if (property instanceof Object) {
107
+ // Wrap nested objects, including nested arrays, in child proxies.
108
+ return watchArrayForChanges(arrayPath, array, getPropertySchema(field, fieldSchema, propertyKey), property, addToUpdateList);
109
+ }
110
+ // Otherwise we must be getting a primitive. No need to wrap it.
111
+ return property;
112
+ },
113
+ set(target, propertyKey, value) {
114
+ if (typeof propertyKey === "symbol") {
115
+ // Allow symbols to pass through.
116
+ return Reflect.set(target, propertyKey, value);
117
+ }
118
+ let processedValue = value;
119
+ // If the new value is an object wrapped in a Firetender proxy, which can
120
+ // commonly happen when referencing it inside a mutator function passed to
121
+ // FiretenderDoc.prototype.update(), unwrap it.
122
+ if (value instanceof Object) {
123
+ const valueTarget = value[PROXY_TARGET_SYMBOL];
124
+ if (valueTarget !== undefined) {
125
+ processedValue = valueTarget;
126
+ }
127
+ }
128
+ // An array element or one of its subfields is being set to a new value.
129
+ // Parse the new value with the appropriate schema, set it in the local
130
+ // data, and mark the entire top-level array as needing to be written.
131
+ const propertySchema = getPropertySchema(field, fieldSchema, propertyKey);
132
+ processedValue = propertySchema.parse(processedValue);
133
+ const result = Reflect.set(target, propertyKey, processedValue);
134
+ addToUpdateList(arrayPath, array);
135
+ return result;
136
+ },
137
+ deleteProperty(target, propertyKey) {
138
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
139
+ // Calling Reflect.deleteProperty on an array item sets it to undefined,
140
+ // which causes Firestore updates to fail unless ignoreUndefinedProperties
141
+ // is set, and which is generally not what we want. Hence splice.
142
+ const removedValues = array.splice(Number(propertyKey), 1);
143
+ if (removedValues.length !== 1) {
144
+ throw RangeError(`Failed to delete array item with index ${propertyKey}. Out of bounds?`);
145
+ }
146
+ // Only top-level elements can be deleted with Firestore's arrayRemove.
147
+ if (target === array) {
148
+ addToUpdateList(arrayPath, (0, firestore_deps_1.arrayRemove)(removedValues[0]));
149
+ }
150
+ else {
151
+ addToUpdateList(arrayPath, array);
152
+ }
153
+ return true;
154
+ },
155
+ });
156
+ }
157
+ exports.watchArrayForChanges = watchArrayForChanges;
158
+ /**
159
+ * Wraps an object based on a Zod schema in a proxy that watches for changes.
160
+ *
161
+ * Nested fields are monitored by creating a chain of proxies. Consider this
162
+ * case:
163
+ *
164
+ * testDoc.w.record1.record2.someStringValue = "foo";
165
+ *
166
+ * There is a top-level proxy (call it proxy 0) for the ".w" accessor. Getting
167
+ * ".record1" from it returns a child proxy (1) wrapping that field. Getting
168
+ * ".record2" from that returns another child proxy (2) wrapping that subfield.
169
+ * Finally, setting ".someStringValue" uses the setter of proxy 2 to set the new
170
+ * value locally and register an update to be sent to Firestore.
171
+ *
172
+ * The proxy returned by watchFieldForChanges is used for fields and subfields
173
+ * when no parent is an array. If a field or subfield is an array, the proxy
174
+ * returned by watchArrayForChanges is used for it and all of its children,
175
+ * regardless of whether they are arrays.
176
+ *
177
+ * @param fieldPath the dot-delimited path of the object being wrapped.
178
+ * @param fieldSchema schema of the object's field.
179
+ * @param field reference to the field in the local document data.
180
+ * @param addToUpdateList callback to register modifications to this field.
181
+ */
182
+ function watchFieldForChanges(fieldPath, fieldSchema, field, addToUpdateList) {
183
+ return new Proxy(field, {
184
+ get(target, propertyKey) {
185
+ const property = target[propertyKey];
186
+ if (property instanceof Function) {
187
+ // Provide methods with a "this" reference for the underlying field.
188
+ return (...args) => property.apply(field, args);
189
+ }
190
+ if (typeof propertyKey === "symbol") {
191
+ if (propertyKey === PROXY_TARGET_SYMBOL) {
192
+ return target;
193
+ }
194
+ // Allow all other symbols to pass through.
195
+ return property;
196
+ }
197
+ if (property instanceof Array) {
198
+ // Wrap array subfields in the watchArrayForChanges proxy. It is
199
+ // necessarily a top-level array, because otherwise we would be in
200
+ // watchArrayForChanges already.
201
+ return watchArrayForChanges([...fieldPath, propertyKey], property, getPropertySchema(field, fieldSchema, propertyKey), property, addToUpdateList);
202
+ }
203
+ if (property instanceof Object) {
204
+ // Wrap nested objects in another instance of this proxy.
205
+ return watchFieldForChanges([...fieldPath, propertyKey], getPropertySchema(field, fieldSchema, propertyKey), property, addToUpdateList);
206
+ }
207
+ // Otherwise we must be getting a primitive. No need to wrap it.
208
+ return property;
209
+ },
210
+ set(target, propertyKey, value) {
211
+ if (typeof propertyKey === "symbol") {
212
+ // Allow symbols to pass through.
213
+ return Reflect.set(target, propertyKey, value);
214
+ }
215
+ let processedValue = value;
216
+ // If the new value is an object wrapped in a Firetender proxy, which can
217
+ // commonly happen when referencing it inside a mutator function passed to
218
+ // FiretenderDoc.prototype.update(), unwrap it.
219
+ if (value instanceof Object) {
220
+ const valueTarget = value[PROXY_TARGET_SYMBOL];
221
+ if (valueTarget !== undefined) {
222
+ processedValue = valueTarget;
223
+ }
224
+ }
225
+ // A property of this object is being set to a new value. Parse the new
226
+ // value with the appropriate schema, set it in the local data, and mark
227
+ // the entire top-level array as needing to be written.
228
+ const propertySchema = getPropertySchema(field, fieldSchema, propertyKey);
229
+ processedValue = propertySchema.parse(processedValue);
230
+ addToUpdateList([...fieldPath, propertyKey], processedValue);
231
+ return Reflect.set(target, propertyKey, processedValue);
232
+ },
233
+ deleteProperty(target, propertyKey) {
234
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
235
+ // Delete the field in Firestore by marking it with the deleteField
236
+ // operator.
237
+ addToUpdateList([...fieldPath, propertyKey], (0, firestore_deps_1.deleteField)());
238
+ return Reflect.deleteProperty(target, propertyKey);
239
+ },
240
+ });
241
+ }
242
+ exports.watchFieldForChanges = watchFieldForChanges;
243
+ //# sourceMappingURL=proxies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ import { Timestamp } from "./firestore-deps";
3
+ /**
4
+ * Timestamp representation used by Firestore: seconds and nanoseconds since the
5
+ * epoch.
6
+ */
7
+ export declare const timestampSchema: z.ZodType<Timestamp, z.ZodTypeDef, Timestamp>;
8
+ /**
9
+ * Returns a Firestore Timestamp for some future date. The result is typically
10
+ * used for writing TTLs.
11
+ *
12
+ * The client's clock (specifically `Date.now()`) is used to generate the
13
+ * timestamp. For TTLs days in the future, this is generally not a concern.
14
+ * However, this function should not be depended on for short offsets.
15
+ *
16
+ * @param daysFromNow days in the future to set this Timestamp.
17
+ */
18
+ export declare function futureTimestampDays(daysFromNow: number): Timestamp;
19
+ /**
20
+ * Returns a sentinel to include a server-generated timestamp in the written
21
+ * data.
22
+ *
23
+ * Note that the sentinel, despite being typed as a Timestamp, has none of that
24
+ * class's properties or methods. For a sentinel that can be immediately used
25
+ * as a Timestamp, see {@link serverTimestampWithClientTime}.
26
+ */
27
+ export declare function serverTimestamp(): Timestamp;
28
+ /**
29
+ * Returns a sentinel to include a server-generated timestamp in the written
30
+ * data. The returned object also includes all properties and methods of
31
+ * Timestamp, allowing its immediate use without retrieving the server-set time.
32
+ *
33
+ * Note that the time returned by the Timestamp methods will likely differ from
34
+ * the time set by the server. It may differ substantially if the client's
35
+ * clock is incorrect. Caveat coder.
36
+ */
37
+ export declare function serverTimestampWithClientTime(): Timestamp;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serverTimestampWithClientTime = exports.serverTimestamp = exports.futureTimestampDays = exports.timestampSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const firestore_deps_1 = require("./firestore-deps");
6
+ /**
7
+ * Timestamp representation used by Firestore: seconds and nanoseconds since the
8
+ * epoch.
9
+ */
10
+ exports.timestampSchema = zod_1.z.custom((data) => data instanceof firestore_deps_1.Timestamp || (0, firestore_deps_1.isServerTimestamp)(data));
11
+ /**
12
+ * Returns a Firestore Timestamp for some future date. The result is typically
13
+ * used for writing TTLs.
14
+ *
15
+ * The client's clock (specifically `Date.now()`) is used to generate the
16
+ * timestamp. For TTLs days in the future, this is generally not a concern.
17
+ * However, this function should not be depended on for short offsets.
18
+ *
19
+ * @param daysFromNow days in the future to set this Timestamp.
20
+ */
21
+ function futureTimestampDays(daysFromNow) {
22
+ return firestore_deps_1.Timestamp.fromMillis(Date.now() + daysFromNow * 24 * 60 * 60 * 1000);
23
+ }
24
+ exports.futureTimestampDays = futureTimestampDays;
25
+ /**
26
+ * Returns a sentinel to include a server-generated timestamp in the written
27
+ * data.
28
+ *
29
+ * Note that the sentinel, despite being typed as a Timestamp, has none of that
30
+ * class's properties or methods. For a sentinel that can be immediately used
31
+ * as a Timestamp, see {@link serverTimestampWithClientTime}.
32
+ */
33
+ function serverTimestamp() {
34
+ return (0, firestore_deps_1.serverTimestamp)();
35
+ }
36
+ exports.serverTimestamp = serverTimestamp;
37
+ /**
38
+ * Returns a sentinel to include a server-generated timestamp in the written
39
+ * data. The returned object also includes all properties and methods of
40
+ * Timestamp, allowing its immediate use without retrieving the server-set time.
41
+ *
42
+ * Note that the time returned by the Timestamp methods will likely differ from
43
+ * the time set by the server. It may differ substantially if the client's
44
+ * clock is incorrect. Caveat coder.
45
+ */
46
+ function serverTimestampWithClientTime() {
47
+ const sentinel = (0, firestore_deps_1.serverTimestamp)();
48
+ const timestamp = firestore_deps_1.Timestamp.now();
49
+ Object.assign(sentinel, timestamp);
50
+ sentinel.isEqual = (other) => timestamp.isEqual(other);
51
+ sentinel.toDate = () => timestamp.toDate();
52
+ sentinel.toMillis = () => timestamp.toMillis();
53
+ sentinel.toString = () => timestamp.toString();
54
+ sentinel.valueOf = () => timestamp.valueOf();
55
+ return sentinel;
56
+ }
57
+ exports.serverTimestampWithClientTime = serverTimestampWithClientTime;
58
+ //# sourceMappingURL=timestamps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timestamps.js","sourceRoot":"","sources":["../src/timestamps.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,qDAI0B;AAE1B;;;GAGG;AACU,QAAA,eAAe,GAAG,OAAC,CAAC,MAAM,CACrC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,YAAY,0BAAS,IAAI,IAAA,kCAAiB,EAAC,IAAI,CAAC,CACpE,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,WAAmB;IACrD,OAAO,0BAAS,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAC9E,CAAC;AAFD,kDAEC;AAED;;;;;;;GAOG;AACH,SAAgB,eAAe;IAC7B,OAAO,IAAA,gCAAwB,GAAe,CAAC;AACjD,CAAC;AAFD,0CAEC;AAED;;;;;;;;GAQG;AACH,SAAgB,6BAA6B;IAC3C,MAAM,QAAQ,GAAG,IAAA,gCAAwB,GAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,0BAAS,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAClC,QAAgB,CAAC,OAAO,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1E,QAAgB,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;IACnD,QAAgB,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACvD,QAAgB,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACvD,QAAgB,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IACtD,OAAO,QAAqB,CAAC;AAC/B,CAAC;AAVD,sEAUC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Typescript-related helper functions and types.
3
+ */
4
+ export type DeepPartial<T> = T extends object ? {
5
+ [K in keyof T]?: DeepPartial<T[K]>;
6
+ } : T;
7
+ export type DeepReadonly<T> = T extends Array<infer ArrKey> ? ReadonlyArray<DeepReadonly<ArrKey>> : T extends Map<infer MapKey, infer MapVal> ? ReadonlyMap<DeepReadonly<MapKey>, DeepReadonly<MapVal>> : T extends Set<infer SetKey> ? ReadonlySet<DeepReadonly<SetKey>> : T extends Record<any, unknown> ? {
8
+ readonly [ObjKey in keyof T]: DeepReadonly<T[ObjKey]>;
9
+ } : T;
10
+ export type MakeFieldsWithDefaultsOptional<T> = T extends Array<infer ArrKey> ? ReadonlyArray<DeepReadonly<ArrKey>> : T extends Map<infer MapKey, infer MapVal> ? ReadonlyMap<DeepReadonly<MapKey>, DeepReadonly<MapVal>> : T extends Set<infer SetKey> ? ReadonlySet<DeepReadonly<SetKey>> : T extends Record<any, unknown> ? {
11
+ readonly [ObjKey in keyof T]: DeepReadonly<T[ObjKey]>;
12
+ } : T;
13
+ export declare function assertIsDefined<T>(value: T): asserts value is NonNullable<T>;
14
+ export declare function assertKeyIsString(key: any): asserts key is string;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * Typescript-related helper functions and types.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.assertKeyIsString = exports.assertIsDefined = void 0;
7
+ function assertIsDefined(value) {
8
+ if (value === undefined || value === null) {
9
+ throw new TypeError(`${value} is not defined`);
10
+ }
11
+ }
12
+ exports.assertIsDefined = assertIsDefined;
13
+ function assertKeyIsString(key) {
14
+ if (typeof key !== "string") {
15
+ throw TypeError("Property access using symbols is not supported.");
16
+ }
17
+ }
18
+ exports.assertKeyIsString = assertKeyIsString;
19
+ //# sourceMappingURL=ts-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-helpers.js","sourceRoot":"","sources":["../src/ts-helpers.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA0BH,SAAgB,eAAe,CAAI,KAAQ;IACzC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;QACzC,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC;KAChD;AACH,CAAC;AAJD,0CAIC;AAED,SAAgB,iBAAiB,CAAC,GAAQ;IACxC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC3B,MAAM,SAAS,CAAC,iDAAiD,CAAC,CAAC;KACpE;AACH,CAAC;AAJD,8CAIC"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "firetender-admin",
3
+ "displayName": "Firetender (for firebase-admin/firestore)",
4
+ "description": "Typescript wrapper for Firestore documents",
5
+ "version": "0.10.0",
6
+ "author": "Jake Hartman",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/jakes-space/firetender",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/jakes-space/firetender.git"
12
+ },
13
+ "keywords": [
14
+ "firestore",
15
+ "typescript",
16
+ "schema"
17
+ ],
18
+ "types": "./dist/index.d.ts",
19
+ "main": "./dist/index.js",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "/dist",
29
+ "/src/*.ts"
30
+ ],
31
+ "scripts": {
32
+ "use-web-firestore": "cp package-web.json package.json && cp src/firestore-deps-web.ts src/firestore-deps.ts && npm install",
33
+ "use-admin-firestore": "echo Already using admin firestore.",
34
+ "diff-web-admin": "diff package-web.json package-admin.json",
35
+ "lint:check": "eslint src --ext .ts",
36
+ "lint:fix": "eslint --fix src --ext .ts",
37
+ "prettier:check": "prettier --check src/*.ts src/**/*.ts",
38
+ "prettier:fix": "prettier --write src/*.ts src/**/*.ts",
39
+ "check": "npm run lint:check && npm run prettier:check",
40
+ "fix": "npm run lint:fix && npm run prettier:fix",
41
+ "emulate-db": "firebase emulators:start --project=firetender",
42
+ "test": "jest --forceExit --detectOpenHandles",
43
+ "prepare": "husky install",
44
+ "clean": "rm -rf dist/*",
45
+ "build": "npm run clean && tsc && rm -rf dist/__tests__",
46
+ "prepublishOnly": "npm run check && npm run test && npm run build"
47
+ },
48
+ "dependencies": {
49
+ "firebase-admin": "^11.6.0",
50
+ "zod": "^3.20.6"
51
+ },
52
+ "devDependencies": {
53
+ "@firebase/rules-unit-testing": "^2.0.7",
54
+ "@rushstack/eslint-patch": "^1.2.0",
55
+ "@types/jest": "^29.4.0",
56
+ "@typescript-eslint/eslint-plugin": "^5.54.0",
57
+ "@typescript-eslint/parser": "^5.54.0",
58
+ "eslint": "^8.35.0",
59
+ "eslint-config-prettier": "^8.6.0",
60
+ "eslint-import-resolver-typescript": "^3.5.3",
61
+ "eslint-plugin-import": "^2.27.5",
62
+ "eslint-plugin-prettier": "^4.2.1",
63
+ "eslint-plugin-simple-import-sort": "^10.0.0",
64
+ "firebase-admin": "^11.6.0",
65
+ "husky": "^8.0.3",
66
+ "jest": "^29.4.3",
67
+ "prettier": "^2.8.4",
68
+ "ts-jest": "^29.0.5",
69
+ "tslib": "^2.5.0",
70
+ "typescript": "^4.9.5"
71
+ }
72
+ }