@caperjs/plugin-firebase 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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) Relish Interactive
4
+ Copyright (c) 2026 Anthony Sapp
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,133 @@
1
+ import { IApplication, Plugin } from '@caperjs/core';
2
+ import { FirebaseApp, FirebaseOptions } from 'firebase/app';
3
+ import { DocumentData, Firestore, QueryConstraint } from 'firebase/firestore';
4
+ interface DocumentResult extends DocumentData {
5
+ id: string;
6
+ [key: string]: unknown;
7
+ }
8
+ interface IFirebasePluginOptions extends FirebaseOptions {
9
+ debug?: boolean;
10
+ }
11
+ export interface IFirebasePlugin {
12
+ db: Firestore;
13
+ firebaseApp: FirebaseApp;
14
+ initialize(options: Partial<FirebaseOptions>, app: IApplication): void;
15
+ save<DocumentResult>(collectionName: string, data: DocumentData, id?: string): Promise<DocumentResult>;
16
+ getDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;
17
+ getDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;
18
+ getCollection(collectionName: string): Promise<DocumentResult[]>;
19
+ deleteDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;
20
+ deleteDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;
21
+ deleteCollection(collectionName: string): Promise<void>;
22
+ queryCollection(collectionName: string, ...queries: QueryConstraint[]): Promise<DocumentResult[]>;
23
+ }
24
+ /**
25
+ * A class representing a storage adapter that uses Firebase.
26
+ * @extends StorageAdapter
27
+ */
28
+ export declare class FirebasePlugin extends Plugin<IFirebasePluginOptions> implements IFirebasePlugin {
29
+ private _options;
30
+ private _firebaseApp;
31
+ /**
32
+ * Returns the Firebase app.
33
+ * @returns {FirebaseApp} The Firebase app.
34
+ */
35
+ get firebaseApp(): FirebaseApp;
36
+ private _db;
37
+ /**
38
+ * Returns the Firestore database.
39
+ * @returns {Firestore} The Firestore database.
40
+ */
41
+ get db(): Firestore;
42
+ private hello;
43
+ /**
44
+ * Initializes the adapter.
45
+ * @param {IApplication} _app The application that the adapter belongs to.
46
+ * @param {FirebaseOptions} options The options to initialize the adapter with.
47
+ * @returns {void}
48
+ */
49
+ initialize(options: Partial<IFirebasePluginOptions>, _app: IApplication): void;
50
+ /**
51
+ * Save or update a document in a collection.
52
+ * @param {string} collectionName The name of the collection.
53
+ * @param {DocumentData} data The data to save or update.
54
+ * @param {string} id The ID of the document to save or update, if applicable.
55
+ * @returns {Promise<DocumentResult>} The saved or updated document.
56
+ *
57
+ * @example
58
+ * await this.app.firebase.save('users', { username: 'relish', score: 50 }, 'custom-id');
59
+ */
60
+ save<DocumentResult>(collectionName: string, data: DocumentData, id?: string): Promise<DocumentResult>;
61
+ /**
62
+ * Get a single document by its ID.
63
+ * @param {string} collectionName The name of the collection.
64
+ * @param {string} id The ID of the document to get.
65
+ * @returns {Promise<DocumentResult | null>} The document, or null if not found.
66
+ *
67
+ * @example
68
+ * await this.app.firebase.getDocumentById('users', 'custom-id');
69
+ */
70
+ getDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;
71
+ /**
72
+ * Get a single document by a field value.
73
+ * @param {string} collectionName The name of the collection.
74
+ * @param {string} field The field to query.
75
+ * @param {unknown} value The value to query.
76
+ * @returns {Promise<DocumentResult | null>} The document, or null if not found.
77
+ *
78
+ * @example
79
+ * await this.app.firebase.getDocumentByField('users', 'username', 'relish');
80
+ */
81
+ getDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;
82
+ /**
83
+ * Get all documents in a collection.
84
+ * @param {string} collectionName The name of the collection.
85
+ * @returns {Promise<DocumentResult[]>} An array of documents.
86
+ *
87
+ * @example
88
+ * await this.app.firebase.getCollection('users');
89
+ */
90
+ getCollection(collectionName: string): Promise<DocumentResult[]>;
91
+ /**
92
+ * Delete a document by its ID.
93
+ * @param {string} collectionName The name of the collection.
94
+ * @param {string} id The ID of the document to delete.
95
+ * @returns {Promise<DocumentResult | null>} The deleted document, or null if not found.
96
+ *
97
+ * @example
98
+ * await this.app.firebase.deleteDocumentById('users', 'custom-id');
99
+ */
100
+ deleteDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;
101
+ /**
102
+ * Delete a document by a field value.
103
+ * @param {string} collectionName The name of the collection.
104
+ * @param {string} field The field to query.
105
+ * @param {unknown} value The value to query.
106
+ * @returns {Promise<DocumentResult | null>} The deleted document, or null if not found.
107
+ *
108
+ * @example
109
+ * await this.app.firebase.deleteDocumentByField('users', 'username', 'relish');
110
+ */
111
+ deleteDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;
112
+ /**
113
+ * Delete all documents in a collection.
114
+ * @param {string} collectionName The name of the collection.
115
+ * @returns {Promise<void>} A promise that resolves when the operation is complete.
116
+ *
117
+ * @example
118
+ * await this.app.firebase.deleteCollection('users');
119
+ */
120
+ deleteCollection(collectionName: string): Promise<void>;
121
+ /**
122
+ * Query a collection.
123
+ * @param {string} collectionName The name of the collection.
124
+ * @param {QueryConstraint[]} queries The query constraints to apply.
125
+ * @returns {Promise<DocumentResult[]>} An array of documents.
126
+ *
127
+ * @example
128
+ * await this.app.firebase.queryCollection('users', where('score', '>', 0), limit(10));
129
+ */
130
+ queryCollection(collectionName: string, ...queries: QueryConstraint[]): Promise<DocumentResult[]>;
131
+ }
132
+ export {};
133
+ //# sourceMappingURL=FirebasePlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FirebasePlugin.d.ts","sourceRoot":"","sources":["../src/FirebasePlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ import { Logger as e, Plugin as t, isDev as n } from "@caperjs/core";
2
+ import { initializeApp as r } from "firebase/app";
3
+ import { addDoc as i, collection as a, deleteDoc as o, doc as s, getDoc as c, getDocs as l, getFirestore as u, query as d, setDoc as f, where as p } from "firebase/firestore";
4
+ //#region src/version.ts
5
+ var m = "0.1.0", h = "10.14.1", g = class extends t {
6
+ get firebaseApp() {
7
+ return this._firebaseApp;
8
+ }
9
+ get db() {
10
+ return this._db;
11
+ }
12
+ hello() {
13
+ let t = `%c Caper Firebase Storage Adapter v${m} | %cFirebase v${h}`;
14
+ console.log(t, "background: rgba(31, 41, 55, 1);color: #74b64c", "background: rgba(31, 41, 55, 1);color: #e91e63", "background: rgba(31, 41, 55, 1);color: #74b64c"), this._options.debug && e.log(this._options);
15
+ }
16
+ initialize(e, t) {
17
+ this._options = {
18
+ debug: n,
19
+ apiKey: t.env.VITE_FIREBASE_API_KEY || t.env.FIREBASE_API_KEY,
20
+ authDomain: t.env.VITE_FIREBASE_AUTH_DOMAIN || t.env.FIREBASE_AUTH_DOMAIN,
21
+ projectId: t.env.VITE_FIREBASE_PROJECT_ID || t.env.FIREBASE_PROJECT_ID,
22
+ storageBucket: t.env.VITE_FIREBASE_STORAGE_BUCKET || t.env.FIREBASE_STORAGE_BUCKET,
23
+ messagingSenderId: t.env.VITE_FIREBASE_MESSAGING_SENDER_ID || t.env.FIREBASE_MESSAGING_SENDER_ID,
24
+ appId: t.env.VITE_FIREBASE_APP_ID || t.env.FIREBASE_APP_ID,
25
+ ...e
26
+ }, this._firebaseApp = r(this._options), this._db = u(this._firebaseApp), this.hello();
27
+ }
28
+ async save(e, t, n) {
29
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
30
+ let r;
31
+ try {
32
+ r = n ? s(this.db, e, n) : await i(a(this.db, e), t), await f(r, t, { merge: !0 });
33
+ let o = await c(r);
34
+ return {
35
+ id: o.id,
36
+ ...o.data()
37
+ };
38
+ } catch (e) {
39
+ throw Error(`Error saving document: ${e}`);
40
+ }
41
+ }
42
+ async getDocumentById(e, t) {
43
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
44
+ let n = s(this.db, e, t);
45
+ try {
46
+ let e = await c(n);
47
+ return e.exists() && {
48
+ id: e.id,
49
+ ...e.data()
50
+ } || null;
51
+ } catch (e) {
52
+ throw Error(`Error getting document: ${e}`);
53
+ }
54
+ }
55
+ async getDocumentWhere(e, t, n) {
56
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
57
+ try {
58
+ let r = await l(d(a(this.db, e), p(t, "==", n)));
59
+ if (r.empty) return null;
60
+ {
61
+ let e = r.docs[0];
62
+ return {
63
+ id: e.id,
64
+ ...e.data()
65
+ };
66
+ }
67
+ } catch (e) {
68
+ throw Error(`Error getting document: ${e}`);
69
+ }
70
+ }
71
+ async getCollection(e) {
72
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
73
+ try {
74
+ let t = await l(a(this.db, e)), n = [];
75
+ return t.forEach((e) => {
76
+ n.push({
77
+ id: e.id,
78
+ ...e.data()
79
+ });
80
+ }), n;
81
+ } catch (e) {
82
+ throw Error(`Error getting collection: ${e}`);
83
+ }
84
+ }
85
+ async deleteDocumentById(e, t) {
86
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
87
+ try {
88
+ let n = s(this.db, e, t), r = await c(n);
89
+ return r.exists() ? (await o(n), {
90
+ id: r.id,
91
+ ...r.data()
92
+ }) : null;
93
+ } catch (e) {
94
+ throw Error(`Error deleting document: ${e}`);
95
+ }
96
+ }
97
+ async deleteDocumentWhere(e, t, n) {
98
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
99
+ try {
100
+ let r = await this.getDocumentWhere(e, t, n);
101
+ return r ? (await o(s(this.db, e, r.id)), r) : null;
102
+ } catch (e) {
103
+ throw Error(`Error deleting document: ${e}`);
104
+ }
105
+ }
106
+ async deleteCollection(e) {
107
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
108
+ try {
109
+ let t = await l(a(this.db, e)), n = [];
110
+ t.forEach((e) => {
111
+ n.push(o(e.ref));
112
+ }), await Promise.all(n);
113
+ } catch (e) {
114
+ throw Error(`Error deleting collection: ${e}`);
115
+ }
116
+ }
117
+ async queryCollection(e, ...t) {
118
+ if (!this.db) throw Error("Firestore has not been initialized. Call initialize() first.");
119
+ let n = [];
120
+ try {
121
+ return (await l(d(a(this.db, e), ...t))).forEach((e) => {
122
+ n.push({
123
+ id: e.id,
124
+ ...e.data()
125
+ });
126
+ }), n;
127
+ } catch (e) {
128
+ throw Error(`Error querying collection: ${e}`);
129
+ }
130
+ }
131
+ }, _ = g;
132
+ //#endregion
133
+ export { g as FirebasePlugin, _ as default };
134
+
135
+ //# sourceMappingURL=caper-plugin-firebase.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caper-plugin-firebase.mjs","names":[],"sources":["../src/version.ts","../src/FirebasePlugin.ts","../src/index.ts"],"sourcesContent":["export const version = '0.1.0';\nexport const firebaseVersion = '10.14.1';","import { IApplication, isDev, Logger, Plugin } from '@caperjs/core';\nimport type { FirebaseApp, FirebaseOptions } from 'firebase/app';\nimport { initializeApp } from 'firebase/app';\nimport type { DocumentData, Firestore, QueryConstraint } from 'firebase/firestore';\nimport {\n addDoc,\n collection,\n deleteDoc,\n doc,\n getDoc,\n getDocs,\n getFirestore,\n query,\n setDoc,\n where,\n} from 'firebase/firestore';\nimport { firebaseVersion, version } from './version';\n\ninterface DocumentResult extends DocumentData {\n id: string;\n [key: string]: unknown;\n}\ninterface IFirebasePluginOptions extends FirebaseOptions {\n debug?: boolean;\n}\nexport interface IFirebasePlugin {\n db: Firestore;\n firebaseApp: FirebaseApp;\n\n initialize(options: Partial<FirebaseOptions>, app: IApplication): void;\n\n save<DocumentResult>(collectionName: string, data: DocumentData, id?: string): Promise<DocumentResult>;\n\n getDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;\n\n getDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;\n\n getCollection(collectionName: string): Promise<DocumentResult[]>;\n\n deleteDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;\n\n deleteDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;\n\n deleteCollection(collectionName: string): Promise<void>;\n\n queryCollection(collectionName: string, ...queries: QueryConstraint[]): Promise<DocumentResult[]>;\n}\n\n/**\n * A class representing a storage adapter that uses Firebase.\n * @extends StorageAdapter\n */\nexport class FirebasePlugin extends Plugin<IFirebasePluginOptions> implements IFirebasePlugin {\n private _options: IFirebasePluginOptions;\n\n private _firebaseApp: FirebaseApp;\n\n /**\n * Returns the Firebase app.\n * @returns {FirebaseApp} The Firebase app.\n */\n get firebaseApp(): FirebaseApp {\n return this._firebaseApp;\n }\n\n private _db: Firestore;\n\n /**\n * Returns the Firestore database.\n * @returns {Firestore} The Firestore database.\n */\n get db() {\n return this._db;\n }\n\n private hello() {\n const hello = `%c Caper Firebase Storage Adapter v${version} | %cFirebase v${firebaseVersion}`;\n console.log(\n hello,\n 'background: rgba(31, 41, 55, 1);color: #74b64c',\n 'background: rgba(31, 41, 55, 1);color: #e91e63',\n 'background: rgba(31, 41, 55, 1);color: #74b64c',\n );\n\n if (this._options.debug) {\n Logger.log(this._options);\n }\n }\n /**\n * Initializes the adapter.\n * @param {IApplication} _app The application that the adapter belongs to.\n * @param {FirebaseOptions} options The options to initialize the adapter with.\n * @returns {void}\n */\n public initialize(options: Partial<IFirebasePluginOptions>, _app: IApplication): void {\n const defaultConfig: IFirebasePluginOptions = {\n debug: isDev,\n apiKey: _app.env.VITE_FIREBASE_API_KEY || _app.env.FIREBASE_API_KEY,\n authDomain: _app.env.VITE_FIREBASE_AUTH_DOMAIN || _app.env.FIREBASE_AUTH_DOMAIN,\n projectId: _app.env.VITE_FIREBASE_PROJECT_ID || _app.env.FIREBASE_PROJECT_ID,\n storageBucket: _app.env.VITE_FIREBASE_STORAGE_BUCKET || _app.env.FIREBASE_STORAGE_BUCKET,\n messagingSenderId: _app.env.VITE_FIREBASE_MESSAGING_SENDER_ID || _app.env.FIREBASE_MESSAGING_SENDER_ID,\n appId: _app.env.VITE_FIREBASE_APP_ID || _app.env.FIREBASE_APP_ID,\n };\n this._options = { ...defaultConfig, ...options };\n this._firebaseApp = initializeApp(this._options);\n this._db = getFirestore(this._firebaseApp); // initialize Firestore and get a reference to the database\n this.hello();\n }\n\n /**\n * Save or update a document in a collection.\n * @param {string} collectionName The name of the collection.\n * @param {DocumentData} data The data to save or update.\n * @param {string} id The ID of the document to save or update, if applicable.\n * @returns {Promise<DocumentResult>} The saved or updated document.\n *\n * @example\n * await this.app.firebase.save('users', { username: 'relish', score: 50 }, 'custom-id');\n */\n async save<DocumentResult>(collectionName: string, data: DocumentData, id?: string): Promise<DocumentResult> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n let docRef;\n try {\n if (id) {\n docRef = doc(this.db, collectionName, id);\n } else {\n docRef = await addDoc(collection(this.db, collectionName), data);\n }\n\n // If the document does not exist, it will be created.\n // If the document does exist, the data will be merged into the existing document.\n await setDoc(docRef, data, { merge: true });\n\n const docSnap = await getDoc(docRef);\n return {\n id: docSnap.id,\n ...docSnap.data(),\n } as DocumentResult;\n } catch (error) {\n throw new Error(`Error saving document: ${error}`);\n }\n }\n\n /**\n * Get a single document by its ID.\n * @param {string} collectionName The name of the collection.\n * @param {string} id The ID of the document to get.\n * @returns {Promise<DocumentResult | null>} The document, or null if not found.\n *\n * @example\n * await this.app.firebase.getDocumentById('users', 'custom-id');\n */\n async getDocumentById(collectionName: string, id: string): Promise<DocumentResult | null> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n const docRef = doc(this.db, collectionName, id);\n\n try {\n const docSnap = await getDoc(docRef);\n\n if (!docSnap.exists()) return null;\n\n const data = {\n id: docSnap.id,\n ...docSnap.data(),\n };\n\n if (!data) return null;\n\n return data;\n } catch (error) {\n throw new Error(`Error getting document: ${error}`);\n }\n }\n\n /**\n * Get a single document by a field value.\n * @param {string} collectionName The name of the collection.\n * @param {string} field The field to query.\n * @param {unknown} value The value to query.\n * @returns {Promise<DocumentResult | null>} The document, or null if not found.\n *\n * @example\n * await this.app.firebase.getDocumentByField('users', 'username', 'relish');\n */\n async getDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n try {\n const collectionRef = collection(this.db, collectionName);\n const q = query(collectionRef, where(field, '==', value));\n const querySnapshot = await getDocs(q);\n\n if (!querySnapshot.empty) {\n const doc = querySnapshot.docs[0];\n return { id: doc.id, ...doc.data() };\n } else {\n return null;\n }\n } catch (error) {\n throw new Error(`Error getting document: ${error}`);\n }\n }\n\n /**\n * Get all documents in a collection.\n * @param {string} collectionName The name of the collection.\n * @returns {Promise<DocumentResult[]>} An array of documents.\n *\n * @example\n * await this.app.firebase.getCollection('users');\n */\n async getCollection(collectionName: string): Promise<DocumentResult[]> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n try {\n const collectionRef = collection(this.db, collectionName);\n const querySnapshot = await getDocs(collectionRef);\n\n const documents: DocumentResult[] = [];\n querySnapshot.forEach((doc) => {\n documents.push({ id: doc.id, ...doc.data() });\n });\n\n return documents;\n } catch (error) {\n throw new Error(`Error getting collection: ${error}`);\n }\n }\n\n /**\n * Delete a document by its ID.\n * @param {string} collectionName The name of the collection.\n * @param {string} id The ID of the document to delete.\n * @returns {Promise<DocumentResult | null>} The deleted document, or null if not found.\n *\n * @example\n * await this.app.firebase.deleteDocumentById('users', 'custom-id');\n */\n async deleteDocumentById(collectionName: string, id: string): Promise<DocumentResult | null> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n try {\n const docRef = doc(this.db, collectionName, id);\n const docToDelete = await getDoc(docRef);\n\n if (!docToDelete.exists()) {\n return null;\n }\n\n await deleteDoc(docRef);\n return {\n id: docToDelete.id,\n ...docToDelete.data(),\n };\n } catch (error) {\n throw new Error(`Error deleting document: ${error}`);\n }\n }\n\n /**\n * Delete a document by a field value.\n * @param {string} collectionName The name of the collection.\n * @param {string} field The field to query.\n * @param {unknown} value The value to query.\n * @returns {Promise<DocumentResult | null>} The deleted document, or null if not found.\n *\n * @example\n * await this.app.firebase.deleteDocumentByField('users', 'username', 'relish');\n */\n async deleteDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n try {\n const docToDelete = await this.getDocumentWhere(collectionName, field, value);\n\n if (!docToDelete) return null;\n\n const docRef = doc(this.db, collectionName, docToDelete.id);\n await deleteDoc(docRef);\n\n return docToDelete;\n } catch (error) {\n throw new Error(`Error deleting document: ${error}`);\n }\n }\n\n /**\n * Delete all documents in a collection.\n * @param {string} collectionName The name of the collection.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n *\n * @example\n * await this.app.firebase.deleteCollection('users');\n */\n async deleteCollection(collectionName: string): Promise<void> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n try {\n const collectionRef = collection(this.db, collectionName);\n const querySnapshot = await getDocs(collectionRef);\n\n const docsToDelete: Promise<void>[] = [];\n querySnapshot.forEach((doc) => {\n docsToDelete.push(deleteDoc(doc.ref));\n });\n\n await Promise.all(docsToDelete);\n } catch (error) {\n throw new Error(`Error deleting collection: ${error}`);\n }\n }\n\n /**\n * Query a collection.\n * @param {string} collectionName The name of the collection.\n * @param {QueryConstraint[]} queries The query constraints to apply.\n * @returns {Promise<DocumentResult[]>} An array of documents.\n *\n * @example\n * await this.app.firebase.queryCollection('users', where('score', '>', 0), limit(10));\n */\n async queryCollection(collectionName: string, ...queries: QueryConstraint[]): Promise<DocumentResult[]> {\n if (!this.db) {\n throw new Error('Firestore has not been initialized. Call initialize() first.');\n }\n\n const documents: DocumentResult[] = [];\n try {\n const collectionRef = collection(this.db, collectionName);\n\n const q = query(collectionRef, ...queries);\n\n const querySnapshot = await getDocs(q);\n querySnapshot.forEach((doc) => {\n documents.push({ id: doc.id, ...doc.data() });\n });\n\n return documents;\n } catch (error) {\n throw new Error(`Error querying collection: ${error}`);\n }\n }\n}\n","import { FirebasePlugin } from './FirebasePlugin';\n\nexport * from './FirebasePlugin';\n\nexport default FirebasePlugin;\n"],"mappings":";;;;AAAA,IAAa,IAAU,SACV,IAAkB,WCmDlB,IAAb,cAAoC,EAA0D;CAS5F,IAAI,cAA2B;AAC7B,SAAO,KAAK;;CASd,IAAI,KAAK;AACP,SAAO,KAAK;;CAGd,QAAgB;EACd,IAAM,IAAQ,sCAAsC,EAAQ,iBAAiB;AAQ7E,EAPA,QAAQ,IACN,GACA,kDACA,kDACA,iDACD,EAEG,KAAK,SAAS,SAChB,EAAO,IAAI,KAAK,SAAS;;CAS7B,WAAkB,GAA0C,GAA0B;AAapF,EAHA,KAAK,WAAW;GARd,OAAO;GACP,QAAQ,EAAK,IAAI,yBAAyB,EAAK,IAAI;GACnD,YAAY,EAAK,IAAI,6BAA6B,EAAK,IAAI;GAC3D,WAAW,EAAK,IAAI,4BAA4B,EAAK,IAAI;GACzD,eAAe,EAAK,IAAI,gCAAgC,EAAK,IAAI;GACjE,mBAAmB,EAAK,IAAI,qCAAqC,EAAK,IAAI;GAC1E,OAAO,EAAK,IAAI,wBAAwB,EAAK,IAAI;GAEf,GAAG;GAAS,EAChD,KAAK,eAAe,EAAc,KAAK,SAAS,EAChD,KAAK,MAAM,EAAa,KAAK,aAAa,EAC1C,KAAK,OAAO;;CAad,MAAM,KAAqB,GAAwB,GAAoB,GAAsC;AAC3G,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;EAGjF,IAAI;AACJ,MAAI;AASF,GARA,AAGE,IAHE,IACO,EAAI,KAAK,IAAI,GAAgB,EAAG,GAEhC,MAAM,EAAO,EAAW,KAAK,IAAI,EAAe,EAAE,EAAK,EAKlE,MAAM,EAAO,GAAQ,GAAM,EAAE,OAAO,IAAM,CAAC;GAE3C,IAAM,IAAU,MAAM,EAAO,EAAO;AACpC,UAAO;IACL,IAAI,EAAQ;IACZ,GAAG,EAAQ,MAAM;IAClB;WACM,GAAO;AACd,SAAU,MAAM,0BAA0B,IAAQ;;;CAatD,MAAM,gBAAgB,GAAwB,GAA4C;AACxF,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;EAEjF,IAAM,IAAS,EAAI,KAAK,IAAI,GAAgB,EAAG;AAE/C,MAAI;GACF,IAAM,IAAU,MAAM,EAAO,EAAO;AAWpC,UATK,EAAQ,QAAQ,IAER;IACX,IAAI,EAAQ;IACZ,GAAG,EAAQ,MAAM;IAClB,IAL6B;WAUvB,GAAO;AACd,SAAU,MAAM,2BAA2B,IAAQ;;;CAcvD,MAAM,iBAAiB,GAAwB,GAAe,GAAgD;AAC5G,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;AAGjF,MAAI;GAGF,IAAM,IAAgB,MAAM,EADlB,EADY,EAAW,KAAK,IAAI,EAAe,EAC1B,EAAM,GAAO,MAAM,EAAM,CAAC,CACnB;AAEtC,OAAK,EAAc,MAIjB,QAAO;GAJiB;IACxB,IAAM,IAAM,EAAc,KAAK;AAC/B,WAAO;KAAE,IAAI,EAAI;KAAI,GAAG,EAAI,MAAM;KAAE;;WAI/B,GAAO;AACd,SAAU,MAAM,2BAA2B,IAAQ;;;CAYvD,MAAM,cAAc,GAAmD;AACrE,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;AAGjF,MAAI;GAEF,IAAM,IAAgB,MAAM,EADN,EAAW,KAAK,IAAI,EAAe,CACP,EAE5C,IAA8B,EAAE;AAKtC,UAJA,EAAc,SAAS,MAAQ;AAC7B,MAAU,KAAK;KAAE,IAAI,EAAI;KAAI,GAAG,EAAI,MAAM;KAAE,CAAC;KAC7C,EAEK;WACA,GAAO;AACd,SAAU,MAAM,6BAA6B,IAAQ;;;CAazD,MAAM,mBAAmB,GAAwB,GAA4C;AAC3F,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;AAGjF,MAAI;GACF,IAAM,IAAS,EAAI,KAAK,IAAI,GAAgB,EAAG,EACzC,IAAc,MAAM,EAAO,EAAO;AAOxC,UALK,EAAY,QAAQ,IAIzB,MAAM,EAAU,EAAO,EAChB;IACL,IAAI,EAAY;IAChB,GAAG,EAAY,MAAM;IACtB,IAPQ;WAQF,GAAO;AACd,SAAU,MAAM,4BAA4B,IAAQ;;;CAcxD,MAAM,oBAAoB,GAAwB,GAAe,GAAgD;AAC/G,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;AAGjF,MAAI;GACF,IAAM,IAAc,MAAM,KAAK,iBAAiB,GAAgB,GAAO,EAAM;AAO7E,UALK,KAGL,MAAM,EADS,EAAI,KAAK,IAAI,GAAgB,EAAY,GAAG,CACpC,EAEhB,KALkB;WAMlB,GAAO;AACd,SAAU,MAAM,4BAA4B,IAAQ;;;CAYxD,MAAM,iBAAiB,GAAuC;AAC5D,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;AAGjF,MAAI;GAEF,IAAM,IAAgB,MAAM,EADN,EAAW,KAAK,IAAI,EAAe,CACP,EAE5C,IAAgC,EAAE;AAKxC,GAJA,EAAc,SAAS,MAAQ;AAC7B,MAAa,KAAK,EAAU,EAAI,IAAI,CAAC;KACrC,EAEF,MAAM,QAAQ,IAAI,EAAa;WACxB,GAAO;AACd,SAAU,MAAM,8BAA8B,IAAQ;;;CAa1D,MAAM,gBAAgB,GAAwB,GAAG,GAAuD;AACtG,MAAI,CAAC,KAAK,GACR,OAAU,MAAM,+DAA+D;EAGjF,IAAM,IAA8B,EAAE;AACtC,MAAI;AAUF,WALsB,MAAM,EAFlB,EAFY,EAAW,KAAK,IAAI,EAAe,EAE1B,GAAG,EAAQ,CAEJ,EACxB,SAAS,MAAQ;AAC7B,MAAU,KAAK;KAAE,IAAI,EAAI;KAAI,GAAG,EAAI,MAAM;KAAE,CAAC;KAC7C,EAEK;WACA,GAAO;AACd,SAAU,MAAM,8BAA8B,IAAQ;;;GC/V5D,IAAe"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { FirebasePlugin } from './FirebasePlugin';
2
+ export * from './FirebasePlugin';
3
+ export default FirebasePlugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,cAAc,kBAAkB,CAAC;AAEjC,eAAe,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const version = "0.1.0";
2
+ export declare const firebaseVersion = "10.14.1";
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,eAAe,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@caperjs/plugin-firebase",
3
+ "version": "0.1.0",
4
+ "description": "Firebase plugin for caper",
5
+ "files": [
6
+ "lib",
7
+ "src"
8
+ ],
9
+ "main": "lib/caper-plugin-firebase.mjs",
10
+ "types": "lib/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "default": "./lib/caper-plugin-firebase.mjs",
14
+ "types": "./lib/index.d.ts"
15
+ }
16
+ },
17
+ "keywords": [
18
+ "firebase",
19
+ "plugin",
20
+ "@caperjs/core",
21
+ "caper"
22
+ ],
23
+ "author": "",
24
+ "license": "MIT",
25
+ "devDependencies": {
26
+ "@types/node": "^20.14.1",
27
+ "vite": "^8.0.7",
28
+ "vite-plugin-dts": "^4.5.3",
29
+ "@caperjs/core": "0.1.0"
30
+ },
31
+ "peerDependencies": {
32
+ "@caperjs/core": "0.1.0"
33
+ },
34
+ "dependencies": {
35
+ "firebase": "^10.12.1"
36
+ },
37
+ "scripts": {
38
+ "build": "pnpm run version && vite build",
39
+ "version": "node generateVersion.mjs",
40
+ "test": "echo \"Error: no test specified\" && exit 1"
41
+ }
42
+ }
@@ -0,0 +1,359 @@
1
+ import { IApplication, isDev, Logger, Plugin } from '@caperjs/core';
2
+ import type { FirebaseApp, FirebaseOptions } from 'firebase/app';
3
+ import { initializeApp } from 'firebase/app';
4
+ import type { DocumentData, Firestore, QueryConstraint } from 'firebase/firestore';
5
+ import {
6
+ addDoc,
7
+ collection,
8
+ deleteDoc,
9
+ doc,
10
+ getDoc,
11
+ getDocs,
12
+ getFirestore,
13
+ query,
14
+ setDoc,
15
+ where,
16
+ } from 'firebase/firestore';
17
+ import { firebaseVersion, version } from './version';
18
+
19
+ interface DocumentResult extends DocumentData {
20
+ id: string;
21
+ [key: string]: unknown;
22
+ }
23
+ interface IFirebasePluginOptions extends FirebaseOptions {
24
+ debug?: boolean;
25
+ }
26
+ export interface IFirebasePlugin {
27
+ db: Firestore;
28
+ firebaseApp: FirebaseApp;
29
+
30
+ initialize(options: Partial<FirebaseOptions>, app: IApplication): void;
31
+
32
+ save<DocumentResult>(collectionName: string, data: DocumentData, id?: string): Promise<DocumentResult>;
33
+
34
+ getDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;
35
+
36
+ getDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;
37
+
38
+ getCollection(collectionName: string): Promise<DocumentResult[]>;
39
+
40
+ deleteDocumentById(collectionName: string, id: string): Promise<DocumentResult | null>;
41
+
42
+ deleteDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null>;
43
+
44
+ deleteCollection(collectionName: string): Promise<void>;
45
+
46
+ queryCollection(collectionName: string, ...queries: QueryConstraint[]): Promise<DocumentResult[]>;
47
+ }
48
+
49
+ /**
50
+ * A class representing a storage adapter that uses Firebase.
51
+ * @extends StorageAdapter
52
+ */
53
+ export class FirebasePlugin extends Plugin<IFirebasePluginOptions> implements IFirebasePlugin {
54
+ private _options: IFirebasePluginOptions;
55
+
56
+ private _firebaseApp: FirebaseApp;
57
+
58
+ /**
59
+ * Returns the Firebase app.
60
+ * @returns {FirebaseApp} The Firebase app.
61
+ */
62
+ get firebaseApp(): FirebaseApp {
63
+ return this._firebaseApp;
64
+ }
65
+
66
+ private _db: Firestore;
67
+
68
+ /**
69
+ * Returns the Firestore database.
70
+ * @returns {Firestore} The Firestore database.
71
+ */
72
+ get db() {
73
+ return this._db;
74
+ }
75
+
76
+ private hello() {
77
+ const hello = `%c Caper Firebase Storage Adapter v${version} | %cFirebase v${firebaseVersion}`;
78
+ console.log(
79
+ hello,
80
+ 'background: rgba(31, 41, 55, 1);color: #74b64c',
81
+ 'background: rgba(31, 41, 55, 1);color: #e91e63',
82
+ 'background: rgba(31, 41, 55, 1);color: #74b64c',
83
+ );
84
+
85
+ if (this._options.debug) {
86
+ Logger.log(this._options);
87
+ }
88
+ }
89
+ /**
90
+ * Initializes the adapter.
91
+ * @param {IApplication} _app The application that the adapter belongs to.
92
+ * @param {FirebaseOptions} options The options to initialize the adapter with.
93
+ * @returns {void}
94
+ */
95
+ public initialize(options: Partial<IFirebasePluginOptions>, _app: IApplication): void {
96
+ const defaultConfig: IFirebasePluginOptions = {
97
+ debug: isDev,
98
+ apiKey: _app.env.VITE_FIREBASE_API_KEY || _app.env.FIREBASE_API_KEY,
99
+ authDomain: _app.env.VITE_FIREBASE_AUTH_DOMAIN || _app.env.FIREBASE_AUTH_DOMAIN,
100
+ projectId: _app.env.VITE_FIREBASE_PROJECT_ID || _app.env.FIREBASE_PROJECT_ID,
101
+ storageBucket: _app.env.VITE_FIREBASE_STORAGE_BUCKET || _app.env.FIREBASE_STORAGE_BUCKET,
102
+ messagingSenderId: _app.env.VITE_FIREBASE_MESSAGING_SENDER_ID || _app.env.FIREBASE_MESSAGING_SENDER_ID,
103
+ appId: _app.env.VITE_FIREBASE_APP_ID || _app.env.FIREBASE_APP_ID,
104
+ };
105
+ this._options = { ...defaultConfig, ...options };
106
+ this._firebaseApp = initializeApp(this._options);
107
+ this._db = getFirestore(this._firebaseApp); // initialize Firestore and get a reference to the database
108
+ this.hello();
109
+ }
110
+
111
+ /**
112
+ * Save or update a document in a collection.
113
+ * @param {string} collectionName The name of the collection.
114
+ * @param {DocumentData} data The data to save or update.
115
+ * @param {string} id The ID of the document to save or update, if applicable.
116
+ * @returns {Promise<DocumentResult>} The saved or updated document.
117
+ *
118
+ * @example
119
+ * await this.app.firebase.save('users', { username: 'relish', score: 50 }, 'custom-id');
120
+ */
121
+ async save<DocumentResult>(collectionName: string, data: DocumentData, id?: string): Promise<DocumentResult> {
122
+ if (!this.db) {
123
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
124
+ }
125
+
126
+ let docRef;
127
+ try {
128
+ if (id) {
129
+ docRef = doc(this.db, collectionName, id);
130
+ } else {
131
+ docRef = await addDoc(collection(this.db, collectionName), data);
132
+ }
133
+
134
+ // If the document does not exist, it will be created.
135
+ // If the document does exist, the data will be merged into the existing document.
136
+ await setDoc(docRef, data, { merge: true });
137
+
138
+ const docSnap = await getDoc(docRef);
139
+ return {
140
+ id: docSnap.id,
141
+ ...docSnap.data(),
142
+ } as DocumentResult;
143
+ } catch (error) {
144
+ throw new Error(`Error saving document: ${error}`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Get a single document by its ID.
150
+ * @param {string} collectionName The name of the collection.
151
+ * @param {string} id The ID of the document to get.
152
+ * @returns {Promise<DocumentResult | null>} The document, or null if not found.
153
+ *
154
+ * @example
155
+ * await this.app.firebase.getDocumentById('users', 'custom-id');
156
+ */
157
+ async getDocumentById(collectionName: string, id: string): Promise<DocumentResult | null> {
158
+ if (!this.db) {
159
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
160
+ }
161
+ const docRef = doc(this.db, collectionName, id);
162
+
163
+ try {
164
+ const docSnap = await getDoc(docRef);
165
+
166
+ if (!docSnap.exists()) return null;
167
+
168
+ const data = {
169
+ id: docSnap.id,
170
+ ...docSnap.data(),
171
+ };
172
+
173
+ if (!data) return null;
174
+
175
+ return data;
176
+ } catch (error) {
177
+ throw new Error(`Error getting document: ${error}`);
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Get a single document by a field value.
183
+ * @param {string} collectionName The name of the collection.
184
+ * @param {string} field The field to query.
185
+ * @param {unknown} value The value to query.
186
+ * @returns {Promise<DocumentResult | null>} The document, or null if not found.
187
+ *
188
+ * @example
189
+ * await this.app.firebase.getDocumentByField('users', 'username', 'relish');
190
+ */
191
+ async getDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null> {
192
+ if (!this.db) {
193
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
194
+ }
195
+
196
+ try {
197
+ const collectionRef = collection(this.db, collectionName);
198
+ const q = query(collectionRef, where(field, '==', value));
199
+ const querySnapshot = await getDocs(q);
200
+
201
+ if (!querySnapshot.empty) {
202
+ const doc = querySnapshot.docs[0];
203
+ return { id: doc.id, ...doc.data() };
204
+ } else {
205
+ return null;
206
+ }
207
+ } catch (error) {
208
+ throw new Error(`Error getting document: ${error}`);
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Get all documents in a collection.
214
+ * @param {string} collectionName The name of the collection.
215
+ * @returns {Promise<DocumentResult[]>} An array of documents.
216
+ *
217
+ * @example
218
+ * await this.app.firebase.getCollection('users');
219
+ */
220
+ async getCollection(collectionName: string): Promise<DocumentResult[]> {
221
+ if (!this.db) {
222
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
223
+ }
224
+
225
+ try {
226
+ const collectionRef = collection(this.db, collectionName);
227
+ const querySnapshot = await getDocs(collectionRef);
228
+
229
+ const documents: DocumentResult[] = [];
230
+ querySnapshot.forEach((doc) => {
231
+ documents.push({ id: doc.id, ...doc.data() });
232
+ });
233
+
234
+ return documents;
235
+ } catch (error) {
236
+ throw new Error(`Error getting collection: ${error}`);
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Delete a document by its ID.
242
+ * @param {string} collectionName The name of the collection.
243
+ * @param {string} id The ID of the document to delete.
244
+ * @returns {Promise<DocumentResult | null>} The deleted document, or null if not found.
245
+ *
246
+ * @example
247
+ * await this.app.firebase.deleteDocumentById('users', 'custom-id');
248
+ */
249
+ async deleteDocumentById(collectionName: string, id: string): Promise<DocumentResult | null> {
250
+ if (!this.db) {
251
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
252
+ }
253
+
254
+ try {
255
+ const docRef = doc(this.db, collectionName, id);
256
+ const docToDelete = await getDoc(docRef);
257
+
258
+ if (!docToDelete.exists()) {
259
+ return null;
260
+ }
261
+
262
+ await deleteDoc(docRef);
263
+ return {
264
+ id: docToDelete.id,
265
+ ...docToDelete.data(),
266
+ };
267
+ } catch (error) {
268
+ throw new Error(`Error deleting document: ${error}`);
269
+ }
270
+ }
271
+
272
+ /**
273
+ * Delete a document by a field value.
274
+ * @param {string} collectionName The name of the collection.
275
+ * @param {string} field The field to query.
276
+ * @param {unknown} value The value to query.
277
+ * @returns {Promise<DocumentResult | null>} The deleted document, or null if not found.
278
+ *
279
+ * @example
280
+ * await this.app.firebase.deleteDocumentByField('users', 'username', 'relish');
281
+ */
282
+ async deleteDocumentWhere(collectionName: string, field: string, value: unknown): Promise<DocumentResult | null> {
283
+ if (!this.db) {
284
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
285
+ }
286
+
287
+ try {
288
+ const docToDelete = await this.getDocumentWhere(collectionName, field, value);
289
+
290
+ if (!docToDelete) return null;
291
+
292
+ const docRef = doc(this.db, collectionName, docToDelete.id);
293
+ await deleteDoc(docRef);
294
+
295
+ return docToDelete;
296
+ } catch (error) {
297
+ throw new Error(`Error deleting document: ${error}`);
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Delete all documents in a collection.
303
+ * @param {string} collectionName The name of the collection.
304
+ * @returns {Promise<void>} A promise that resolves when the operation is complete.
305
+ *
306
+ * @example
307
+ * await this.app.firebase.deleteCollection('users');
308
+ */
309
+ async deleteCollection(collectionName: string): Promise<void> {
310
+ if (!this.db) {
311
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
312
+ }
313
+
314
+ try {
315
+ const collectionRef = collection(this.db, collectionName);
316
+ const querySnapshot = await getDocs(collectionRef);
317
+
318
+ const docsToDelete: Promise<void>[] = [];
319
+ querySnapshot.forEach((doc) => {
320
+ docsToDelete.push(deleteDoc(doc.ref));
321
+ });
322
+
323
+ await Promise.all(docsToDelete);
324
+ } catch (error) {
325
+ throw new Error(`Error deleting collection: ${error}`);
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Query a collection.
331
+ * @param {string} collectionName The name of the collection.
332
+ * @param {QueryConstraint[]} queries The query constraints to apply.
333
+ * @returns {Promise<DocumentResult[]>} An array of documents.
334
+ *
335
+ * @example
336
+ * await this.app.firebase.queryCollection('users', where('score', '>', 0), limit(10));
337
+ */
338
+ async queryCollection(collectionName: string, ...queries: QueryConstraint[]): Promise<DocumentResult[]> {
339
+ if (!this.db) {
340
+ throw new Error('Firestore has not been initialized. Call initialize() first.');
341
+ }
342
+
343
+ const documents: DocumentResult[] = [];
344
+ try {
345
+ const collectionRef = collection(this.db, collectionName);
346
+
347
+ const q = query(collectionRef, ...queries);
348
+
349
+ const querySnapshot = await getDocs(q);
350
+ querySnapshot.forEach((doc) => {
351
+ documents.push({ id: doc.id, ...doc.data() });
352
+ });
353
+
354
+ return documents;
355
+ } catch (error) {
356
+ throw new Error(`Error querying collection: ${error}`);
357
+ }
358
+ }
359
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { FirebasePlugin } from './FirebasePlugin';
2
+
3
+ export * from './FirebasePlugin';
4
+
5
+ export default FirebasePlugin;
package/src/version.ts ADDED
@@ -0,0 +1,2 @@
1
+ export const version = '0.1.0';
2
+ export const firebaseVersion = '10.14.1';
@@ -0,0 +1,14 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_FIREBASE_API_KEY: string;
5
+ readonly VITE_FIREBASE_AUTH_DOMAIN: string;
6
+ readonly VITE_FIREBASE_PROJECT_ID: string;
7
+ readonly VITE_FIREBASE_STORAGE_BUCKET: string;
8
+ readonly VITE_FIREBASE_MESSAGING_SENDER_ID: string;
9
+ readonly VITE_FIREBASE_APP_ID: string;
10
+ }
11
+
12
+ interface ImportMeta {
13
+ readonly env: ImportMetaEnv;
14
+ }