@prmichaelsen/firebase-admin-sdk-v8 2.2.1 → 2.2.2
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/CHANGELOG.md +63 -0
- package/dist/index.d.mts +109 -1
- package/dist/index.d.ts +109 -1
- package/dist/index.js +46 -0
- package/dist/index.mjs +43 -0
- package/package.json +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Collection iteration functions: `listDocuments()`, `iterateCollection()`, and `countDocuments()`
|
|
12
|
+
- Automatic pagination support for large collections
|
|
13
|
+
- Support for iterating with filters and ordering
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **BREAKING**: `fromFirestoreValue()` now throws an error for unknown Firestore value types instead of returning `null`
|
|
17
|
+
- Removed debug console.log statements from production code in `auth.ts`
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Silent failures in Firestore data conversion now throw descriptive errors
|
|
21
|
+
|
|
22
|
+
## [2.2.1] - 2026-02-12
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Modular Firestore architecture with separate modules for converters, operations, query-builder, transforms, and path-validation
|
|
26
|
+
- Comprehensive path validation for Firestore operations
|
|
27
|
+
- Support for subcollection queries
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
- Refactored Firestore implementation into modular structure
|
|
31
|
+
- Improved error messages for path validation
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- Subcollection query support using correct REST API endpoints
|
|
35
|
+
- Path validation for nested collections
|
|
36
|
+
|
|
37
|
+
## [2.2.0] - Previous Release
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
- Firebase Storage support with signed URLs
|
|
41
|
+
- Custom token creation and sign-in
|
|
42
|
+
- Support for Firebase v10 session tokens
|
|
43
|
+
- Field transforms (serverTimestamp, increment, arrayUnion, arrayRemove, delete)
|
|
44
|
+
- Batch write operations
|
|
45
|
+
- Advanced query support (where, orderBy, limit)
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- Improved token verification to support both v9 and v10 token formats
|
|
49
|
+
- Enhanced error handling across all modules
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
- Public key caching and rotation handling
|
|
53
|
+
- Token verification for multiple issuer formats
|
|
54
|
+
|
|
55
|
+
## [2.1.0] - Initial Release
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
- Core Firebase Admin SDK functionality for Cloudflare Workers
|
|
59
|
+
- Authentication with ID token verification
|
|
60
|
+
- Firestore CRUD operations via REST API
|
|
61
|
+
- Service account configuration
|
|
62
|
+
- X.509 certificate handling
|
|
63
|
+
- JWT token generation
|
package/dist/index.d.mts
CHANGED
|
@@ -480,6 +480,114 @@ declare function queryDocuments(collectionPath: string, options?: QueryOptions):
|
|
|
480
480
|
*/
|
|
481
481
|
declare function batchWrite(operations: BatchWrite[]): Promise<BatchWriteResult>;
|
|
482
482
|
|
|
483
|
+
/**
|
|
484
|
+
* Firebase Admin SDK v8 - Firestore Collection Iteration
|
|
485
|
+
* Convenience functions for iterating through collections
|
|
486
|
+
*/
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* List all documents in a collection
|
|
490
|
+
* This is a convenience wrapper around queryDocuments with no filters
|
|
491
|
+
*
|
|
492
|
+
* @param collectionPath - Collection path
|
|
493
|
+
* @param options - Query options (limit, orderBy, etc.)
|
|
494
|
+
* @returns Array of documents with id and data
|
|
495
|
+
* @throws {Error} If the operation fails
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* ```typescript
|
|
499
|
+
* // List all users
|
|
500
|
+
* const users = await listDocuments('users');
|
|
501
|
+
*
|
|
502
|
+
* // List with pagination
|
|
503
|
+
* const firstPage = await listDocuments('users', { limit: 10 });
|
|
504
|
+
* const secondPage = await listDocuments('users', {
|
|
505
|
+
* limit: 10,
|
|
506
|
+
* startAfter: [firstPage[firstPage.length - 1].data.name]
|
|
507
|
+
* });
|
|
508
|
+
* ```
|
|
509
|
+
*/
|
|
510
|
+
declare function listDocuments(collectionPath: string, options?: QueryOptions): Promise<Array<{
|
|
511
|
+
id: string;
|
|
512
|
+
data: DataObject;
|
|
513
|
+
}>>;
|
|
514
|
+
/**
|
|
515
|
+
* Iterate through all documents in a collection
|
|
516
|
+
* Handles pagination automatically by fetching documents in batches
|
|
517
|
+
*
|
|
518
|
+
* @param collectionPath - Collection path
|
|
519
|
+
* @param callback - Function called for each document
|
|
520
|
+
* @param options - Iteration options
|
|
521
|
+
* @throws {Error} If the operation fails
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* // Process all messages
|
|
526
|
+
* await iterateCollection(
|
|
527
|
+
* 'users/user123/conversations/main/messages',
|
|
528
|
+
* async (msg) => {
|
|
529
|
+
* console.log('Processing message:', msg.id);
|
|
530
|
+
* // Perform operations on each message
|
|
531
|
+
* },
|
|
532
|
+
* { batchSize: 100 }
|
|
533
|
+
* );
|
|
534
|
+
*
|
|
535
|
+
* // Iterate with ordering
|
|
536
|
+
* await iterateCollection(
|
|
537
|
+
* 'users',
|
|
538
|
+
* async (user) => {
|
|
539
|
+
* console.log('User:', user.data.name);
|
|
540
|
+
* },
|
|
541
|
+
* {
|
|
542
|
+
* batchSize: 50,
|
|
543
|
+
* orderBy: [{ field: 'createdAt', direction: 'ASCENDING' }]
|
|
544
|
+
* }
|
|
545
|
+
* );
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
declare function iterateCollection(collectionPath: string, callback: (doc: {
|
|
549
|
+
id: string;
|
|
550
|
+
data: DataObject;
|
|
551
|
+
}) => Promise<void>, options?: {
|
|
552
|
+
batchSize?: number;
|
|
553
|
+
orderBy?: Array<{
|
|
554
|
+
field: string;
|
|
555
|
+
direction: 'ASCENDING' | 'DESCENDING';
|
|
556
|
+
}>;
|
|
557
|
+
where?: Array<{
|
|
558
|
+
field: string;
|
|
559
|
+
op: any;
|
|
560
|
+
value: any;
|
|
561
|
+
}>;
|
|
562
|
+
}): Promise<void>;
|
|
563
|
+
/**
|
|
564
|
+
* Count documents in a collection
|
|
565
|
+
* Note: This fetches all documents to count them, which may be expensive for large collections
|
|
566
|
+
*
|
|
567
|
+
* @param collectionPath - Collection path
|
|
568
|
+
* @param options - Query options (where filters)
|
|
569
|
+
* @returns Number of documents
|
|
570
|
+
* @throws {Error} If the operation fails
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```typescript
|
|
574
|
+
* // Count all users
|
|
575
|
+
* const totalUsers = await countDocuments('users');
|
|
576
|
+
*
|
|
577
|
+
* // Count active users
|
|
578
|
+
* const activeUsers = await countDocuments('users', {
|
|
579
|
+
* where: [{ field: 'active', op: '==', value: true }]
|
|
580
|
+
* });
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
declare function countDocuments(collectionPath: string, options?: {
|
|
584
|
+
where?: Array<{
|
|
585
|
+
field: string;
|
|
586
|
+
op: any;
|
|
587
|
+
value: any;
|
|
588
|
+
}>;
|
|
589
|
+
}): Promise<number>;
|
|
590
|
+
|
|
483
591
|
/**
|
|
484
592
|
* Firebase Storage client using Google Cloud Storage REST API
|
|
485
593
|
* Compatible with edge runtimes (Cloudflare Workers, Vercel Edge, etc.)
|
|
@@ -760,4 +868,4 @@ declare function getAdminAccessToken(): Promise<string>;
|
|
|
760
868
|
*/
|
|
761
869
|
declare function clearTokenCache(): void;
|
|
762
870
|
|
|
763
|
-
export { type BatchWrite, type BatchWriteResult, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UploadOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, createCustomToken, deleteDocument, deleteFile, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserFromToken, initializeApp, listFiles, queryDocuments, setDocument, signInWithCustomToken, updateDocument, uploadFile, verifyIdToken };
|
|
871
|
+
export { type BatchWrite, type BatchWriteResult, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UploadOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, deleteDocument, deleteFile, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, queryDocuments, setDocument, signInWithCustomToken, updateDocument, uploadFile, verifyIdToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -480,6 +480,114 @@ declare function queryDocuments(collectionPath: string, options?: QueryOptions):
|
|
|
480
480
|
*/
|
|
481
481
|
declare function batchWrite(operations: BatchWrite[]): Promise<BatchWriteResult>;
|
|
482
482
|
|
|
483
|
+
/**
|
|
484
|
+
* Firebase Admin SDK v8 - Firestore Collection Iteration
|
|
485
|
+
* Convenience functions for iterating through collections
|
|
486
|
+
*/
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* List all documents in a collection
|
|
490
|
+
* This is a convenience wrapper around queryDocuments with no filters
|
|
491
|
+
*
|
|
492
|
+
* @param collectionPath - Collection path
|
|
493
|
+
* @param options - Query options (limit, orderBy, etc.)
|
|
494
|
+
* @returns Array of documents with id and data
|
|
495
|
+
* @throws {Error} If the operation fails
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* ```typescript
|
|
499
|
+
* // List all users
|
|
500
|
+
* const users = await listDocuments('users');
|
|
501
|
+
*
|
|
502
|
+
* // List with pagination
|
|
503
|
+
* const firstPage = await listDocuments('users', { limit: 10 });
|
|
504
|
+
* const secondPage = await listDocuments('users', {
|
|
505
|
+
* limit: 10,
|
|
506
|
+
* startAfter: [firstPage[firstPage.length - 1].data.name]
|
|
507
|
+
* });
|
|
508
|
+
* ```
|
|
509
|
+
*/
|
|
510
|
+
declare function listDocuments(collectionPath: string, options?: QueryOptions): Promise<Array<{
|
|
511
|
+
id: string;
|
|
512
|
+
data: DataObject;
|
|
513
|
+
}>>;
|
|
514
|
+
/**
|
|
515
|
+
* Iterate through all documents in a collection
|
|
516
|
+
* Handles pagination automatically by fetching documents in batches
|
|
517
|
+
*
|
|
518
|
+
* @param collectionPath - Collection path
|
|
519
|
+
* @param callback - Function called for each document
|
|
520
|
+
* @param options - Iteration options
|
|
521
|
+
* @throws {Error} If the operation fails
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* // Process all messages
|
|
526
|
+
* await iterateCollection(
|
|
527
|
+
* 'users/user123/conversations/main/messages',
|
|
528
|
+
* async (msg) => {
|
|
529
|
+
* console.log('Processing message:', msg.id);
|
|
530
|
+
* // Perform operations on each message
|
|
531
|
+
* },
|
|
532
|
+
* { batchSize: 100 }
|
|
533
|
+
* );
|
|
534
|
+
*
|
|
535
|
+
* // Iterate with ordering
|
|
536
|
+
* await iterateCollection(
|
|
537
|
+
* 'users',
|
|
538
|
+
* async (user) => {
|
|
539
|
+
* console.log('User:', user.data.name);
|
|
540
|
+
* },
|
|
541
|
+
* {
|
|
542
|
+
* batchSize: 50,
|
|
543
|
+
* orderBy: [{ field: 'createdAt', direction: 'ASCENDING' }]
|
|
544
|
+
* }
|
|
545
|
+
* );
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
declare function iterateCollection(collectionPath: string, callback: (doc: {
|
|
549
|
+
id: string;
|
|
550
|
+
data: DataObject;
|
|
551
|
+
}) => Promise<void>, options?: {
|
|
552
|
+
batchSize?: number;
|
|
553
|
+
orderBy?: Array<{
|
|
554
|
+
field: string;
|
|
555
|
+
direction: 'ASCENDING' | 'DESCENDING';
|
|
556
|
+
}>;
|
|
557
|
+
where?: Array<{
|
|
558
|
+
field: string;
|
|
559
|
+
op: any;
|
|
560
|
+
value: any;
|
|
561
|
+
}>;
|
|
562
|
+
}): Promise<void>;
|
|
563
|
+
/**
|
|
564
|
+
* Count documents in a collection
|
|
565
|
+
* Note: This fetches all documents to count them, which may be expensive for large collections
|
|
566
|
+
*
|
|
567
|
+
* @param collectionPath - Collection path
|
|
568
|
+
* @param options - Query options (where filters)
|
|
569
|
+
* @returns Number of documents
|
|
570
|
+
* @throws {Error} If the operation fails
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```typescript
|
|
574
|
+
* // Count all users
|
|
575
|
+
* const totalUsers = await countDocuments('users');
|
|
576
|
+
*
|
|
577
|
+
* // Count active users
|
|
578
|
+
* const activeUsers = await countDocuments('users', {
|
|
579
|
+
* where: [{ field: 'active', op: '==', value: true }]
|
|
580
|
+
* });
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
declare function countDocuments(collectionPath: string, options?: {
|
|
584
|
+
where?: Array<{
|
|
585
|
+
field: string;
|
|
586
|
+
op: any;
|
|
587
|
+
value: any;
|
|
588
|
+
}>;
|
|
589
|
+
}): Promise<number>;
|
|
590
|
+
|
|
483
591
|
/**
|
|
484
592
|
* Firebase Storage client using Google Cloud Storage REST API
|
|
485
593
|
* Compatible with edge runtimes (Cloudflare Workers, Vercel Edge, etc.)
|
|
@@ -760,4 +868,4 @@ declare function getAdminAccessToken(): Promise<string>;
|
|
|
760
868
|
*/
|
|
761
869
|
declare function clearTokenCache(): void;
|
|
762
870
|
|
|
763
|
-
export { type BatchWrite, type BatchWriteResult, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UploadOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, createCustomToken, deleteDocument, deleteFile, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserFromToken, initializeApp, listFiles, queryDocuments, setDocument, signInWithCustomToken, updateDocument, uploadFile, verifyIdToken };
|
|
871
|
+
export { type BatchWrite, type BatchWriteResult, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UploadOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, deleteDocument, deleteFile, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, queryDocuments, setDocument, signInWithCustomToken, updateDocument, uploadFile, verifyIdToken };
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
batchWrite: () => batchWrite,
|
|
26
26
|
clearConfig: () => clearConfig,
|
|
27
27
|
clearTokenCache: () => clearTokenCache,
|
|
28
|
+
countDocuments: () => countDocuments,
|
|
28
29
|
createCustomToken: () => createCustomToken,
|
|
29
30
|
deleteDocument: () => deleteDocument,
|
|
30
31
|
deleteFile: () => deleteFile,
|
|
@@ -40,6 +41,8 @@ __export(index_exports, {
|
|
|
40
41
|
getServiceAccount: () => getServiceAccount,
|
|
41
42
|
getUserFromToken: () => getUserFromToken,
|
|
42
43
|
initializeApp: () => initializeApp,
|
|
44
|
+
iterateCollection: () => iterateCollection,
|
|
45
|
+
listDocuments: () => listDocuments,
|
|
43
46
|
listFiles: () => listFiles,
|
|
44
47
|
queryDocuments: () => queryDocuments,
|
|
45
48
|
setDocument: () => setDocument,
|
|
@@ -1127,6 +1130,46 @@ async function batchWrite(operations) {
|
|
|
1127
1130
|
return await response.json();
|
|
1128
1131
|
}
|
|
1129
1132
|
|
|
1133
|
+
// src/firestore/iteration.ts
|
|
1134
|
+
async function listDocuments(collectionPath, options) {
|
|
1135
|
+
return queryDocuments(collectionPath, options);
|
|
1136
|
+
}
|
|
1137
|
+
async function iterateCollection(collectionPath, callback, options) {
|
|
1138
|
+
const batchSize = options?.batchSize || 100;
|
|
1139
|
+
let lastDoc = null;
|
|
1140
|
+
let hasMore = true;
|
|
1141
|
+
while (hasMore) {
|
|
1142
|
+
const queryOptions = {
|
|
1143
|
+
limit: batchSize,
|
|
1144
|
+
orderBy: options?.orderBy,
|
|
1145
|
+
where: options?.where
|
|
1146
|
+
};
|
|
1147
|
+
if (lastDoc && options?.orderBy && options.orderBy.length > 0) {
|
|
1148
|
+
const cursorValues = options.orderBy.map((order) => lastDoc.data[order.field]);
|
|
1149
|
+
queryOptions.startAfter = cursorValues;
|
|
1150
|
+
}
|
|
1151
|
+
const docs = await queryDocuments(collectionPath, queryOptions);
|
|
1152
|
+
for (const doc of docs) {
|
|
1153
|
+
await callback(doc);
|
|
1154
|
+
}
|
|
1155
|
+
hasMore = docs.length === batchSize;
|
|
1156
|
+
if (hasMore && docs.length > 0) {
|
|
1157
|
+
lastDoc = docs[docs.length - 1];
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
async function countDocuments(collectionPath, options) {
|
|
1162
|
+
let count = 0;
|
|
1163
|
+
await iterateCollection(
|
|
1164
|
+
collectionPath,
|
|
1165
|
+
async () => {
|
|
1166
|
+
count++;
|
|
1167
|
+
},
|
|
1168
|
+
{ batchSize: 1e3, where: options?.where }
|
|
1169
|
+
);
|
|
1170
|
+
return count;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1130
1173
|
// src/storage/client.ts
|
|
1131
1174
|
var STORAGE_API_BASE = "https://storage.googleapis.com/storage/v1";
|
|
1132
1175
|
var UPLOAD_API_BASE = "https://storage.googleapis.com/upload/storage/v1";
|
|
@@ -1442,6 +1485,7 @@ async function generateSignedUrl(path, options) {
|
|
|
1442
1485
|
batchWrite,
|
|
1443
1486
|
clearConfig,
|
|
1444
1487
|
clearTokenCache,
|
|
1488
|
+
countDocuments,
|
|
1445
1489
|
createCustomToken,
|
|
1446
1490
|
deleteDocument,
|
|
1447
1491
|
deleteFile,
|
|
@@ -1457,6 +1501,8 @@ async function generateSignedUrl(path, options) {
|
|
|
1457
1501
|
getServiceAccount,
|
|
1458
1502
|
getUserFromToken,
|
|
1459
1503
|
initializeApp,
|
|
1504
|
+
iterateCollection,
|
|
1505
|
+
listDocuments,
|
|
1460
1506
|
listFiles,
|
|
1461
1507
|
queryDocuments,
|
|
1462
1508
|
setDocument,
|
package/dist/index.mjs
CHANGED
|
@@ -1075,6 +1075,46 @@ async function batchWrite(operations) {
|
|
|
1075
1075
|
return await response.json();
|
|
1076
1076
|
}
|
|
1077
1077
|
|
|
1078
|
+
// src/firestore/iteration.ts
|
|
1079
|
+
async function listDocuments(collectionPath, options) {
|
|
1080
|
+
return queryDocuments(collectionPath, options);
|
|
1081
|
+
}
|
|
1082
|
+
async function iterateCollection(collectionPath, callback, options) {
|
|
1083
|
+
const batchSize = options?.batchSize || 100;
|
|
1084
|
+
let lastDoc = null;
|
|
1085
|
+
let hasMore = true;
|
|
1086
|
+
while (hasMore) {
|
|
1087
|
+
const queryOptions = {
|
|
1088
|
+
limit: batchSize,
|
|
1089
|
+
orderBy: options?.orderBy,
|
|
1090
|
+
where: options?.where
|
|
1091
|
+
};
|
|
1092
|
+
if (lastDoc && options?.orderBy && options.orderBy.length > 0) {
|
|
1093
|
+
const cursorValues = options.orderBy.map((order) => lastDoc.data[order.field]);
|
|
1094
|
+
queryOptions.startAfter = cursorValues;
|
|
1095
|
+
}
|
|
1096
|
+
const docs = await queryDocuments(collectionPath, queryOptions);
|
|
1097
|
+
for (const doc of docs) {
|
|
1098
|
+
await callback(doc);
|
|
1099
|
+
}
|
|
1100
|
+
hasMore = docs.length === batchSize;
|
|
1101
|
+
if (hasMore && docs.length > 0) {
|
|
1102
|
+
lastDoc = docs[docs.length - 1];
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
async function countDocuments(collectionPath, options) {
|
|
1107
|
+
let count = 0;
|
|
1108
|
+
await iterateCollection(
|
|
1109
|
+
collectionPath,
|
|
1110
|
+
async () => {
|
|
1111
|
+
count++;
|
|
1112
|
+
},
|
|
1113
|
+
{ batchSize: 1e3, where: options?.where }
|
|
1114
|
+
);
|
|
1115
|
+
return count;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1078
1118
|
// src/storage/client.ts
|
|
1079
1119
|
var STORAGE_API_BASE = "https://storage.googleapis.com/storage/v1";
|
|
1080
1120
|
var UPLOAD_API_BASE = "https://storage.googleapis.com/upload/storage/v1";
|
|
@@ -1389,6 +1429,7 @@ export {
|
|
|
1389
1429
|
batchWrite,
|
|
1390
1430
|
clearConfig,
|
|
1391
1431
|
clearTokenCache,
|
|
1432
|
+
countDocuments,
|
|
1392
1433
|
createCustomToken,
|
|
1393
1434
|
deleteDocument,
|
|
1394
1435
|
deleteFile,
|
|
@@ -1404,6 +1445,8 @@ export {
|
|
|
1404
1445
|
getServiceAccount,
|
|
1405
1446
|
getUserFromToken,
|
|
1406
1447
|
initializeApp,
|
|
1448
|
+
iterateCollection,
|
|
1449
|
+
listDocuments,
|
|
1407
1450
|
listFiles,
|
|
1408
1451
|
queryDocuments,
|
|
1409
1452
|
setDocument,
|
package/package.json
CHANGED