firestore-batch-updater 1.18.0 → 1.20.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/README.ko.md +40 -0
- package/README.md +40 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +43 -0
- package/dist/index.mjs +43 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
- 통합 통계 - `fieldStats()`로 sum/avg/min/max/count 한 번에 조회
|
|
25
25
|
- 커서 페이지네이션 - `paginate()`로 메모리 효율적인 페이지 단위 조회
|
|
26
26
|
- ID 직접 조회 - `getOne()`으로 문서 ID로 빠른 조회
|
|
27
|
+
- 문서 ID 존재 확인 - `has(id)`로 데이터 읽기 없이 특정 문서 ID 존재 여부 확인
|
|
28
|
+
- 다중 ID 조회 - `pick(ids)`로 여러 문서 ID를 한 번에 효율적으로 조회
|
|
27
29
|
- 벌크 작업 - `bulkCreate()`, `bulkUpdate()`, `bulkDelete()`로 여러 문서에 각기 다른 데이터로 효율적 처리
|
|
28
30
|
- 문서 변환 - `transform()`으로 각 문서에 커스텀 로직 적용 (가격 인상, 데이터 마이그레이션 등)
|
|
29
31
|
- 복사 & 이동 - `copyTo()`로 컬렉션 간 문서 복사/이동 (데이터 변환 옵션 포함)
|
|
@@ -109,6 +111,8 @@ console.log(`${result.successCount}개 문서 업데이트 완료`);
|
|
|
109
111
|
| `isEmpty()` | 매칭되는 문서가 없는지 확인 | `boolean` |
|
|
110
112
|
| `findOne()` | 첫 번째 매칭 문서 조회 | `{ id, data } \| null` |
|
|
111
113
|
| `getOne(id)` | ID로 문서 직접 조회 | `{ id, data } \| null` |
|
|
114
|
+
| `has(id)` | 문서 ID 존재 여부 확인 | `boolean` |
|
|
115
|
+
| `pick(ids)` | 여러 문서 ID로 한 번에 조회 | `{ id, data }[]` |
|
|
112
116
|
| `getAll()` | 모든 매칭 문서 조회 | `{ id, data }[]` |
|
|
113
117
|
| `preview(data)` | 업데이트 전 미리보기 | `PreviewResult` |
|
|
114
118
|
| `update(data, options?)` | 매칭되는 문서 업데이트 | `UpdateResult` |
|
|
@@ -646,6 +650,42 @@ const order = await updater
|
|
|
646
650
|
.getOne("order-456");
|
|
647
651
|
```
|
|
648
652
|
|
|
653
|
+
### 문서 ID 존재 확인
|
|
654
|
+
|
|
655
|
+
```typescript
|
|
656
|
+
// 특정 문서 ID가 존재하는지 확인 (데이터 읽기 없이 효율적)
|
|
657
|
+
const exists = await updater.collection("users").has("user-123");
|
|
658
|
+
|
|
659
|
+
if (exists) {
|
|
660
|
+
console.log("사용자가 존재합니다!");
|
|
661
|
+
} else {
|
|
662
|
+
console.log("사용자를 찾을 수 없음");
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// 가드 절에 유용
|
|
666
|
+
if (!(await updater.collection("users").has(userId))) {
|
|
667
|
+
throw new Error("사용자를 찾을 수 없습니다");
|
|
668
|
+
}
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### 여러 문서 ID로 조회
|
|
672
|
+
|
|
673
|
+
```typescript
|
|
674
|
+
// 여러 문서를 한 번에 조회 (getOne() 여러 번 호출보다 효율적)
|
|
675
|
+
const users = await updater
|
|
676
|
+
.collection("users")
|
|
677
|
+
.pick(["user-1", "user-2", "user-3"]);
|
|
678
|
+
|
|
679
|
+
console.log(`${users.length}명 조회됨`);
|
|
680
|
+
users.forEach((u) => console.log(`${u.id}: ${u.data.name}`));
|
|
681
|
+
|
|
682
|
+
// 존재하지 않는 ID는 자동으로 건너뜀
|
|
683
|
+
const docs = await updater
|
|
684
|
+
.collection("products")
|
|
685
|
+
.pick(["prod-1", "non-existent", "prod-3"]);
|
|
686
|
+
// prod-1, prod-3만 반환 (존재하는 경우)
|
|
687
|
+
```
|
|
688
|
+
|
|
649
689
|
### 벌크 업데이트
|
|
650
690
|
|
|
651
691
|
```typescript
|
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@ English | [한국어](./README.ko.md)
|
|
|
24
24
|
- Combined stats - Use `fieldStats()` to get sum/avg/min/max/count in one call
|
|
25
25
|
- Cursor pagination - Use `paginate()` for memory-efficient page-by-page iteration
|
|
26
26
|
- Direct ID lookup - Use `getOne()` for fast document retrieval by ID
|
|
27
|
+
- Document ID check - Use `has(id)` to check if a specific document ID exists without reading data
|
|
28
|
+
- Multi-ID lookup - Use `pick(ids)` to get multiple documents by IDs in a single efficient call
|
|
27
29
|
- Bulk operations - Use `bulkCreate()`, `bulkUpdate()`, `bulkDelete()` for efficient multi-document operations with different data each
|
|
28
30
|
- Transform - Use `transform()` to apply custom logic to each document (e.g., price increase, data migration)
|
|
29
31
|
- Copy & Move - Use `copyTo()` to copy/move documents between collections with optional data transformation
|
|
@@ -109,6 +111,8 @@ console.log(`Updated ${result.successCount} documents`);
|
|
|
109
111
|
| `isEmpty()` | Check if no matching documents exist | `boolean` |
|
|
110
112
|
| `findOne()` | Find first matching document | `{ id, data } \| null` |
|
|
111
113
|
| `getOne(id)` | Get document by ID directly | `{ id, data } \| null` |
|
|
114
|
+
| `has(id)` | Check if document ID exists | `boolean` |
|
|
115
|
+
| `pick(ids)` | Get multiple documents by IDs | `{ id, data }[]` |
|
|
112
116
|
| `getAll()` | Get all matching documents | `{ id, data }[]` |
|
|
113
117
|
| `preview(data)` | Preview changes before update | `PreviewResult` |
|
|
114
118
|
| `update(data, options?)` | Update matching documents | `UpdateResult` |
|
|
@@ -665,6 +669,42 @@ const profile = await updater
|
|
|
665
669
|
.getOne("user-123");
|
|
666
670
|
```
|
|
667
671
|
|
|
672
|
+
### Check Document Exists by ID
|
|
673
|
+
|
|
674
|
+
```typescript
|
|
675
|
+
// Check if a specific document ID exists (without reading data)
|
|
676
|
+
const exists = await updater.collection("users").has("user-123");
|
|
677
|
+
|
|
678
|
+
if (exists) {
|
|
679
|
+
console.log("User exists!");
|
|
680
|
+
} else {
|
|
681
|
+
console.log("User not found");
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Useful for guard clauses before operations
|
|
685
|
+
if (!(await updater.collection("users").has(userId))) {
|
|
686
|
+
throw new Error("User not found");
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Get Multiple Documents by IDs
|
|
691
|
+
|
|
692
|
+
```typescript
|
|
693
|
+
// Get multiple documents in a single call (more efficient than multiple getOne)
|
|
694
|
+
const users = await updater
|
|
695
|
+
.collection("users")
|
|
696
|
+
.pick(["user-1", "user-2", "user-3"]);
|
|
697
|
+
|
|
698
|
+
console.log(`Found ${users.length} users`);
|
|
699
|
+
users.forEach((u) => console.log(`${u.id}: ${u.data.name}`));
|
|
700
|
+
|
|
701
|
+
// Non-existent IDs are silently skipped
|
|
702
|
+
const docs = await updater
|
|
703
|
+
.collection("products")
|
|
704
|
+
.pick(["prod-1", "non-existent", "prod-3"]);
|
|
705
|
+
// Returns only prod-1 and prod-3 (if they exist)
|
|
706
|
+
```
|
|
707
|
+
|
|
668
708
|
### Bulk Update with Different Data
|
|
669
709
|
|
|
670
710
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -629,6 +629,21 @@ declare class BatchUpdater {
|
|
|
629
629
|
id: string;
|
|
630
630
|
data: Record<string, any>;
|
|
631
631
|
} | null>;
|
|
632
|
+
/**
|
|
633
|
+
* Check if a document with the given ID exists in the collection
|
|
634
|
+
* @param id - Document ID to check
|
|
635
|
+
* @returns true if the document exists, false otherwise
|
|
636
|
+
*/
|
|
637
|
+
has(id: string): Promise<boolean>;
|
|
638
|
+
/**
|
|
639
|
+
* Get multiple documents by their IDs in a single call
|
|
640
|
+
* @param ids - Array of document IDs to retrieve
|
|
641
|
+
* @returns Array of documents with id and data (skips non-existent documents)
|
|
642
|
+
*/
|
|
643
|
+
pick(ids: string[]): Promise<{
|
|
644
|
+
id: string;
|
|
645
|
+
data: Record<string, any>;
|
|
646
|
+
}[]>;
|
|
632
647
|
/**
|
|
633
648
|
* Update the first document matching the query conditions
|
|
634
649
|
* @param updateData - Data to update
|
package/dist/index.d.ts
CHANGED
|
@@ -629,6 +629,21 @@ declare class BatchUpdater {
|
|
|
629
629
|
id: string;
|
|
630
630
|
data: Record<string, any>;
|
|
631
631
|
} | null>;
|
|
632
|
+
/**
|
|
633
|
+
* Check if a document with the given ID exists in the collection
|
|
634
|
+
* @param id - Document ID to check
|
|
635
|
+
* @returns true if the document exists, false otherwise
|
|
636
|
+
*/
|
|
637
|
+
has(id: string): Promise<boolean>;
|
|
638
|
+
/**
|
|
639
|
+
* Get multiple documents by their IDs in a single call
|
|
640
|
+
* @param ids - Array of document IDs to retrieve
|
|
641
|
+
* @returns Array of documents with id and data (skips non-existent documents)
|
|
642
|
+
*/
|
|
643
|
+
pick(ids: string[]): Promise<{
|
|
644
|
+
id: string;
|
|
645
|
+
data: Record<string, any>;
|
|
646
|
+
}[]>;
|
|
632
647
|
/**
|
|
633
648
|
* Update the first document matching the query conditions
|
|
634
649
|
* @param updateData - Data to update
|
package/dist/index.js
CHANGED
|
@@ -373,6 +373,49 @@ var BatchUpdater = class {
|
|
|
373
373
|
data: docSnapshot.data()
|
|
374
374
|
};
|
|
375
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Check if a document with the given ID exists in the collection
|
|
378
|
+
* @param id - Document ID to check
|
|
379
|
+
* @returns true if the document exists, false otherwise
|
|
380
|
+
*/
|
|
381
|
+
async has(id) {
|
|
382
|
+
this.validateSetup();
|
|
383
|
+
if (!id || typeof id !== "string") {
|
|
384
|
+
throw new Error("Document ID is required");
|
|
385
|
+
}
|
|
386
|
+
if (this.isCollectionGroup) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
"has() cannot be used with collectionGroup(). Use exists() with where conditions instead."
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
const docRef = this.firestore.collection(this.collectionPath).doc(id);
|
|
392
|
+
const docSnapshot = await docRef.get();
|
|
393
|
+
return docSnapshot.exists;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get multiple documents by their IDs in a single call
|
|
397
|
+
* @param ids - Array of document IDs to retrieve
|
|
398
|
+
* @returns Array of documents with id and data (skips non-existent documents)
|
|
399
|
+
*/
|
|
400
|
+
async pick(ids) {
|
|
401
|
+
this.validateSetup();
|
|
402
|
+
if (!Array.isArray(ids) || ids.length === 0) {
|
|
403
|
+
throw new Error("Document IDs array is required and must not be empty");
|
|
404
|
+
}
|
|
405
|
+
if (this.isCollectionGroup) {
|
|
406
|
+
throw new Error(
|
|
407
|
+
"pick() cannot be used with collectionGroup(). Use getAll() with where conditions instead."
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
const docRefs = ids.map(
|
|
411
|
+
(id) => this.firestore.collection(this.collectionPath).doc(id)
|
|
412
|
+
);
|
|
413
|
+
const snapshots = await this.firestore.getAll(...docRefs);
|
|
414
|
+
return snapshots.filter((snap) => snap.exists).map((snap) => ({
|
|
415
|
+
id: snap.id,
|
|
416
|
+
data: snap.data()
|
|
417
|
+
}));
|
|
418
|
+
}
|
|
376
419
|
/**
|
|
377
420
|
* Update the first document matching the query conditions
|
|
378
421
|
* @param updateData - Data to update
|
package/dist/index.mjs
CHANGED
|
@@ -328,6 +328,49 @@ var BatchUpdater = class {
|
|
|
328
328
|
data: docSnapshot.data()
|
|
329
329
|
};
|
|
330
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Check if a document with the given ID exists in the collection
|
|
333
|
+
* @param id - Document ID to check
|
|
334
|
+
* @returns true if the document exists, false otherwise
|
|
335
|
+
*/
|
|
336
|
+
async has(id) {
|
|
337
|
+
this.validateSetup();
|
|
338
|
+
if (!id || typeof id !== "string") {
|
|
339
|
+
throw new Error("Document ID is required");
|
|
340
|
+
}
|
|
341
|
+
if (this.isCollectionGroup) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
"has() cannot be used with collectionGroup(). Use exists() with where conditions instead."
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
const docRef = this.firestore.collection(this.collectionPath).doc(id);
|
|
347
|
+
const docSnapshot = await docRef.get();
|
|
348
|
+
return docSnapshot.exists;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Get multiple documents by their IDs in a single call
|
|
352
|
+
* @param ids - Array of document IDs to retrieve
|
|
353
|
+
* @returns Array of documents with id and data (skips non-existent documents)
|
|
354
|
+
*/
|
|
355
|
+
async pick(ids) {
|
|
356
|
+
this.validateSetup();
|
|
357
|
+
if (!Array.isArray(ids) || ids.length === 0) {
|
|
358
|
+
throw new Error("Document IDs array is required and must not be empty");
|
|
359
|
+
}
|
|
360
|
+
if (this.isCollectionGroup) {
|
|
361
|
+
throw new Error(
|
|
362
|
+
"pick() cannot be used with collectionGroup(). Use getAll() with where conditions instead."
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
const docRefs = ids.map(
|
|
366
|
+
(id) => this.firestore.collection(this.collectionPath).doc(id)
|
|
367
|
+
);
|
|
368
|
+
const snapshots = await this.firestore.getAll(...docRefs);
|
|
369
|
+
return snapshots.filter((snap) => snap.exists).map((snap) => ({
|
|
370
|
+
id: snap.id,
|
|
371
|
+
data: snap.data()
|
|
372
|
+
}));
|
|
373
|
+
}
|
|
331
374
|
/**
|
|
332
375
|
* Update the first document matching the query conditions
|
|
333
376
|
* @param updateData - Data to update
|