firetender 0.4.2 → 0.5.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/README.md CHANGED
@@ -4,11 +4,6 @@ The goal of Firetender is to make Firestore documents look (almost) like any
4
4
  other Typescript objects, reducing boilerplate and conceptual overhead and
5
5
  providing type safety and data validation.
6
6
 
7
- Querying and concurrency are not yet supported. I'm adding features as I need
8
- them, but contributions are most welcome. See the list of [alternative
9
- packages](#alternatives) at the end of this README if you're looking for
10
- something more mature.
11
-
12
7
  ## Usage
13
8
 
14
9
  To illustrate, let's run through the basics of defining, creating, modifying,
@@ -65,6 +60,7 @@ const pizzaSchema = z.object({
65
60
  path: ["surcharge"],
66
61
  })
67
62
  ),
63
+ basePrice: z.number().optional(),
68
64
  tags: z.array(z.string()).default([]),
69
65
  });
70
66
 
@@ -149,6 +145,82 @@ newPizza.write();
149
145
  Note the use of the `delete` operator to remove optional fields and record and
150
146
  array items.
151
147
 
148
+ ### Get all docs in a collection
149
+
150
+ You can retrieve all the documents in a collection or subcollection:
151
+
152
+ ```javascript
153
+ const docs = await pizzaCollection().getAllDocs();
154
+ ```
155
+
156
+ `docs` will contain an array of `FiretenderDoc` objects for all entries in the
157
+ pizzas collection. To get the contents of a subcollection, provide the ID(s) of
158
+ its parent collection (and subcollections) to `getAllDocs()`.
159
+
160
+ ### Query a collection or subcollection
161
+
162
+ To query a collection, call `query()` and pass in `where` clauses. The
163
+ [Firestore how-to
164
+ guide](https://firebase.google.com/docs/firestore/query-data/queries) provides
165
+ many examples of simple and compound queries.
166
+
167
+ ```javascript
168
+ const veggieOptions = await pizzaCollection.query(
169
+ where("tags", "array-contains", "vegetarian")
170
+ );
171
+ const cheapClassics = await pizzaCollection.query(
172
+ where("baseprice", "<=", 10),
173
+ where("tags", "array-contains", "traditional")
174
+ );
175
+ ```
176
+
177
+ To query a specific subcollection, provide the ID(s) of its parent collection
178
+ (and subcollections) as the first argument of `query()`.
179
+
180
+ To perform a collection group query across all instances of a particular
181
+ subcollection, leave out the IDs. From the [Firestore how-to
182
+ example](https://firebase.google.com/docs/firestore/query-data/queries#collection-group-query),
183
+ you could retrieve all parks from all cities with this query:
184
+
185
+ ```javascript
186
+ const cityLandmarkSchema = z.object({
187
+ name: z.string(),
188
+ type: z.string(),
189
+ });
190
+ const cityLandmarkCollection = new FiretenderCollection(
191
+ cityLandmarkSchema,
192
+ [firestore, "cities", "landmarks"],
193
+ {}
194
+ );
195
+
196
+ const beijingParks = cityLandmarkCollection.query(
197
+ "BJ",
198
+ where("type", "==", "park"))
199
+ );
200
+ // Resulting array contains the document for Jingshan Park.
201
+
202
+ const allParks = cityLandmarkCollection.query(where("type", "==", "park"));
203
+ // Resulting array has docs for Griffith Park, Ueno Park, and Jingshan Park.
204
+ ```
205
+
206
+ ### Delete a document
207
+
208
+ To delete a document from the cities example:
209
+
210
+ ```javascript
211
+ const citySchema = z.object({ /* ... */ });
212
+ const cityCollection = new FiretenderCollection(
213
+ citySchema, [firestore, "cities"], {}
214
+ );
215
+ cityCollection.delete("LA");
216
+ ```
217
+
218
+ Subcollections are not deleted; in this example, the LA landmark docs would
219
+ remain. To also delete a document's subcollections, use `query()` to get lists
220
+ of its subcollections' docs, then call `delete()` on each doc. The Firestore
221
+ guide recommends only performing such unbounded batched deletions from a trusted
222
+ server environment.
223
+
152
224
  ## TODO
153
225
 
154
226
  The [full list of issues](https://github.com/jakes-space/firetender/issues) is
@@ -165,17 +237,13 @@ tracked on Github. Here are some features on the roadmap:
165
237
  ([#14](https://github.com/jakes-space/firetender/issues/14))
166
238
  * Support the Firestore transaction API.
167
239
  ([#15](https://github.com/jakes-space/firetender/issues/15))
168
- * Queries
169
- ([#16](https://github.com/jakes-space/firetender/issues/16))
170
- * Document deletion
171
- ([#17](https://github.com/jakes-space/firetender/issues/17))
172
240
  * Improved timestamp handling, tests ([multiple
173
241
  issues](https://github.com/jakes-space/firetender/issues?q=timestamp))
174
242
 
175
243
  ## Alternatives
176
244
 
177
- This project is not at all stable yet. If you're looking for a more mature
178
- Firestore helper, check out:
245
+ This project is not stable yet. If you're looking for a more mature Firestore
246
+ helper, check out:
179
247
 
180
248
  * [Vuefire](https://github.com/vuejs/vuefire) and
181
249
  [Reactfire](https://github.com/FirebaseExtended/reactfire) for integration
@@ -1,4 +1,4 @@
1
- import { Firestore } from "firebase/firestore";
1
+ import { Firestore, QueryConstraint } from "firebase/firestore";
2
2
  import { z } from "zod";
3
3
  import { FiretenderDoc, FiretenderDocOptions } from "./FiretenderDoc";
4
4
  import { DeepPartial } from "./ts-helpers";
@@ -10,6 +10,21 @@ export declare class FiretenderCollection<SchemaType extends z.SomeZodObject> {
10
10
  constructor(schema: SchemaType, collectionPath: [Firestore, ...string[]], baseInitialData: DeepPartial<z.infer<SchemaType>>);
11
11
  createNewDoc(id?: string[] | string | undefined, initialData?: DeepPartial<z.infer<SchemaType>> | undefined, options?: FiretenderDocOptions): FiretenderDoc<SchemaType, z.TypeOf<SchemaType>>;
12
12
  getExistingDoc(id: string[] | string, options?: FiretenderDocOptions): FiretenderDoc<SchemaType, z.TypeOf<SchemaType>>;
13
+ getAllDocs(id?: string[] | string | undefined): Promise<FiretenderDoc<SchemaType, z.TypeOf<SchemaType>>[]>;
14
+ query(idOrWhereClause: string | string[] | QueryConstraint, ...moreWhereClauses: QueryConstraint[]): Promise<FiretenderDoc<SchemaType, z.TypeOf<SchemaType>>[]>;
15
+ /**
16
+ * Deletes the given document from this collection.
17
+ *
18
+ * Subcollections (if any) are not deleted. To also delete a document's
19
+ * subcollections, use query() to get lists of the subcollections' docs, then
20
+ * call delete() on each one. Please note that the Firestore guide recommends
21
+ * only performing such unbounded batched deletions from a trusted server
22
+ * environment.
23
+ *
24
+ * @param id full path ID of the target document.
25
+ */
26
+ delete(id: string[] | string): Promise<void>;
13
27
  private makeDocRef;
14
28
  private makeCollectionRef;
29
+ private getAndWrapDocs;
15
30
  }
@@ -17,7 +17,7 @@ class FiretenderCollection {
17
17
  ref = this.makeCollectionRef(ids);
18
18
  }
19
19
  if (!ref) {
20
- throw Error("createNewDoc() requires an ID for all collections and subcollections except the last.");
20
+ throw Error("createNewDoc() requires an ID for all collections and subcollections except optionally the last.");
21
21
  }
22
22
  const data = this.baseInitialData;
23
23
  if (initialData) {
@@ -32,6 +32,53 @@ class FiretenderCollection {
32
32
  }
33
33
  return new FiretenderDoc_1.FiretenderDoc(this.schema, ref, options);
34
34
  }
35
+ async getAllDocs(id = undefined) {
36
+ const ids = id instanceof Array ? id : id ? [id] : [];
37
+ const collectionRef = this.makeCollectionRef(ids);
38
+ if (!collectionRef) {
39
+ throw Error("getAllDocs() requires an ID for all collections and subcollections except the last.");
40
+ }
41
+ return this.getAndWrapDocs(collectionRef);
42
+ }
43
+ async query(idOrWhereClause, ...moreWhereClauses) {
44
+ let ids;
45
+ let whereClauses;
46
+ if (idOrWhereClause instanceof Array) {
47
+ ids = idOrWhereClause;
48
+ whereClauses = moreWhereClauses;
49
+ }
50
+ else if (typeof idOrWhereClause === "string") {
51
+ ids = [idOrWhereClause];
52
+ whereClauses = moreWhereClauses;
53
+ }
54
+ else {
55
+ ids = [];
56
+ whereClauses = [idOrWhereClause, ...moreWhereClauses];
57
+ }
58
+ let ref = this.makeCollectionRef(ids);
59
+ if (!ref) {
60
+ ref = (0, firestore_1.collectionGroup)(this.firestore, this.collectionNames[this.collectionNames.length - 1]);
61
+ }
62
+ return this.getAndWrapDocs((0, firestore_1.query)(ref, ...whereClauses));
63
+ }
64
+ /**
65
+ * Deletes the given document from this collection.
66
+ *
67
+ * Subcollections (if any) are not deleted. To also delete a document's
68
+ * subcollections, use query() to get lists of the subcollections' docs, then
69
+ * call delete() on each one. Please note that the Firestore guide recommends
70
+ * only performing such unbounded batched deletions from a trusted server
71
+ * environment.
72
+ *
73
+ * @param id full path ID of the target document.
74
+ */
75
+ async delete(id) {
76
+ const ref = this.makeDocRef([id].flat());
77
+ if (!ref) {
78
+ throw Error("delete() requires the full ID path of the target document.");
79
+ }
80
+ await (0, firestore_1.deleteDoc)(ref);
81
+ }
35
82
  makeDocRef(ids) {
36
83
  if (ids.length !== this.collectionNames.length) {
37
84
  return undefined;
@@ -46,6 +93,12 @@ class FiretenderCollection {
46
93
  const subPath = ids.flatMap((id, i) => [id, this.collectionNames[i + 1]]);
47
94
  return (0, firestore_1.collection)(this.firestore, this.collectionNames[0], ...subPath);
48
95
  }
96
+ async getAndWrapDocs(query) {
97
+ const querySnapshot = await (0, firestore_1.getDocs)(query);
98
+ return querySnapshot.docs.map((queryDoc) => new FiretenderDoc_1.FiretenderDoc(this.schema, queryDoc.ref, {
99
+ initialData: queryDoc.data(),
100
+ }));
101
+ }
49
102
  }
50
103
  exports.FiretenderCollection = FiretenderCollection;
51
104
  //# sourceMappingURL=FiretenderCollection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FiretenderCollection.js","sourceRoot":"","sources":["../src/FiretenderCollection.ts"],"names":[],"mappings":";;;AAAA,kDAM4B;AAG5B,mDAAsE;AAGtE,MAAa,oBAAoB;IAM/B,YACE,MAAkB,EAClB,cAAwC,EACxC,eAAiD;QAEjD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAa,CAAC;QAC3D,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACzC,CAAC;IAED,YAAY,CACV,KAAoC,SAAS,EAC7C,cAA4D,SAAS,EACrE,UAAgC,EAAE;QAElC,MAAM,GAAG,GAAG,EAAE,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,IAAI,GAAG,GACL,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,GAAG,EAAE;YACR,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;SACnC;QACD,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,KAAK,CACT,uFAAuF,CACxF,CAAC;SACH;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC;QAClC,IAAI,WAAW,EAAE;YACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;SAClC;QACD,OAAO,6BAAa,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,cAAc,CAAC,EAAqB,EAAE,UAAgC,EAAE;QACtE,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,KAAK,CACT,qGAAqG,CACtG,CAAC;SACH;QACD,OAAO,IAAI,6BAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAEO,UAAU,CAAC,GAAa;QAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;YAC9C,OAAO,SAAS,CAAC;SAClB;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACnE,OAAO,IAAA,eAAG,EAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAEO,iBAAiB,CAAC,GAAa;QACrC,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;YAClD,OAAO,SAAS,CAAC;SAClB;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;IACzE,CAAC;CACF;AAjED,oDAiEC"}
1
+ {"version":3,"file":"FiretenderCollection.js","sourceRoot":"","sources":["../src/FiretenderCollection.ts"],"names":[],"mappings":"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"}
@@ -16,12 +16,12 @@ class FiretenderDoc {
16
16
  this.schema = schema;
17
17
  this.ref = ref;
18
18
  this.isNewDoc = options.createDoc ?? false;
19
- if (this.isNewDoc) {
20
- if (!options.initialData) {
21
- throw ReferenceError("Initial data must be given when creating a new doc.");
22
- }
19
+ if (options.initialData) {
23
20
  this.data = schema.parse(options.initialData);
24
21
  }
22
+ else if (this.isNewDoc) {
23
+ throw ReferenceError("Initial data must be given when creating a new doc.");
24
+ }
25
25
  if (this.ref.type === "document") {
26
26
  this.docID = this.ref.path.split("/").pop();
27
27
  }
@@ -130,7 +130,30 @@ class FiretenderDoc {
130
130
  return this;
131
131
  }
132
132
  onChange(fieldPath, newValue) {
133
- this.updates.set(fieldPath.join("."), newValue);
133
+ let pathString = "";
134
+ if (this.updates.size > 0) {
135
+ // Check if some parent of this update is already in the list of mutations
136
+ // to send to Firestore. Objects in the update list are references into
137
+ // this.data, so the parent field will automatically reflect this change;
138
+ // no additional Firestore mutation is needed.
139
+ if (fieldPath.some((field, i) => {
140
+ pathString = pathString ? `${pathString}.${field}` : field;
141
+ return i < fieldPath.length - 1 && this.updates.has(pathString);
142
+ })) {
143
+ return;
144
+ }
145
+ // Remove any previous updates that this one overwrites.
146
+ this.updates.forEach((value, key) => {
147
+ if (key.startsWith(pathString)) {
148
+ this.updates.delete(key);
149
+ }
150
+ });
151
+ }
152
+ else {
153
+ // Shortcut for the common case of a single update being made.
154
+ pathString = fieldPath.join(".");
155
+ }
156
+ this.updates.set(pathString, newValue);
134
157
  }
135
158
  }
136
159
  exports.FiretenderDoc = FiretenderDoc;
@@ -1 +1 @@
1
- {"version":3,"file":"FiretenderDoc.js","sourceRoot":"","sources":["../src/FiretenderDoc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FiretenderDoc.js","sourceRoot":"","sources":["../src/FiretenderDoc.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "firetender",
3
3
  "displayName": "Firetender",
4
4
  "description": "Typescript wrapper for Firestore documents",
5
- "version": "0.4.2",
5
+ "version": "0.5.2",
6
6
  "author": "Jake Hartman",
7
7
  "license": "MIT",
8
8
  "homepage": "https://github.com/jakes-space/firetender",