@firestore-repository/firebase-js-sdk 0.1.0 → 0.2.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 +143 -36
- package/package.json +2 -2
package/README.md
CHANGED
@@ -15,78 +15,185 @@ A minimum and universal Firestore ORM (Repository Pattern) for TypeScript
|
|
15
15
|
|
16
16
|
## Installation
|
17
17
|
|
18
|
-
### For backend (with `@google-cloud/firestore`
|
18
|
+
### For backend (with [`@google-cloud/firestore`](https://www.npmjs.com/package/@google-cloud/firestore))
|
19
19
|
|
20
20
|
```shell
|
21
21
|
npm install firestore-repository @firestore-repository/google-cloud-firestore
|
22
22
|
````
|
23
23
|
|
24
|
-
### For web frontend (with `firebase
|
24
|
+
### For web frontend (with [`@firebase/firestore`](https://www.npmjs.com/package/@firebase/firestore))
|
25
25
|
|
26
26
|
```shell
|
27
27
|
npm install firestore-repository @firestore-repository/firebase-js-sdk
|
28
28
|
```
|
29
29
|
|
30
|
-
##
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Define a collection and its repository
|
31
33
|
|
32
34
|
```ts
|
33
|
-
import {
|
34
|
-
import { condition as $, limit, query, where } from 'firestore-repository/query';
|
35
|
+
import { mapTo, data, rootCollection } from 'firestore-repository/schema';
|
35
36
|
|
36
37
|
// For backend
|
37
38
|
import { Firestore } from '@google-cloud/firestore';
|
38
39
|
import { Repository } from '@firestore-repository/google-cloud-firestore';
|
39
40
|
const db = new Firestore();
|
40
|
-
const repository = new Repository(authors, db);
|
41
41
|
|
42
42
|
// For web frontend
|
43
43
|
import { getFirestore } from '@firebase/firestore';
|
44
44
|
import { Repository } from '@firestore-repository/firebase-js-sdk';
|
45
45
|
const db = getFirestore();
|
46
|
-
const repository = new Repository(authors, db);
|
47
46
|
|
48
47
|
// define a collection
|
49
|
-
const
|
50
|
-
name: '
|
51
|
-
id:
|
52
|
-
data:
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
registeredAt: Timestamp;
|
61
|
-
}) => ({
|
62
|
-
...data,
|
63
|
-
registeredAt: data.registeredAt.toDate(),
|
64
|
-
}),
|
65
|
-
),
|
48
|
+
const users = rootCollection({
|
49
|
+
name: 'Users',
|
50
|
+
id: mapTo('userId'),
|
51
|
+
data: data<{
|
52
|
+
name: string;
|
53
|
+
profile: {
|
54
|
+
age: number;
|
55
|
+
gender?: 'male' | 'female';
|
56
|
+
};
|
57
|
+
tag: string[];
|
58
|
+
}>(),
|
66
59
|
});
|
67
60
|
|
68
|
-
|
61
|
+
const repository = new Repository(users, db);
|
62
|
+
```
|
63
|
+
|
64
|
+
### Basic operations for a single document
|
65
|
+
|
66
|
+
```ts
|
67
|
+
// Set a document
|
69
68
|
await repository.set({
|
70
|
-
|
69
|
+
userId: 'user1',
|
71
70
|
name: 'John Doe',
|
72
71
|
profile: {
|
73
72
|
age: 42,
|
74
73
|
gender: 'male',
|
75
74
|
},
|
76
75
|
tag: ['new'],
|
77
|
-
registeredAt: new Date(),
|
78
76
|
});
|
79
77
|
|
80
|
-
//
|
81
|
-
const doc = await repository.get({
|
82
|
-
|
78
|
+
// Get a document
|
79
|
+
const doc = await repository.get({ userId: 'user1' });
|
80
|
+
|
81
|
+
// Listen a document
|
82
|
+
repository.getOnSnapshot({ userId: 'user1' }, (doc) => {
|
83
|
+
console.log(doc);
|
84
|
+
});
|
85
|
+
|
86
|
+
// Delete a document
|
87
|
+
await repository.delete({ userId: 'user2' });
|
88
|
+
```
|
89
|
+
|
90
|
+
### Query
|
83
91
|
|
84
|
-
|
85
|
-
|
86
|
-
|
92
|
+
```ts
|
93
|
+
import { condition as $, limit, query, where } from 'firestore-repository/query';
|
94
|
+
|
95
|
+
// Define a query
|
96
|
+
const query1 = query(users, where($('profile.age', '>=', 20)), limit(10));
|
97
|
+
|
98
|
+
// List documents
|
99
|
+
const docs = await repository.list(query1);
|
87
100
|
console.log(docs);
|
88
101
|
|
89
|
-
//
|
90
|
-
|
91
|
-
|
102
|
+
// Listen documents
|
103
|
+
repository.listOnSnapshot(query1, (docs) => {
|
104
|
+
console.log(docs);
|
105
|
+
});
|
106
|
+
|
107
|
+
// Aggregate
|
108
|
+
const result = await repository.aggregate({
|
109
|
+
query: query1,
|
110
|
+
spec: {
|
111
|
+
avgAge: average('profile.age'),
|
112
|
+
sumAge: sum('profile.age'),
|
113
|
+
count: count(),
|
114
|
+
},
|
115
|
+
});
|
116
|
+
console.log(`avg:${result.avgAge} sum:${result.sumAge} count:${result.count}`);
|
92
117
|
```
|
118
|
+
|
119
|
+
### Batch operations
|
120
|
+
|
121
|
+
```ts
|
122
|
+
// Get multiple documents (backend only)
|
123
|
+
const users = await repository.batchGet([{ userId: 'user1' }, { userId: 'user2' }]);
|
124
|
+
|
125
|
+
// Set multiple documents
|
126
|
+
await repository.batchSet([
|
127
|
+
{
|
128
|
+
userId: 'user1',
|
129
|
+
name: 'Alice',
|
130
|
+
profile: { age: 30, gender: 'female' },
|
131
|
+
tag: ['new'],
|
132
|
+
},
|
133
|
+
{
|
134
|
+
userId: 'user2',
|
135
|
+
name: 'Bob',
|
136
|
+
profile: { age: 20, gender: 'male' },
|
137
|
+
tag: [],
|
138
|
+
},
|
139
|
+
]);
|
140
|
+
|
141
|
+
// Delete multiple documents
|
142
|
+
await repository.batchDelete([{ userId: 'user1' }, { userId: 'user2' }]);
|
143
|
+
```
|
144
|
+
|
145
|
+
#### Include multiple different operations in a batch
|
146
|
+
|
147
|
+
```ts
|
148
|
+
// For backend
|
149
|
+
const batch = db.writeBatch();
|
150
|
+
// For web frontend
|
151
|
+
import { writeBatch } from '@firebase/firestore';
|
152
|
+
const batch = writeBatch();
|
153
|
+
|
154
|
+
await repository.set(
|
155
|
+
{
|
156
|
+
userId: 'user3',
|
157
|
+
name: 'Bob',
|
158
|
+
profile: { age: 20, gender: 'male' },
|
159
|
+
tag: [],
|
160
|
+
},
|
161
|
+
{ tx: batch },
|
162
|
+
);
|
163
|
+
await repository.batchSet([ /* ... */ ], { tx: batch },
|
164
|
+
);
|
165
|
+
await repository.delete({ userId: 'user4' }, { tx: batch });
|
166
|
+
await repository.batchDelete([{ userId: 'user5' }, { userId: 'user6' }], {
|
167
|
+
tx: batch,
|
168
|
+
});
|
169
|
+
|
170
|
+
await batch.commit();
|
171
|
+
```
|
172
|
+
|
173
|
+
### Transaction
|
174
|
+
|
175
|
+
```ts
|
176
|
+
// For web frontend
|
177
|
+
import { runTransaction } from '@firebase/firestore';
|
178
|
+
|
179
|
+
// Or, please use db.runTransaction for backend
|
180
|
+
await runTransaction(async (tx) => {
|
181
|
+
// Get
|
182
|
+
const doc = await repository.get({ userId: 'user1' }, { tx });
|
183
|
+
|
184
|
+
if (doc) {
|
185
|
+
doc.tag = [...doc.tag, 'new-tag'];
|
186
|
+
// Set
|
187
|
+
await repository.set(doc, { tx });
|
188
|
+
await repository.batchSet([
|
189
|
+
{ ...doc, userId: 'user2' },
|
190
|
+
{ ...doc, userId: 'user3' },
|
191
|
+
]);
|
192
|
+
}
|
193
|
+
|
194
|
+
// Delete
|
195
|
+
await repository.delete({ userId: 'user4' }, { tx });
|
196
|
+
await repository.batchDelete([{ userId: 'user5' }, { userId: 'user6' }]);
|
197
|
+
});
|
198
|
+
```
|
199
|
+
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@firestore-repository/firebase-js-sdk",
|
3
|
-
"version": "0.1
|
3
|
+
"version": "0.2.1",
|
4
4
|
"description": "A minimum and universal Firestore ORM (Repository Pattern) for TypeScript",
|
5
5
|
"homepage": "https://github.com/ikenox/firestore-repository",
|
6
6
|
"repository": {
|
@@ -10,7 +10,7 @@
|
|
10
10
|
"type": "module",
|
11
11
|
"dependencies": {
|
12
12
|
"@firebase/firestore": "^4.7.5",
|
13
|
-
"firestore-repository": "0.1
|
13
|
+
"firestore-repository": "0.2.1"
|
14
14
|
},
|
15
15
|
"devDependencies": {
|
16
16
|
"@firebase/app": "^0.10.16"
|