firetender 0.1.0 → 0.3.1

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
@@ -1,8 +1,8 @@
1
- # FireTender
1
+ # Firetender
2
2
 
3
- FireTender is a wrapper for Firestore documents to make reading and writing them
4
- simpler and safer. A Firestore doc looks like any other Typescript object, and
5
- they are validated upon reading and writing.
3
+ The goal of Firetender is to make Firestore documents look (almost) like any
4
+ other Typescript objects, reducing boilerplate and conceptual overhead and
5
+ providing type safety and data validation.
6
6
 
7
7
  Querying and concurrency are not yet supported. I'm adding features as I need
8
8
  them, but contributions are most welcome. See the list of [alternative
@@ -11,23 +11,38 @@ something more mature.
11
11
 
12
12
  ## Usage
13
13
 
14
- To illustrate, let's run through the basics of defining, creating, reading, and
15
- modifying a Firestore document.
14
+ To illustrate, let's run through the basics of defining, creating, modifying,
15
+ and copying a Firestore document.
16
16
 
17
- ### Define your schemas
17
+ ### Initialize Cloud Firestore
18
18
 
19
- First, we define the document schemas and their validation criteria with
20
- [Zod](https://github.com/colinhacks/zod). If you've used Joi or Yup, you will
21
- find Zod very similar. Optional collections should use `.default({})` or
22
- `.default([])` to simplify later access. Here we define a schema for types of
23
- pizza, because I was hungry when I first wrote this.
19
+ The first step is the usual Firestore configuration and initialization. See
20
+ the [Firestore
21
+ quickstart](https://firebase.google.com/docs/firestore/quickstart) for details.
24
22
 
25
- Then create `pizzaWrapper`, which is a factory that makes objects to wrap
26
- Firestore documents and enforce the given schema.
23
+ ```javascript
24
+ import { doc, initializeApp } from "firebase/app";
25
+ import { getFirestore } from "firebase/firestore";
26
+
27
+ // TODO: Replace the following with your app's Firebase project configuration.
28
+ // See: https://firebase.google.com/docs/web/learn-more#config-object
29
+ const firebaseConfig = {
30
+ // ...
31
+ };
32
+
33
+ const app = initializeApp(firebaseConfig);
34
+ const firestore = getFirestore(app);
35
+ ```
36
+
37
+ ### Define the schema
38
+
39
+ Firetender uses [Zod](https://github.com/colinhacks/zod) to define the
40
+ document's schema and validation rules; if you've used Joi or Yup, you will find
41
+ Zod very similar. In the example below, I've defined a schema for types of
42
+ pizza. I was a little hungry when I wrote this.
27
43
 
28
44
  ```javascript
29
- import { doc } from "firebase/firestore";
30
- import { DocWrapper } from "firetender";
45
+ import { FiretenderDoc } from "firetender";
31
46
  import { z } from "zod";
32
47
 
33
48
  const pizzaSchema = z.object({
@@ -48,81 +63,107 @@ const pizzaSchema = z.object({
48
63
  tags: z.array(z.string()).default([]),
49
64
  });
50
65
 
51
- const pizzaWrapper = new DocWrapper(pizzaSchema);
66
+ const pizzaFactory = FiretenderDoc.makeClassFactoryFor(pizzaSchema);
52
67
  ```
53
68
 
69
+ The static `FiretenderDoc.makeClassFactory()` method simplifies document
70
+ creation by capturing the schema.
71
+
72
+ Optional records and arrays should typically use `.default()` to provide an
73
+ empty collection when missing. That isn't required, but it makes accessing
74
+ these fields simpler because they will always be defined. The downside is that
75
+ empty collection fields are not pruned and will appear in Firestore.
76
+
54
77
  ### Add a document
55
78
 
56
- Let's add a document to the `pizzas` collection with an ID of `margherita`. We
57
- use `DocWrapper.prototype.createNew()` to create a validated local object
58
- representing a new document in the collection. We then add the doc to Firestore
59
- by calling its `.write()` method.
79
+ Let's add a document to the `pizzas` collection, with an ID of `margherita`. We
80
+ use the factory's `.createNewDoc()` to produce a `FiretenderDoc` representing a
81
+ new document, initialized with validated data. This object is purely local
82
+ until it is written to Firestore by calling `.write()`. Don't forget to do
83
+ that.
60
84
 
61
85
  ```javascript
62
86
  const docRef = doc(db, "pizzas", "margherita");
63
- const pizza = pizzaWrapper.createNew(docRef, {
87
+ const pizza = pizzaFactory.createNewDoc(docRef, {
64
88
  name: "Margherita",
89
+ description: "Neapolitan style pizza"
65
90
  toppings: { "fresh mozzarella": {}, "fresh basil": {} },
66
91
  tags: ["traditional"],
67
92
  });
68
93
  await pizza.write();
69
94
  ```
70
95
 
71
- If we don't care about the doc ID, we can also pass a collection reference
72
- (e.g., `collection(db, "pizzas")`) to `.createNew()`. Firestore will assign a
73
- random ID.
96
+ If you don't care about the doc ID, pass a collection reference to
97
+ `.createNewDoc()` and Firestore will assign an ID at random. It can be read
98
+ from `.id` or `.docRef`.
74
99
 
75
100
  ### Read and modify a document
76
101
 
77
- To read or modify an existing document, we instantiate a doc wrapper using
78
- `DocWrapper.prototype.wrapExisting()`, passing in the doc's Firestore reference.
79
- To read from it, we call `.load()` and access the data with `.ro` (read only);
80
- to write, we modify the `.rw` accessor and then call `.write()`. They can be
81
- used in combination, like so:
102
+ To access an existing document, pass its reference to the `.wrapExistingDoc()`
103
+ factory method. To read it, call `.load()` and access its data with the `.r`
104
+ property; see the example below. To make changes, use `.w` then call
105
+ `.write()`. Reading and updating can be done in combination:
82
106
 
83
107
  ```javascript
84
108
  const meats = ["pepperoni", "chicken", "sausage"];
85
- const pizza = await pizzaWrapper.wrapExisting(docRef).load();
86
- const isMeatIncluded = Object.entries(pizza.ro.toppings).some(
109
+ const pizza = await pizzaFactory.wrapExistingDoc(docRef).load();
110
+ const isMeatIncluded = Object.entries(pizza.r.toppings).some(
87
111
  ([name, topping]) => topping.isIncluded && name in meats
88
112
  );
89
113
  if (!isMeatIncluded) {
90
- pizza.rw.toppings.tags.push("vegetarian");
114
+ pizza.w.toppings.tags.push("vegetarian");
91
115
  }
92
116
  await pizza.write();
93
117
  ```
94
118
 
119
+ The `.r` and `.w` properties point to the same data, with the read-only accessor
120
+ typed accordingly. Reading from `.r` is more efficient, as `.w` builds a chain
121
+ of proxies to track updates.
122
+
95
123
  ### Make a copy
96
124
 
97
- Here we create a new pizza in the same collection. Alternatively, a document
98
- can be copied to elsewhere by specifying a document or collection reference.
125
+ Finally, use `.copy()` to get a deep copy of the document. If an ID is not
126
+ specified, it will be assigned randomly when the new doc is added to Firestore.
127
+ The copy is solely local until `.write()` is called.
99
128
 
100
129
  ```javascript
101
130
  const sourceRef = doc(db, "pizza", "margherita");
102
- const sourcePizza = await pizzaWrapper.wrapExisting(sourceRef).load();
131
+ const sourcePizza = await pizzaFactory.wrapExistingDoc(sourceRef).load();
103
132
  const newPizza = sourcePizza.copy("meaty margh");
104
133
  newPizza.name = "Meaty Margh";
105
134
  newPizza.toppings.sausage = {};
106
135
  newPizza.toppings.pepperoni = { included: false, surcharge: 1.25 };
107
136
  newPizza.toppings.chicken = { included: false, surcharge: 1.50 };
137
+ delete newPizza.description;
108
138
  delete newPizza.toppings["fresh basil"];
109
139
  delete newPizza.tags.vegetarian;
110
140
  newPizza.write();
111
141
  ```
112
142
 
143
+ Note the use of the `delete` operator to remove optional fields and record and
144
+ array items.
145
+
113
146
  ## TODO
114
147
 
148
+ * Javadoc
149
+ * Compile them to an API reference page in markdown.
115
150
  * Concurrency
116
151
  * Listen for changes and update the object if it has not been locally
117
152
  modified. Provide an onChange() callback option.
118
153
  * Support the Firestore transaction API.
119
154
  * Queries
120
155
  * Document deletion
121
- * Improved timestamp handling
122
- * Prod releases
123
- * Block on failing tests
156
+ * Improved timestamp handling, tests
157
+ * Releases
124
158
  * Minify code (esbuild?)
125
- * Release on github
159
+ * Automate github & npm releases, either using semantic versioning
160
+ ([video](https://egghead.io/lessons/javascript-automating-releases-with-semantic-release),
161
+ [package](https://github.com/semantic-release/semantic-release)) or github
162
+ workflows
163
+ ([tutorial](https://writeabout.net/2021/10/15/releasing-github-npm-packages/),
164
+ [Zod's
165
+ yaml](https://github.com/colinhacks/zod/blob/master/.github/workflows/release.yml))
166
+ or some combination.
126
167
 
127
168
  ## Alternatives
128
169
 
@@ -136,10 +177,11 @@ Firestore helper, check out:
136
177
  * [Fireschema](https://github.com/yarnaimo/fireschema): Another strongly typed
137
178
  framework for building and using schemas in Firestore.
138
179
 
139
- * [firestore-fp](https://github.com/mobily/firestore-fp): If you are a
140
- functional programming aficionado.
180
+ * [firestore-fp](https://github.com/mobily/firestore-fp): If you like functional
181
+ programming.
141
182
 
142
- * [simplyfire](https://github.com/coturiv/simplyfire): A brilliantly named
143
- simplified API that is focused more on querying.
183
+ * [simplyfire](https://github.com/coturiv/simplyfire): Another
184
+ simplified API that is focused more on querying. (And kudos to the author for
185
+ its great name.)
144
186
 
145
187
  I'm sure there are many more, and apologies if I missed your favorite.
@@ -0,0 +1,39 @@
1
+ import { CollectionReference, DocumentReference } from "firebase/firestore";
2
+ import { z } from "zod";
3
+ import { DeepReadonly } from "./ts-helpers";
4
+ export declare type FiretenderDocOptions = {
5
+ createDoc?: true;
6
+ initialData?: any;
7
+ };
8
+ /**
9
+ * Helper class for reading and writing Firestore data based on Zod schemas.
10
+ */
11
+ export declare class FiretenderDoc<SchemaType extends z.SomeZodObject, DataType extends {
12
+ [x: string]: any;
13
+ } = z.infer<SchemaType>> {
14
+ readonly schema: SchemaType;
15
+ private ref;
16
+ private isNewDoc;
17
+ private docID;
18
+ private data;
19
+ private dataProxy;
20
+ private updates;
21
+ constructor(schema: SchemaType, ref: DocumentReference | CollectionReference, options?: FiretenderDocOptions);
22
+ static createNewDoc<SchemaType1 extends z.SomeZodObject, InputType extends {
23
+ [x: string]: any;
24
+ } = z.input<SchemaType1>>(schema: SchemaType1, ref: DocumentReference | CollectionReference, initialData: InputType, options?: FiretenderDocOptions): FiretenderDoc<SchemaType1, z.TypeOf<SchemaType1>>;
25
+ static makeClassFactoryFor<SchemaType1 extends z.SomeZodObject, InputType extends {
26
+ [x: string]: any;
27
+ } = z.input<SchemaType1>>(schema: SchemaType1): {
28
+ createNewDoc: (ref: DocumentReference | CollectionReference, initialData: InputType, options?: FiretenderDocOptions) => FiretenderDoc<SchemaType1, z.TypeOf<SchemaType1>>;
29
+ wrapExistingDoc: (ref: DocumentReference | CollectionReference, options?: FiretenderDocOptions) => FiretenderDoc<SchemaType1, z.TypeOf<SchemaType1>>;
30
+ };
31
+ get id(): string | undefined;
32
+ get docRef(): DocumentReference;
33
+ copy(dest?: DocumentReference | CollectionReference | string | undefined, options?: FiretenderDocOptions): FiretenderDoc<SchemaType, DataType>;
34
+ load(force?: boolean): Promise<this>;
35
+ get r(): DeepReadonly<DataType>;
36
+ get w(): DataType;
37
+ write(): Promise<void>;
38
+ private onChange;
39
+ }
@@ -1,17 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FireTenderDoc = void 0;
3
+ exports.FiretenderDoc = void 0;
4
4
  const firestore_1 = require("firebase/firestore");
5
5
  const proxies_1 = require("./proxies");
6
- function assertIsDefined(value) {
7
- if (value === undefined || value === null) {
8
- throw new TypeError(`${value} is not defined`);
9
- }
10
- }
6
+ const ts_helpers_1 = require("./ts-helpers");
11
7
  /**
12
8
  * Helper class for reading and writing Firestore data based on Zod schemas.
13
9
  */
14
- class FireTenderDoc {
10
+ class FiretenderDoc {
15
11
  constructor(schema, ref, options = {}) {
16
12
  this.docID = undefined;
17
13
  this.data = undefined;
@@ -20,7 +16,6 @@ class FireTenderDoc {
20
16
  this.schema = schema;
21
17
  this.ref = ref;
22
18
  this.isNewDoc = options.createDoc ?? false;
23
- console.log(ref, ref instanceof firestore_1.DocumentReference, options);
24
19
  if (this.isNewDoc) {
25
20
  if (!options.initialData) {
26
21
  throw ReferenceError("Initial data must be given when creating a new doc.");
@@ -31,9 +26,23 @@ class FireTenderDoc {
31
26
  this.docID = this.ref.path.split("/").pop();
32
27
  }
33
28
  else if (!this.isNewDoc) {
34
- throw TypeError("FireTender can only take a collection reference when creating a new document. Use FireTender.createDoc() if this is your intent.");
29
+ throw TypeError("Firetender can only take a collection reference when creating a new document. Use Firetender.createDoc() if this is your intent.");
35
30
  }
36
31
  }
32
+ static createNewDoc(schema, ref, initialData, options = {}) {
33
+ const mergedOptions = {
34
+ ...options,
35
+ createDoc: true,
36
+ initialData,
37
+ };
38
+ return new FiretenderDoc(schema, ref, mergedOptions);
39
+ }
40
+ static makeClassFactoryFor(schema) {
41
+ return {
42
+ createNewDoc: (ref, initialData, options = {}) => FiretenderDoc.createNewDoc(schema, ref, initialData, options),
43
+ wrapExistingDoc: (ref, options = {}) => new FiretenderDoc(schema, ref, options),
44
+ };
45
+ }
37
46
  get id() {
38
47
  return this.docID;
39
48
  }
@@ -65,7 +74,7 @@ class FireTenderDoc {
65
74
  createDoc: true,
66
75
  initialData: this.data,
67
76
  };
68
- return new FireTenderDoc(this.schema, ref, mergedOptions);
77
+ return new FiretenderDoc(this.schema, ref, mergedOptions);
69
78
  }
70
79
  async load(force = false) {
71
80
  if (this.isNewDoc || this.ref.type === "collection") {
@@ -82,20 +91,20 @@ class FireTenderDoc {
82
91
  }
83
92
  return this;
84
93
  }
85
- get ro() {
94
+ get r() {
86
95
  if (!this.data) {
87
- throw Error("You must call load() before using the .ro accessor.");
96
+ throw Error("load() must be called before reading the document.");
88
97
  }
89
98
  return this.data;
90
99
  }
91
- get rw() {
100
+ get w() {
92
101
  if (this.isNewDoc) {
93
102
  // No need to monitor changes if we're creating rather than updating.
94
103
  return this.data;
95
104
  }
96
105
  if (!this.dataProxy) {
97
106
  if (!this.data) {
98
- throw Error("You must call load() before using the .rw accessor.");
107
+ throw Error("load() must be called before updating the document.");
99
108
  }
100
109
  this.dataProxy = (0, proxies_1.watchFieldForChanges)([], this.schema, this.data, this.onChange.bind(this));
101
110
  }
@@ -103,7 +112,7 @@ class FireTenderDoc {
103
112
  }
104
113
  async write() {
105
114
  if (this.isNewDoc) {
106
- assertIsDefined(this.data);
115
+ (0, ts_helpers_1.assertIsDefined)(this.data);
107
116
  if (this.ref.type === "document") {
108
117
  await (0, firestore_1.setDoc)(this.ref, this.data);
109
118
  }
@@ -116,7 +125,7 @@ class FireTenderDoc {
116
125
  else {
117
126
  if (!(this.ref.type === "document")) {
118
127
  // We should never get here.
119
- throw Error("Internal error. FireTender object should always reference a document when updating an existing doc.");
128
+ throw Error("Internal error. Firetender object should always reference a document when updating an existing doc.");
120
129
  }
121
130
  if (this.updates.size === 0) {
122
131
  return;
@@ -129,5 +138,5 @@ class FireTenderDoc {
129
138
  this.updates.set(fieldPath.join("."), newValue);
130
139
  }
131
140
  }
132
- exports.FireTenderDoc = FireTenderDoc;
133
- //# sourceMappingURL=FireTenderDoc.js.map
141
+ exports.FiretenderDoc = FiretenderDoc;
142
+ //# sourceMappingURL=FiretenderDoc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FiretenderDoc.js","sourceRoot":"","sources":["../src/FiretenderDoc.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,6 @@ exports.timestampSchema = zod_1.z.object({
10
10
  seconds: zod_1.z.number().positive().int(),
11
11
  nanoseconds: zod_1.z.number().nonnegative().int(),
12
12
  });
13
- // TODO: probably want to move these timestamp functions into their own helper
14
- // module
15
13
  function dateFromTimestamp(timestamp) {
16
14
  return new Date(timestamp.seconds * 1e3 + timestamp.nanoseconds / 1e6);
17
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Timestamps.js","sourceRoot":"","sources":["../src/Timestamps.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB;;;GAGG;AACU,QAAA,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE;IACpC,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE;CAC5C,CAAC,CAAC;AAGH,8EAA8E;AAC9E,SAAS;AAET,SAAgB,iBAAiB,CAAC,SAAwB;IACxD,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,GAAG,GAAG,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;AACzE,CAAC;AAFD,8CAEC;AAED,SAAgB,OAAO,CAAC,WAAW,GAAG,EAAE;IACtC,sEAAsE;IACtE,OAAO,uBAAuB,CAC5B,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAC/C,CAAC;AACJ,CAAC;AALD,0BAKC;AAED,SAAgB,iBAAiB,CAAC,IAAU;IAC1C,OAAO,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AACjD,CAAC;AAFD,8CAEC;AAED,SAAgB,uBAAuB,CAAC,YAAoB;IAC1D,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QACxC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC;KACzD,CAAC;AACJ,CAAC;AALD,0DAKC;AAED,SAAgB,YAAY;IAC1B,sEAAsE;IACtE,OAAO,uBAAuB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC;AAHD,oCAGC"}
1
+ {"version":3,"file":"Timestamps.js","sourceRoot":"","sources":["../src/Timestamps.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB;;;GAGG;AACU,QAAA,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE;IACpC,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE;CAC5C,CAAC,CAAC;AAGH,SAAgB,iBAAiB,CAAC,SAAwB;IACxD,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,GAAG,GAAG,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;AACzE,CAAC;AAFD,8CAEC;AAED,SAAgB,OAAO,CAAC,WAAW,GAAG,EAAE;IACtC,sEAAsE;IACtE,OAAO,uBAAuB,CAC5B,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAC/C,CAAC;AACJ,CAAC;AALD,0BAKC;AAED,SAAgB,iBAAiB,CAAC,IAAU;IAC1C,OAAO,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AACjD,CAAC;AAFD,8CAEC;AAED,SAAgB,uBAAuB,CAAC,YAAoB;IAC1D,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QACxC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC;KACzD,CAAC;AACJ,CAAC;AALD,0DAKC;AAED,SAAgB,YAAY;IAC1B,sEAAsE;IACtE,OAAO,uBAAuB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC;AAHD,oCAGC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export { DocWrapper } from "./DocWrapper";
2
- export { FireTenderDoc } from "./FireTenderDoc";
1
+ export { FiretenderDoc } from "./FiretenderDoc";
3
2
  export * from "./Timestamps";
package/dist/index.js CHANGED
@@ -14,10 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.FireTenderDoc = exports.DocWrapper = void 0;
18
- var DocWrapper_1 = require("./DocWrapper");
19
- Object.defineProperty(exports, "DocWrapper", { enumerable: true, get: function () { return DocWrapper_1.DocWrapper; } });
20
- var FireTenderDoc_1 = require("./FireTenderDoc");
21
- Object.defineProperty(exports, "FireTenderDoc", { enumerable: true, get: function () { return FireTenderDoc_1.FireTenderDoc; } });
17
+ exports.FiretenderDoc = void 0;
18
+ var FiretenderDoc_1 = require("./FiretenderDoc");
19
+ Object.defineProperty(exports, "FiretenderDoc", { enumerable: true, get: function () { return FiretenderDoc_1.FiretenderDoc; } });
22
20
  __exportStar(require("./Timestamps"), exports);
23
21
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,+CAA6B"}
package/dist/proxies.js CHANGED
@@ -1,13 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.watchFieldForChanges = exports.watchArrayForChanges = void 0;
4
+ const ts_helpers_1 = require("./ts-helpers");
4
5
  const firestore_1 = require("firebase/firestore");
5
6
  const zod_1 = require("zod");
6
- function assertKeyIsString(key) {
7
- if (typeof key !== "string") {
8
- throw TypeError("Property access using symbols is not supported.");
9
- }
10
- }
11
7
  function unwrapSchema(schema) {
12
8
  if (schema instanceof zod_1.z.ZodOptional || schema instanceof zod_1.z.ZodNullable) {
13
9
  return unwrapSchema(schema.unwrap());
@@ -36,7 +32,7 @@ function getPropertySchema(parentSchema, propertyKey) {
36
32
  function watchArrayForChanges(arrayPath, array, fieldSchema, field, onChange) {
37
33
  return new Proxy(field, {
38
34
  get(target, propertyKey) {
39
- assertKeyIsString(propertyKey);
35
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
40
36
  const property = target[propertyKey];
41
37
  if (property instanceof Function) {
42
38
  const result = (...args) => property.apply(field, args);
@@ -52,7 +48,7 @@ function watchArrayForChanges(arrayPath, array, fieldSchema, field, onChange) {
52
48
  return property;
53
49
  },
54
50
  set(target, propertyKey, value) {
55
- assertKeyIsString(propertyKey);
51
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
56
52
  const propertySchema = getPropertySchema(fieldSchema, propertyKey);
57
53
  const parsedValue = propertySchema.parse(value);
58
54
  const result = Reflect.set(target, propertyKey, parsedValue);
@@ -60,7 +56,7 @@ function watchArrayForChanges(arrayPath, array, fieldSchema, field, onChange) {
60
56
  return result;
61
57
  },
62
58
  deleteProperty(target, propertyKey) {
63
- assertKeyIsString(propertyKey);
59
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
64
60
  // Calling Reflect.deleteProperty on an array item sets it to undefined,
65
61
  // which causes Firestore updates to fail unless ignoreUndefinedProperties
66
62
  // is set, and which is generally not what we want. Hence splice.
@@ -82,7 +78,7 @@ exports.watchArrayForChanges = watchArrayForChanges;
82
78
  function watchFieldForChanges(fieldPath, fieldSchema, field, onChange) {
83
79
  return new Proxy(field, {
84
80
  get(target, propertyKey) {
85
- assertKeyIsString(propertyKey);
81
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
86
82
  const property = target[propertyKey];
87
83
  if (property instanceof Function) {
88
84
  return (...args) => property.apply(field, args);
@@ -96,14 +92,14 @@ function watchFieldForChanges(fieldPath, fieldSchema, field, onChange) {
96
92
  return property;
97
93
  },
98
94
  set(target, propertyKey, value) {
99
- assertKeyIsString(propertyKey);
95
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
100
96
  const propertySchema = getPropertySchema(fieldSchema, propertyKey);
101
97
  const parsedValue = propertySchema.parse(value);
102
98
  onChange([...fieldPath, propertyKey], parsedValue);
103
99
  return Reflect.set(target, propertyKey, parsedValue);
104
100
  },
105
101
  deleteProperty(target, propertyKey) {
106
- assertKeyIsString(propertyKey);
102
+ (0, ts_helpers_1.assertKeyIsString)(propertyKey);
107
103
  onChange([...fieldPath, propertyKey], (0, firestore_1.deleteField)());
108
104
  return Reflect.deleteProperty(target, propertyKey);
109
105
  },
@@ -1 +1 @@
1
- {"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":";;;AAAA,kDAA8D;AAC9D,6BAAwB;AAExB,SAAS,iBAAiB,CAAC,GAAQ;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC3B,MAAM,SAAS,CAAC,iDAAiD,CAAC,CAAC;KACpE;AACH,CAAC;AAED,SAAS,YAAY,CAAC,MAAoB;IACxC,IAAI,MAAM,YAAY,OAAC,CAAC,WAAW,IAAI,MAAM,YAAY,OAAC,CAAC,WAAW,EAAE;QACtE,OAAO,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;KACtC;IACD,IAAI,MAAM,YAAY,OAAC,CAAC,UAAU,EAAE;QAClC,OAAO,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;KAC7C;IACD,IAAI,MAAM,YAAY,OAAC,CAAC,UAAU,EAAE;QAClC,OAAO,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;KACzC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CACxB,YAA0B,EAC1B,WAAmB;IAEnB,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IAC1C,IAAI,MAAM,YAAY,OAAC,CAAC,SAAS,EAAE;QACjC,OAAO,MAAM,CAAC,WAAW,CAAC;KAC3B;IACD,IAAI,MAAM,YAAY,OAAC,CAAC,QAAQ,EAAE;QAChC,OAAO,MAAM,CAAC,OAAO,CAAC;KACvB;IACD,IAAI,MAAM,YAAY,OAAC,CAAC,SAAS,EAAE;QACjC,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;KAClC;IACD,MAAM,SAAS,CACb,yCAAyC,WAAW,MAAM,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CACpF,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAIlC,SAAmB,EACnB,KAAyB,EACzB,WAA4B,EAC5B,KAA+B,EAC/B,QAAiD;IAEjD,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE;QACtB,GAAG,CAAC,MAAM,EAAE,WAAW;YACrB,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,QAAQ,YAAY,QAAQ,EAAE;gBAChC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC/D,qEAAqE;gBACrE,wEAAwE;gBACxE,kDAAkD;gBAClD,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBAC3B,OAAO,MAAM,CAAC;aACf;YACD,IAAI,QAAQ,YAAY,MAAM,EAAE;gBAC9B,OAAO,oBAAoB,CACzB,SAAS,EACT,KAAK,EACL,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,EAC3C,QAAQ,EACR,QAAQ,CACT,CAAC;aACH;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK;YAC5B,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACnE,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;YAC7D,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,cAAc,CAAC,MAAM,EAAE,WAAW;YAChC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/B,wEAAwE;YACxE,0EAA0E;YAC1E,kEAAkE;YAClE,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC9B,MAAM,UAAU,CACd,0CAA0C,WAAW,mBAAmB,CACzE,CAAC;aACH;YACD,IAAI,MAAM,KAAK,KAAK,EAAE;gBACpB,QAAQ,CAAC,SAAS,EAAE,IAAA,uBAAW,EAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACpD;iBAAM;gBACL,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;aAC5B;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AA5DD,oDA4DC;AAED,SAAgB,oBAAoB,CAClC,SAAmB,EACnB,WAA4B,EAC5B,KAA+B,EAC/B,QAAiD;IAEjD,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE;QACtB,GAAG,CAAC,MAAM,EAAE,WAAW;YACrB,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,QAAQ,YAAY,QAAQ,EAAE;gBAChC,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;aACxD;YACD,IAAI,QAAQ,YAAY,KAAK,EAAE;gBAC7B,OAAO,oBAAoB,CACzB,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAC3B,QAAQ,EACR,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,EAC3C,QAAQ,EACR,QAAQ,CACT,CAAC;aACH;YACD,IAAI,QAAQ,YAAY,MAAM,EAAE;gBAC9B,OAAO,oBAAoB,CACzB,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAC3B,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,EAC3C,QAAQ,EACR,QAAQ,CACT,CAAC;aACH;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK;YAC5B,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACnE,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChD,QAAQ,CAAC,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC;YACnD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QACvD,CAAC;QACD,cAAc,CAAC,MAAM,EAAE,WAAW;YAChC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/B,QAAQ,CAAC,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,IAAA,uBAAW,GAAE,CAAC,CAAC;YACrD,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AA7CD,oDA6CC"}
1
+ {"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Typescript-related helper functions and types.
3
+ */
4
+ export declare 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> ? {
5
+ readonly [ObjKey in keyof T]: DeepReadonly<T[ObjKey]>;
6
+ } : T;
7
+ export declare 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> ? {
8
+ readonly [ObjKey in keyof T]: DeepReadonly<T[ObjKey]>;
9
+ } : T;
10
+ export declare function assertIsDefined<T>(value: T): asserts value is NonNullable<T>;
11
+ 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;;;AAsBH,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 CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "firetender",
3
- "displayName": "FireTender",
3
+ "displayName": "Firetender",
4
4
  "description": "Typescript wrapper for Firestore documents",
5
- "version": "0.1.0",
5
+ "version": "0.3.1",
6
6
  "author": "Jake Hartman",
7
7
  "license": "MIT",
8
8
  "homepage": "https://github.com/jakes-space/firetender",
@@ -27,8 +27,18 @@
27
27
  "/dist"
28
28
  ],
29
29
  "scripts": {
30
- "lint": "eslint",
31
- "test": "jest"
30
+ "lint:check": "eslint src --ext .ts",
31
+ "lint:fix": "eslint --fix src --ext .ts",
32
+ "prettier:check": "prettier --check src/*.ts src/**/*.ts",
33
+ "prettier:fix": "prettier --write src/*.ts src/**/*.ts",
34
+ "check": "npm run lint:check && npm run prettier:check",
35
+ "fix": "npm run lint:fix && npm run prettier:fix",
36
+ "emulate-db": "firebase emulators:start --project=firetender",
37
+ "test": "jest --forceExit --detectOpenHandles",
38
+ "prepare": "husky install",
39
+ "clean": "rm -rf dist/*",
40
+ "build": "npm run clean && tsc && rm -rf dist/__tests__",
41
+ "prepublishOnly": "npm run check && npm run test && npm run build"
32
42
  },
33
43
  "dependencies": {
34
44
  "firebase": "^9.13.0",
@@ -44,6 +54,8 @@
44
54
  "eslint-config-prettier": "^8.5.0",
45
55
  "eslint-import-resolver-typescript": "^3.5.2",
46
56
  "eslint-plugin-import": "^2.26.0",
57
+ "eslint-plugin-prettier": "^4.2.1",
58
+ "husky": "^8.0.1",
47
59
  "jest": "^29.2.2",
48
60
  "prettier": "^2.7.1",
49
61
  "ts-jest": "^29.0.3",
@@ -1,15 +0,0 @@
1
- import { CollectionReference, DocumentReference } from "firebase/firestore";
2
- import { z } from "zod";
3
- import { FireTenderDoc, FireTenderDocOptions } from "./FireTenderDoc";
4
- /**
5
- * Factory for FireTenderDoc objects based on the given schema.
6
- */
7
- export declare class DocWrapper<SchemaType extends z.SomeZodObject, DataType extends {
8
- [x: string]: any;
9
- } = z.infer<SchemaType>> {
10
- private schema;
11
- constructor(schema: SchemaType);
12
- createNew(ref: DocumentReference | CollectionReference, initialData: any, // TODO: change to "DataType," after defaults are dropped.
13
- options?: FireTenderDocOptions): FireTenderDoc<SchemaType, DataType>;
14
- wrapExisting(ref: DocumentReference | CollectionReference, options?: FireTenderDocOptions): FireTenderDoc<SchemaType, DataType>;
15
- }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DocWrapper = void 0;
4
- const FireTenderDoc_1 = require("./FireTenderDoc");
5
- /**
6
- * Factory for FireTenderDoc objects based on the given schema.
7
- */
8
- class DocWrapper {
9
- constructor(schema) {
10
- this.schema = schema;
11
- }
12
- createNew(ref, initialData, // TODO: change to "DataType," after defaults are dropped.
13
- options = {}) {
14
- const mergedOptions = {
15
- ...options,
16
- createDoc: true,
17
- initialData,
18
- };
19
- return new FireTenderDoc_1.FireTenderDoc(this.schema, ref, mergedOptions);
20
- }
21
- wrapExisting(ref, options = {}) {
22
- return new FireTenderDoc_1.FireTenderDoc(this.schema, ref, options);
23
- }
24
- }
25
- exports.DocWrapper = DocWrapper;
26
- //# sourceMappingURL=DocWrapper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DocWrapper.js","sourceRoot":"","sources":["../src/DocWrapper.ts"],"names":[],"mappings":";;;AAEA,mDAAsE;AAEtE;;GAEG;AACH,MAAa,UAAU;IAErB,YAAoB,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAE1C,SAAS,CACP,GAA4C,EAC5C,WAAgB,EAAE,0DAA0D;IAC5E,UAAgC,EAAE;QAElC,MAAM,aAAa,GAAyB;YAC1C,GAAG,OAAO;YACV,SAAS,EAAE,IAAI;YACf,WAAW;SACZ,CAAC;QACF,OAAO,IAAI,6BAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;IAC5D,CAAC;IAED,YAAY,CACV,GAA4C,EAC5C,UAAgC,EAAE;QAElC,OAAO,IAAI,6BAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;CACF;AAvBD,gCAuBC"}
@@ -1,32 +0,0 @@
1
- import { CollectionReference, DocumentReference } from "firebase/firestore";
2
- import { z } from "zod";
3
- export declare 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> ? {
4
- readonly [ObjKey in keyof T]: DeepReadonly<T[ObjKey]>;
5
- } : T;
6
- export declare type FireTenderDocOptions = {
7
- createDoc?: true;
8
- initialData?: any;
9
- };
10
- /**
11
- * Helper class for reading and writing Firestore data based on Zod schemas.
12
- */
13
- export declare class FireTenderDoc<SchemaType extends z.SomeZodObject, DataType extends {
14
- [x: string]: any;
15
- } = z.infer<SchemaType>> {
16
- readonly schema: SchemaType;
17
- private ref;
18
- private isNewDoc;
19
- private docID;
20
- private data;
21
- private dataProxy;
22
- private updates;
23
- constructor(schema: SchemaType, ref: DocumentReference | CollectionReference, options?: FireTenderDocOptions);
24
- get id(): string | undefined;
25
- get docRef(): DocumentReference;
26
- copy(dest?: DocumentReference | CollectionReference | string | undefined, options?: FireTenderDocOptions): FireTenderDoc<SchemaType, DataType>;
27
- load(force?: boolean): Promise<this>;
28
- get ro(): DeepReadonly<DataType>;
29
- get rw(): DataType;
30
- write(): Promise<void>;
31
- private onChange;
32
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"FireTenderDoc.js","sourceRoot":"","sources":["../src/FireTenderDoc.ts"],"names":[],"mappings":"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"}