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 +86 -44
- package/dist/FiretenderDoc.d.ts +39 -0
- package/dist/{FireTenderDoc.js → FiretenderDoc.js} +27 -18
- package/dist/FiretenderDoc.js.map +1 -0
- package/dist/Timestamps.js +0 -2
- package/dist/Timestamps.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/proxies.js +7 -11
- package/dist/proxies.js.map +1 -1
- package/dist/ts-helpers.d.ts +11 -0
- package/dist/ts-helpers.js +19 -0
- package/dist/ts-helpers.js.map +1 -0
- package/package.json +16 -4
- package/dist/DocWrapper.d.ts +0 -15
- package/dist/DocWrapper.js +0 -26
- package/dist/DocWrapper.js.map +0 -1
- package/dist/FireTenderDoc.d.ts +0 -32
- package/dist/FireTenderDoc.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Firetender
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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,
|
|
15
|
-
|
|
14
|
+
To illustrate, let's run through the basics of defining, creating, modifying,
|
|
15
|
+
and copying a Firestore document.
|
|
16
16
|
|
|
17
|
-
###
|
|
17
|
+
### Initialize Cloud Firestore
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
[
|
|
21
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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 {
|
|
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
|
|
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
|
|
58
|
-
|
|
59
|
-
by calling
|
|
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 =
|
|
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
|
|
72
|
-
(
|
|
73
|
-
|
|
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
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
86
|
-
const isMeatIncluded = Object.entries(pizza.
|
|
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.
|
|
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
|
-
|
|
98
|
-
|
|
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
|
|
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
|
-
*
|
|
123
|
-
* Block on failing tests
|
|
156
|
+
* Improved timestamp handling, tests
|
|
157
|
+
* Releases
|
|
124
158
|
* Minify code (esbuild?)
|
|
125
|
-
*
|
|
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
|
|
140
|
-
|
|
180
|
+
* [firestore-fp](https://github.com/mobily/firestore-fp): If you like functional
|
|
181
|
+
programming.
|
|
141
182
|
|
|
142
|
-
* [simplyfire](https://github.com/coturiv/simplyfire):
|
|
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.
|
|
3
|
+
exports.FiretenderDoc = void 0;
|
|
4
4
|
const firestore_1 = require("firebase/firestore");
|
|
5
5
|
const proxies_1 = require("./proxies");
|
|
6
|
-
|
|
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
|
|
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("
|
|
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
|
|
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
|
|
94
|
+
get r() {
|
|
86
95
|
if (!this.data) {
|
|
87
|
-
throw Error("
|
|
96
|
+
throw Error("load() must be called before reading the document.");
|
|
88
97
|
}
|
|
89
98
|
return this.data;
|
|
90
99
|
}
|
|
91
|
-
get
|
|
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("
|
|
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.
|
|
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.
|
|
133
|
-
//# sourceMappingURL=
|
|
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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"}
|
package/dist/Timestamps.js
CHANGED
|
@@ -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
|
}
|
package/dist/Timestamps.js.map
CHANGED
|
@@ -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,
|
|
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
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.
|
|
18
|
-
var
|
|
19
|
-
Object.defineProperty(exports, "
|
|
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,
|
|
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
|
},
|
package/dist/proxies.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":";;;AAAA,kDAA8D;AAC9D,6BAAwB;AAExB,SAAS,
|
|
1
|
+
{"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":";;;AAAA,6CAAiD;AACjD,kDAA8D;AAC9D,6BAAwB;AAExB,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,IAAA,8BAAiB,EAAC,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,IAAA,8BAAiB,EAAC,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,IAAA,8BAAiB,EAAC,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,IAAA,8BAAiB,EAAC,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,IAAA,8BAAiB,EAAC,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,IAAA,8BAAiB,EAAC,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"}
|
|
@@ -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": "
|
|
3
|
+
"displayName": "Firetender",
|
|
4
4
|
"description": "Typescript wrapper for Firestore documents",
|
|
5
|
-
"version": "0.1
|
|
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
|
-
"
|
|
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",
|
package/dist/DocWrapper.d.ts
DELETED
|
@@ -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
|
-
}
|
package/dist/DocWrapper.js
DELETED
|
@@ -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
|
package/dist/DocWrapper.js.map
DELETED
|
@@ -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"}
|
package/dist/FireTenderDoc.d.ts
DELETED
|
@@ -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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"}
|