firesmelt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/admin.js ADDED
@@ -0,0 +1,236 @@
1
+ import { Database, ServerTimestampSentinel, IncrementSentinel, ArrayUnionSentinel, ArrayRemoveSentinel, DeleteFieldSentinel, FiresmeltError, toNative } from './chunk-WEVOVXQQ.js';
2
+ export { Batch, BatchCollectionHandle, BatchDocumentHandle, CollectionHandle, Database, DocumentHandle, FiresmeltError, QueryBuilder, Transaction, TxCollectionHandle, TxDocumentHandle, arrayRemove, arrayUnion, collection, deleteField, documentId, increment, isTimestampLike, serverTimestamp } from './chunk-WEVOVXQQ.js';
3
+ import { Timestamp, FieldValue, AggregateField, FieldPath } from 'firebase-admin/firestore';
4
+
5
+ var AdminDriver = class {
6
+ native;
7
+ #fs;
8
+ constructor(firestore) {
9
+ this.#fs = firestore;
10
+ this.native = {
11
+ timestampFromDate: (date) => Timestamp.fromDate(date),
12
+ fieldValue: (sentinel) => this.#fieldValue(sentinel),
13
+ // Admin serialises a Uint8Array as bytes, so hand it straight through
14
+ bytesFromUint8Array: (bytes) => bytes
15
+ };
16
+ }
17
+ #fieldValue(sentinel) {
18
+ if (sentinel instanceof ServerTimestampSentinel) {
19
+ return FieldValue.serverTimestamp();
20
+ }
21
+ if (sentinel instanceof IncrementSentinel) {
22
+ return FieldValue.increment(sentinel.by);
23
+ }
24
+ if (sentinel instanceof ArrayUnionSentinel) {
25
+ return FieldValue.arrayUnion(...this.#values(sentinel.values));
26
+ }
27
+ if (sentinel instanceof ArrayRemoveSentinel) {
28
+ return FieldValue.arrayRemove(...this.#values(sentinel.values));
29
+ }
30
+ if (sentinel instanceof DeleteFieldSentinel) {
31
+ return FieldValue.delete();
32
+ }
33
+ throw new FiresmeltError("Unknown sentinel");
34
+ }
35
+ #values(values) {
36
+ return values.map((value) => toNative(value, this.native));
37
+ }
38
+ #setOptions(options) {
39
+ if (options?.mergeFields) {
40
+ return { mergeFields: [...options.mergeFields] };
41
+ }
42
+ if (options?.merge) {
43
+ return { merge: true };
44
+ }
45
+ return void 0;
46
+ }
47
+ #doc(segments) {
48
+ return this.#fs.doc(segments.join("/"));
49
+ }
50
+ #collection(segments) {
51
+ return this.#fs.collection(segments.join("/"));
52
+ }
53
+ #query(source, constraints) {
54
+ let query = source.kind === "collection" ? this.#collection(source.segments) : this.#fs.collectionGroup(source.collectionId);
55
+ for (const constraint of constraints) {
56
+ query = this.#applyConstraint(query, constraint);
57
+ }
58
+ return query;
59
+ }
60
+ #applyConstraint(query, constraint) {
61
+ switch (constraint.type) {
62
+ case "where":
63
+ return query.where(
64
+ fieldRef(constraint.field),
65
+ constraint.op,
66
+ toNative(constraint.value, this.native)
67
+ );
68
+ case "orderBy":
69
+ return query.orderBy(fieldRef(constraint.field), constraint.direction);
70
+ case "limit":
71
+ return query.limit(constraint.limit);
72
+ case "startAt":
73
+ return query.startAt(...this.#values(constraint.values));
74
+ case "startAfter":
75
+ return query.startAfter(...this.#values(constraint.values));
76
+ case "endAt":
77
+ return query.endAt(...this.#values(constraint.values));
78
+ case "endBefore":
79
+ return query.endBefore(...this.#values(constraint.values));
80
+ }
81
+ }
82
+ async getDoc(path) {
83
+ const snapshot = await this.#doc(path.segments).get();
84
+ return { id: snapshot.id, exists: snapshot.exists, data: snapshot.data() };
85
+ }
86
+ async setDoc(path, data, options) {
87
+ const ref = this.#doc(path.segments);
88
+ const setOptions = this.#setOptions(options);
89
+ await (setOptions ? ref.set(data, setOptions) : ref.set(data));
90
+ }
91
+ async updateDoc(path, data) {
92
+ await this.#doc(path.segments).update(data);
93
+ }
94
+ async addDoc(path, data) {
95
+ const ref = await this.#collection(path.segments).add(data);
96
+ return ref.id;
97
+ }
98
+ async deleteDoc(path) {
99
+ await this.#doc(path.segments).delete();
100
+ }
101
+ async runQuery(source, constraints) {
102
+ const snapshot = await this.#query(source, constraints).get();
103
+ return snapshot.docs.map((doc) => ({
104
+ id: doc.id,
105
+ exists: true,
106
+ data: doc.data()
107
+ }));
108
+ }
109
+ async count(source, constraints) {
110
+ const snapshot = await this.#query(source, constraints).count().get();
111
+ return snapshot.data().count;
112
+ }
113
+ async sum(source, constraints, field) {
114
+ const snapshot = await this.#query(source, constraints).aggregate({ value: AggregateField.sum(field) }).get();
115
+ return snapshot.data().value;
116
+ }
117
+ async average(source, constraints, field) {
118
+ const snapshot = await this.#query(source, constraints).aggregate({ value: AggregateField.average(field) }).get();
119
+ return snapshot.data().value;
120
+ }
121
+ onSnapshotDoc(path, observer) {
122
+ return this.#doc(path.segments).onSnapshot(
123
+ (snapshot) => observer.next({
124
+ id: snapshot.id,
125
+ exists: snapshot.exists,
126
+ data: snapshot.data()
127
+ }),
128
+ observer.error?.bind(observer)
129
+ );
130
+ }
131
+ onSnapshotQuery(source, constraints, observer) {
132
+ return this.#query(source, constraints).onSnapshot(
133
+ (snapshot) => observer.next(
134
+ snapshot.docs.map((doc) => ({
135
+ id: doc.id,
136
+ exists: true,
137
+ data: doc.data()
138
+ }))
139
+ ),
140
+ observer.error?.bind(observer)
141
+ );
142
+ }
143
+ runTransaction(fn, options) {
144
+ return this.#fs.runTransaction((transaction) => {
145
+ const tx = {
146
+ get: async (path) => {
147
+ const snapshot = await transaction.get(this.#doc(path.segments));
148
+ return {
149
+ id: snapshot.id,
150
+ exists: snapshot.exists,
151
+ data: snapshot.data()
152
+ };
153
+ },
154
+ set: (path, data, options2) => {
155
+ const ref = this.#doc(path.segments);
156
+ const setOptions = this.#setOptions(options2);
157
+ if (setOptions) {
158
+ transaction.set(ref, data, setOptions);
159
+ } else {
160
+ transaction.set(ref, data);
161
+ }
162
+ },
163
+ update: (path, data) => {
164
+ transaction.update(this.#doc(path.segments), data);
165
+ },
166
+ delete: (path) => {
167
+ transaction.delete(this.#doc(path.segments));
168
+ }
169
+ };
170
+ return fn(tx);
171
+ }, options);
172
+ }
173
+ batch() {
174
+ const batch = this.#fs.batch();
175
+ return {
176
+ set: (path, data, options) => {
177
+ const ref = this.#doc(path.segments);
178
+ const setOptions = this.#setOptions(options);
179
+ if (setOptions) {
180
+ batch.set(ref, data, setOptions);
181
+ } else {
182
+ batch.set(ref, data);
183
+ }
184
+ },
185
+ update: (path, data) => {
186
+ batch.update(this.#doc(path.segments), data);
187
+ },
188
+ delete: (path) => {
189
+ batch.delete(this.#doc(path.segments));
190
+ },
191
+ commit: async () => {
192
+ await batch.commit();
193
+ }
194
+ };
195
+ }
196
+ docRef(path, converter) {
197
+ return this.#doc(path.segments).withConverter(adaptConverter(converter));
198
+ }
199
+ collectionRef(path, converter) {
200
+ return this.#collection(path.segments).withConverter(
201
+ adaptConverter(converter)
202
+ );
203
+ }
204
+ queryRef(source, constraints, converter) {
205
+ return this.#query(source, constraints).withConverter(
206
+ adaptConverter(converter)
207
+ );
208
+ }
209
+ };
210
+ function fieldRef(field) {
211
+ return typeof field === "string" ? field : FieldPath.documentId();
212
+ }
213
+ function adaptConverter(converter) {
214
+ return {
215
+ toFirestore: (model) => converter.toNative(model),
216
+ fromFirestore: (snapshot) => converter.fromNative(snapshot.id, snapshot.data())
217
+ };
218
+ }
219
+
220
+ // src/admin.ts
221
+ function createDatabase(firestore) {
222
+ return new Database(new AdminDriver(firestore));
223
+ }
224
+ function docRef(handle) {
225
+ return handle.ref;
226
+ }
227
+ function collectionRef(handle) {
228
+ return handle.ref;
229
+ }
230
+ function queryRef(builder) {
231
+ return builder.ref;
232
+ }
233
+
234
+ export { collectionRef, createDatabase, docRef, queryRef };
235
+ //# sourceMappingURL=admin.js.map
236
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/drivers/admin.ts","../src/admin.ts"],"names":["AdminTimestamp","AdminFieldValue","options","AdminFieldPath"],"mappings":"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","file":"admin.js","sourcesContent":["import {\n AggregateField,\n FieldPath as AdminFieldPath,\n FieldValue as AdminFieldValue,\n type CollectionReference,\n type DocumentReference,\n type Firestore,\n type FirestoreDataConverter,\n type Query,\n type QueryDocumentSnapshot,\n type SetOptions,\n Timestamp as AdminTimestamp,\n} from \"firebase-admin/firestore\";\n\nimport { toNative } from \"@/core/coerce\";\nimport type {\n BatchDriver,\n CollectionLocation,\n Constraint,\n DocLocation,\n DocObserver,\n DocumentData,\n Driver,\n FieldRef,\n NativeAdapter,\n QueryObserver,\n QuerySource,\n RawConverter,\n RawSnapshot,\n TransactionOptions,\n TxDriver,\n Unsubscribe,\n WriteOptions,\n} from \"@/core/driver\";\nimport { FiresmeltError } from \"@/core/errors\";\nimport {\n ArrayRemoveSentinel,\n ArrayUnionSentinel,\n DeleteFieldSentinel,\n IncrementSentinel,\n type Sentinel,\n ServerTimestampSentinel,\n} from \"@/core/firestore\";\n\n// Driver for the firebase-admin OO method-based SDK\nexport class AdminDriver implements Driver {\n readonly native: NativeAdapter;\n readonly #fs: Firestore;\n\n constructor(firestore: Firestore) {\n this.#fs = firestore;\n this.native = {\n timestampFromDate: (date) => AdminTimestamp.fromDate(date),\n fieldValue: (sentinel) => this.#fieldValue(sentinel),\n // Admin serialises a Uint8Array as bytes, so hand it straight through\n bytesFromUint8Array: (bytes) => bytes,\n };\n }\n\n #fieldValue(sentinel: Sentinel): AdminFieldValue {\n if (sentinel instanceof ServerTimestampSentinel) {\n return AdminFieldValue.serverTimestamp();\n }\n if (sentinel instanceof IncrementSentinel) {\n return AdminFieldValue.increment(sentinel.by);\n }\n if (sentinel instanceof ArrayUnionSentinel) {\n return AdminFieldValue.arrayUnion(...this.#values(sentinel.values));\n }\n if (sentinel instanceof ArrayRemoveSentinel) {\n return AdminFieldValue.arrayRemove(...this.#values(sentinel.values));\n }\n if (sentinel instanceof DeleteFieldSentinel) {\n return AdminFieldValue.delete();\n }\n throw new FiresmeltError(\"Unknown sentinel\");\n }\n\n #values(values: readonly unknown[]): unknown[] {\n return values.map((value) => toNative(value, this.native));\n }\n\n #setOptions(options?: WriteOptions): SetOptions | undefined {\n if (options?.mergeFields) {\n return { mergeFields: [...options.mergeFields] };\n }\n if (options?.merge) {\n return { merge: true };\n }\n return undefined;\n }\n\n #doc(segments: readonly string[]): DocumentReference {\n return this.#fs.doc(segments.join(\"/\"));\n }\n\n #collection(segments: readonly string[]): CollectionReference {\n return this.#fs.collection(segments.join(\"/\"));\n }\n\n #query(source: QuerySource, constraints: readonly Constraint[]): Query {\n let query: Query =\n source.kind === \"collection\"\n ? this.#collection(source.segments)\n : this.#fs.collectionGroup(source.collectionId);\n for (const constraint of constraints) {\n query = this.#applyConstraint(query, constraint);\n }\n return query;\n }\n\n #applyConstraint(query: Query, constraint: Constraint): Query {\n switch (constraint.type) {\n case \"where\":\n return query.where(\n fieldRef(constraint.field),\n constraint.op,\n toNative(constraint.value, this.native),\n );\n case \"orderBy\":\n return query.orderBy(fieldRef(constraint.field), constraint.direction);\n case \"limit\":\n return query.limit(constraint.limit);\n case \"startAt\":\n return query.startAt(...this.#values(constraint.values));\n case \"startAfter\":\n return query.startAfter(...this.#values(constraint.values));\n case \"endAt\":\n return query.endAt(...this.#values(constraint.values));\n case \"endBefore\":\n return query.endBefore(...this.#values(constraint.values));\n }\n }\n\n async getDoc(path: DocLocation): Promise<RawSnapshot> {\n const snapshot = await this.#doc(path.segments).get();\n return { id: snapshot.id, exists: snapshot.exists, data: snapshot.data() };\n }\n\n async setDoc(\n path: DocLocation,\n data: DocumentData,\n options?: WriteOptions,\n ): Promise<void> {\n const ref = this.#doc(path.segments);\n const setOptions = this.#setOptions(options);\n await (setOptions ? ref.set(data, setOptions) : ref.set(data));\n }\n\n async updateDoc(path: DocLocation, data: DocumentData): Promise<void> {\n await this.#doc(path.segments).update(data);\n }\n\n async addDoc(path: CollectionLocation, data: DocumentData): Promise<string> {\n const ref = await this.#collection(path.segments).add(data);\n return ref.id;\n }\n\n async deleteDoc(path: DocLocation): Promise<void> {\n await this.#doc(path.segments).delete();\n }\n\n async runQuery(\n source: QuerySource,\n constraints: readonly Constraint[],\n ): Promise<RawSnapshot[]> {\n const snapshot = await this.#query(source, constraints).get();\n return snapshot.docs.map((doc) => ({\n id: doc.id,\n exists: true,\n data: doc.data(),\n }));\n }\n\n async count(\n source: QuerySource,\n constraints: readonly Constraint[],\n ): Promise<number> {\n const snapshot = await this.#query(source, constraints).count().get();\n return snapshot.data().count;\n }\n\n async sum(\n source: QuerySource,\n constraints: readonly Constraint[],\n field: string,\n ): Promise<number> {\n const snapshot = await this.#query(source, constraints)\n .aggregate({ value: AggregateField.sum(field) })\n .get();\n return snapshot.data().value;\n }\n\n async average(\n source: QuerySource,\n constraints: readonly Constraint[],\n field: string,\n ): Promise<number | null> {\n const snapshot = await this.#query(source, constraints)\n .aggregate({ value: AggregateField.average(field) })\n .get();\n return snapshot.data().value;\n }\n\n onSnapshotDoc(path: DocLocation, observer: DocObserver): Unsubscribe {\n return this.#doc(path.segments).onSnapshot(\n (snapshot) =>\n observer.next({\n id: snapshot.id,\n exists: snapshot.exists,\n data: snapshot.data(),\n }),\n observer.error?.bind(observer),\n );\n }\n\n onSnapshotQuery(\n source: QuerySource,\n constraints: readonly Constraint[],\n observer: QueryObserver,\n ): Unsubscribe {\n return this.#query(source, constraints).onSnapshot(\n (snapshot) =>\n observer.next(\n snapshot.docs.map((doc) => ({\n id: doc.id,\n exists: true,\n data: doc.data(),\n })),\n ),\n observer.error?.bind(observer),\n );\n }\n\n runTransaction<T>(\n fn: (tx: TxDriver) => Promise<T>,\n options?: TransactionOptions,\n ): Promise<T> {\n return this.#fs.runTransaction((transaction) => {\n const tx: TxDriver = {\n get: async (path) => {\n const snapshot = await transaction.get(this.#doc(path.segments));\n return {\n id: snapshot.id,\n exists: snapshot.exists,\n data: snapshot.data(),\n };\n },\n set: (path, data, options) => {\n const ref = this.#doc(path.segments);\n const setOptions = this.#setOptions(options);\n if (setOptions) {\n transaction.set(ref, data, setOptions);\n } else {\n transaction.set(ref, data);\n }\n },\n update: (path, data) => {\n transaction.update(this.#doc(path.segments), data);\n },\n delete: (path) => {\n transaction.delete(this.#doc(path.segments));\n },\n };\n return fn(tx);\n }, options);\n }\n\n batch(): BatchDriver {\n const batch = this.#fs.batch();\n return {\n set: (path, data, options) => {\n const ref = this.#doc(path.segments);\n const setOptions = this.#setOptions(options);\n if (setOptions) {\n batch.set(ref, data, setOptions);\n } else {\n batch.set(ref, data);\n }\n },\n update: (path, data) => {\n batch.update(this.#doc(path.segments), data);\n },\n delete: (path) => {\n batch.delete(this.#doc(path.segments));\n },\n commit: async () => {\n await batch.commit();\n },\n };\n }\n\n docRef(path: DocLocation, converter: RawConverter): unknown {\n return this.#doc(path.segments).withConverter(adaptConverter(converter));\n }\n\n collectionRef(path: CollectionLocation, converter: RawConverter): unknown {\n return this.#collection(path.segments).withConverter(\n adaptConverter(converter),\n );\n }\n\n queryRef(\n source: QuerySource,\n constraints: readonly Constraint[],\n converter: RawConverter,\n ): unknown {\n return this.#query(source, constraints).withConverter(\n adaptConverter(converter),\n );\n }\n}\n\n// Document id reference translates to SDK documentId field path\nfunction fieldRef(field: FieldRef): string | AdminFieldPath {\n return typeof field === \"string\" ? field : AdminFieldPath.documentId();\n}\n\nfunction adaptConverter(\n converter: RawConverter,\n): FirestoreDataConverter<DocumentData> {\n return {\n toFirestore: (model) => converter.toNative(model),\n fromFirestore: (snapshot: QueryDocumentSnapshot) =>\n converter.fromNative(snapshot.id, snapshot.data()) as DocumentData,\n };\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type {\n CollectionReference,\n DocumentReference,\n Firestore,\n Query,\n} from \"firebase-admin/firestore\";\n\nimport { Database } from \"@/core/database\";\nimport type { CollectionHandle, DocumentHandle } from \"@/core/handles\";\nimport type { QueryBuilder } from \"@/core/query\";\nimport type { Doc } from \"@/core/types\";\nimport { AdminDriver } from \"@/drivers/admin\";\n\nexport function createDatabase(firestore: Firestore): Database {\n return new Database(new AdminDriver(firestore));\n}\n\n// Typed escape hatches, cast the neutral unknown .ref to the admin SDK ref\nexport function docRef<S extends StandardSchemaV1>(\n handle: DocumentHandle<S>,\n): DocumentReference<Doc<S>> {\n return handle.ref as DocumentReference<Doc<S>>;\n}\n\nexport function collectionRef<S extends StandardSchemaV1>(\n handle: CollectionHandle<S>,\n): CollectionReference<Doc<S>> {\n return handle.ref as CollectionReference<Doc<S>>;\n}\n\nexport function queryRef<S extends StandardSchemaV1>(\n builder: QueryBuilder<S>,\n): Query<Doc<S>> {\n return builder.ref as Query<Doc<S>>;\n}\n\nexport * from \"@/index\";\n"]}