11// deno-lint-ignore-file no-explicit-any
22import * as googleAuth from "google-auth-library" ;
33
4+ /**
5+ * Enum representing the available Firestore query operators
6+ */
47export enum FirestoreOperator {
58 LESS_THAN = "LESS_THAN" ,
69 LESS_THAN_OR_EQUAL = "LESS_THAN_OR_EQUAL" ,
@@ -18,6 +21,17 @@ export enum FirestoreOperator {
1821 IS_NOT_NULL = "IS_NOT_NULL" ,
1922}
2023
24+ /**
25+ * Firestore Admin Client for interacting with Google Cloud Firestore in Deno.
26+ *
27+ * Handles authentication via service account credentials and provides methods for CRUD operations.
28+ * Requires FIREBASE_SERVICE_ACCOUNT environment variable to be set with service account JSON.
29+ *
30+ * @example
31+ * ```ts
32+ * const firestore = new FirestoreAdminClient();
33+ * ```
34+ */
2135export class FirestoreAdminClient {
2236 private FIREBASE_SERVICE_ACCOUNT : any ;
2337 private GCP_PROJECT_NAME : string ;
@@ -51,7 +65,11 @@ export class FirestoreAdminClient {
5165 this . tokenExpiry = 0 ;
5266 }
5367
54- // https://firebase.google.com/docs/projects/provisioning/configure-oauth#auth
68+ /**
69+ * Refreshes the access token if expired or not present
70+ * @private
71+ * @see https://firebase.google.com/docs/projects/provisioning/configure-oauth#auth
72+ */
5573 private async refreshAccessToken ( ) : Promise < void > {
5674 const now = Date . now ( ) ;
5775 if ( ! this . accessToken || now >= this . tokenExpiry ) {
@@ -61,6 +79,11 @@ export class FirestoreAdminClient {
6179 }
6280 }
6381
82+ /**
83+ * Gets authorization headers for API requests
84+ * @private
85+ * @returns Headers object with authorization token
86+ */
6487 private async getHeaders ( ) : Promise < Record < string , string > > {
6588 await this . refreshAccessToken ( ) ;
6689 return {
@@ -74,10 +97,16 @@ export class FirestoreAdminClient {
7497 }
7598
7699 /**
77- * Create a document
78- * @param path - The path to the document
79- * @param data - The data to create
80- * @returns The created document data
100+ * Creates a new document in Firestore
101+ * @param path - The path to the collection where document will be created
102+ * @param data - The document data to create
103+ * @returns The created document data with _id and _path fields
104+ * @example
105+ * ```ts
106+ * const document = await firestore.createDocument("my-collection", {
107+ * name: "John Doe",
108+ * });
109+ * ```
81110 */
82111 async createDocument ( path : string , data : object ) : Promise < any > {
83112 const body = this . jsonToDocument ( data ) ;
@@ -100,9 +129,13 @@ export class FirestoreAdminClient {
100129 }
101130
102131 /**
103- * List all documents in a collection
132+ * Lists all documents in a collection
104133 * @param path - The path to the collection
105- * @returns The list of document names as an array of strings
134+ * @returns Array of document IDs in the collection
135+ * @example
136+ * ```ts
137+ * const documents = await firestore.listDocumentsInCollection("my-collection");
138+ * ```
106139 */
107140 async listDocumentsInCollection ( path : string ) : Promise < string [ ] > {
108141 const headers = await this . getHeaders ( ) ;
@@ -119,9 +152,13 @@ export class FirestoreAdminClient {
119152 }
120153
121154 /**
122- * Fetch a document
123- * @param path - The path to the document
155+ * Fetches a single document by path
156+ * @param path - The full path to the document
124157 * @returns The document data
158+ * @example
159+ * ```ts
160+ * const document = await firestore.getDocument("my-collection/my-document");
161+ * ```
125162 */
126163 async getDocument ( path : string ) : Promise < any > {
127164 const headers = await this . getHeaders ( ) ;
@@ -137,9 +174,42 @@ export class FirestoreAdminClient {
137174 }
138175
139176 /**
140- * Fetch all documents in a collection
177+ * Fetches all documents in a collection with optional query parameters
141178 * @param path - The path to the collection
142- * @returns The collection data
179+ * @param options - Query options including filters, ordering, limits and offsets
180+ * @returns Array of document data
181+ * @example
182+ * ```ts
183+ * // Simple case:
184+ * const documents = await firestore.getDocumentsInCollection("my-collection");
185+ *
186+ * // More complex cases:
187+ *
188+ * // Import the FirestoreOperator enum
189+ * import { FirestoreOperator } from "@koiztech/firestore-admin";
190+ *
191+ * // use some filters:
192+ * const documents = await firestore.getDocumentsInCollection("my-collection", {
193+ * where: {
194+ * filters: [
195+ * ["name", FirestoreOperator.EQUAL, "John Doe"],
196+ * ],
197+ * },
198+ * });
199+ *
200+ * // use filters, sorting and limiting:
201+ * const documents = await firestore.getDocumentsInCollection("my-collection", {
202+ * where: {
203+ * filters: [
204+ * ["name", FirestoreOperator.EQUAL, "Ivan Petrov"],
205+ * ["age", FirestoreOperator.GREATER_THAN, 20],
206+ * ["address.city", FirestoreOperator.EQUAL, "Moscow"], // example of a nested field
207+ * ],
208+ * },
209+ * orderBy: [{ field: "createdAt", direction: "DESCENDING" }], // you can sort the results
210+ * limit: 3, // you can limit the number of results
211+ * });
212+ * ```
143213 */
144214 async getDocumentsInCollection ( path : string , options ?: {
145215 where ?: {
@@ -241,11 +311,28 @@ export class FirestoreAdminClient {
241311 }
242312
243313 /**
244- * Update a document
314+ * Updates a document
245315 * @param path - The path to the document
246316 * @param data - The data to update
247- * @param updateFields - Optional. The specific fields to update
248- * @returns The updated document data
317+ * @param updateFields - Optional array of field paths to update
318+ * @returns The updated document data with _id and _path fields
319+ * @example
320+ * ```ts
321+ * await firestore.updateDocument('my-collection/my-document', {
322+ * name: 'John Doe'
323+ * })
324+ *
325+ * // ...or with specific update fields
326+ *
327+ * await firestore.updateDocument('my-collection/my-document', {
328+ * name: 'John Doe',
329+ * age: 30, // this field will not be updated
330+ * address: {
331+ * city: 'Dubai',
332+ * country: 'United Arab Emirates' // this field will not be updated
333+ * }
334+ * }, ['name', 'address.city']) // you can use nested fields as well
335+ * ```
249336 */
250337 async updateDocument (
251338 path : string ,
@@ -283,6 +370,12 @@ export class FirestoreAdminClient {
283370 } ;
284371 }
285372
373+ /**
374+ * Converts Firestore document format to JSON
375+ * @private
376+ * @param fields - The Firestore document fields
377+ * @returns Plain JavaScript object
378+ */
286379 private documentToJson ( fields : any ) : any {
287380 if ( ! fields ) {
288381 return { } ;
@@ -326,6 +419,12 @@ export class FirestoreAdminClient {
326419 return result ;
327420 }
328421
422+ /**
423+ * Encodes JavaScript values to Firestore value types
424+ * @private
425+ * @param value - The value to encode
426+ * @returns Firestore value representation
427+ */
329428 private encodeValue ( value : any ) : any {
330429 if ( typeof value === "string" ) {
331430 return { stringValue : value } ;
@@ -346,6 +445,12 @@ export class FirestoreAdminClient {
346445 }
347446 }
348447
448+ /**
449+ * Converts JSON to Firestore document format
450+ * @private
451+ * @param json - Plain JavaScript object
452+ * @returns Firestore document representation
453+ */
349454 private jsonToDocument ( json : any ) : { fields : any } {
350455 const data : any = { fields : { } } ;
351456 Object . keys ( json ) . forEach ( ( key ) => {
@@ -387,6 +492,12 @@ export class FirestoreAdminClient {
387492 return data ;
388493 }
389494
495+ /**
496+ * Handles errors from Firestore API calls
497+ * @private
498+ * @param error - The error object from Firestore
499+ * @param call - The name of the function that encountered the error
500+ */
390501 private errorHandler ( error : any , call : any ) : void {
391502 console . error (
392503 "*-*" . repeat ( 20 ) ,
@@ -398,7 +509,5 @@ export class FirestoreAdminClient {
398509 `${ error . message } \n` ,
399510 "*-*" . repeat ( 20 ) ,
400511 ) ;
401- // process.exit(1) // Uncomment this line for Node.js
402- // Deno.exit(1) // Uncomment this line for Deno
403512 }
404513}
0 commit comments