firestore-batch-updater 1.20.0 → 1.21.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 +29 -0
- package/README.md +29 -0
- package/dist/index.d.mts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +50 -0
- package/dist/index.mjs +50 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
- ID 직접 조회 - `getOne()`으로 문서 ID로 빠른 조회
|
|
27
27
|
- 문서 ID 존재 확인 - `has(id)`로 데이터 읽기 없이 특정 문서 ID 존재 여부 확인
|
|
28
28
|
- 다중 ID 조회 - `pick(ids)`로 여러 문서 ID를 한 번에 효율적으로 조회
|
|
29
|
+
- 처음 & 마지막 문서 - `first()` / `last()`로 정렬 기준 첫 번째/마지막 문서 조회
|
|
29
30
|
- 벌크 작업 - `bulkCreate()`, `bulkUpdate()`, `bulkDelete()`로 여러 문서에 각기 다른 데이터로 효율적 처리
|
|
30
31
|
- 문서 변환 - `transform()`으로 각 문서에 커스텀 로직 적용 (가격 인상, 데이터 마이그레이션 등)
|
|
31
32
|
- 복사 & 이동 - `copyTo()`로 컬렉션 간 문서 복사/이동 (데이터 변환 옵션 포함)
|
|
@@ -113,6 +114,8 @@ console.log(`${result.successCount}개 문서 업데이트 완료`);
|
|
|
113
114
|
| `getOne(id)` | ID로 문서 직접 조회 | `{ id, data } \| null` |
|
|
114
115
|
| `has(id)` | 문서 ID 존재 여부 확인 | `boolean` |
|
|
115
116
|
| `pick(ids)` | 여러 문서 ID로 한 번에 조회 | `{ id, data }[]` |
|
|
117
|
+
| `first()` | 정렬 기준 첫 번째 문서 조회 | `{ id, data } \| null` |
|
|
118
|
+
| `last()` | 정렬 기준 마지막 문서 조회 | `{ id, data } \| null` |
|
|
116
119
|
| `getAll()` | 모든 매칭 문서 조회 | `{ id, data }[]` |
|
|
117
120
|
| `preview(data)` | 업데이트 전 미리보기 | `PreviewResult` |
|
|
118
121
|
| `update(data, options?)` | 매칭되는 문서 업데이트 | `UpdateResult` |
|
|
@@ -686,6 +689,32 @@ const docs = await updater
|
|
|
686
689
|
// prod-1, prod-3만 반환 (존재하는 경우)
|
|
687
690
|
```
|
|
688
691
|
|
|
692
|
+
### 처음 & 마지막 문서 조회
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
// 정렬 기준 첫 번째 문서 조회
|
|
696
|
+
const youngest = await updater
|
|
697
|
+
.collection("users")
|
|
698
|
+
.orderBy("age", "asc")
|
|
699
|
+
.first();
|
|
700
|
+
console.log(`최연소: ${youngest?.data.name}`);
|
|
701
|
+
|
|
702
|
+
// 정렬 기준 마지막 문서 조회
|
|
703
|
+
const oldest = await updater
|
|
704
|
+
.collection("users")
|
|
705
|
+
.orderBy("age", "asc")
|
|
706
|
+
.last();
|
|
707
|
+
console.log(`최고령: ${oldest?.data.name}`);
|
|
708
|
+
|
|
709
|
+
// where, select와 함께 사용
|
|
710
|
+
const cheapest = await updater
|
|
711
|
+
.collection("products")
|
|
712
|
+
.where("price", ">=", 10)
|
|
713
|
+
.select("name", "price")
|
|
714
|
+
.orderBy("price", "asc")
|
|
715
|
+
.first();
|
|
716
|
+
```
|
|
717
|
+
|
|
689
718
|
### 벌크 업데이트
|
|
690
719
|
|
|
691
720
|
```typescript
|
package/README.md
CHANGED
|
@@ -26,6 +26,7 @@ English | [한국어](./README.ko.md)
|
|
|
26
26
|
- Direct ID lookup - Use `getOne()` for fast document retrieval by ID
|
|
27
27
|
- Document ID check - Use `has(id)` to check if a specific document ID exists without reading data
|
|
28
28
|
- Multi-ID lookup - Use `pick(ids)` to get multiple documents by IDs in a single efficient call
|
|
29
|
+
- First & Last - Use `first()` / `last()` to get the first or last document by orderBy
|
|
29
30
|
- Bulk operations - Use `bulkCreate()`, `bulkUpdate()`, `bulkDelete()` for efficient multi-document operations with different data each
|
|
30
31
|
- Transform - Use `transform()` to apply custom logic to each document (e.g., price increase, data migration)
|
|
31
32
|
- Copy & Move - Use `copyTo()` to copy/move documents between collections with optional data transformation
|
|
@@ -113,6 +114,8 @@ console.log(`Updated ${result.successCount} documents`);
|
|
|
113
114
|
| `getOne(id)` | Get document by ID directly | `{ id, data } \| null` |
|
|
114
115
|
| `has(id)` | Check if document ID exists | `boolean` |
|
|
115
116
|
| `pick(ids)` | Get multiple documents by IDs | `{ id, data }[]` |
|
|
117
|
+
| `first()` | Get first document by orderBy | `{ id, data } \| null` |
|
|
118
|
+
| `last()` | Get last document by orderBy | `{ id, data } \| null` |
|
|
116
119
|
| `getAll()` | Get all matching documents | `{ id, data }[]` |
|
|
117
120
|
| `preview(data)` | Preview changes before update | `PreviewResult` |
|
|
118
121
|
| `update(data, options?)` | Update matching documents | `UpdateResult` |
|
|
@@ -705,6 +708,32 @@ const docs = await updater
|
|
|
705
708
|
// Returns only prod-1 and prod-3 (if they exist)
|
|
706
709
|
```
|
|
707
710
|
|
|
711
|
+
### First & Last Document
|
|
712
|
+
|
|
713
|
+
```typescript
|
|
714
|
+
// Get the first document (by orderBy)
|
|
715
|
+
const youngest = await updater
|
|
716
|
+
.collection("users")
|
|
717
|
+
.orderBy("age", "asc")
|
|
718
|
+
.first();
|
|
719
|
+
console.log(`Youngest: ${youngest?.data.name}`);
|
|
720
|
+
|
|
721
|
+
// Get the last document (by orderBy)
|
|
722
|
+
const oldest = await updater
|
|
723
|
+
.collection("users")
|
|
724
|
+
.orderBy("age", "asc")
|
|
725
|
+
.last();
|
|
726
|
+
console.log(`Oldest: ${oldest?.data.name}`);
|
|
727
|
+
|
|
728
|
+
// Works with where and select
|
|
729
|
+
const cheapest = await updater
|
|
730
|
+
.collection("products")
|
|
731
|
+
.where("price", ">=", 10)
|
|
732
|
+
.select("name", "price")
|
|
733
|
+
.orderBy("price", "asc")
|
|
734
|
+
.first();
|
|
735
|
+
```
|
|
736
|
+
|
|
708
737
|
### Bulk Update with Different Data
|
|
709
738
|
|
|
710
739
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -644,6 +644,25 @@ declare class BatchUpdater {
|
|
|
644
644
|
id: string;
|
|
645
645
|
data: Record<string, any>;
|
|
646
646
|
}[]>;
|
|
647
|
+
/**
|
|
648
|
+
* Get the first document based on the current orderBy conditions
|
|
649
|
+
* Requires at least one orderBy() to be set
|
|
650
|
+
* @returns First document with id and data, or null if no documents match
|
|
651
|
+
*/
|
|
652
|
+
first(): Promise<{
|
|
653
|
+
id: string;
|
|
654
|
+
data: Record<string, any>;
|
|
655
|
+
} | null>;
|
|
656
|
+
/**
|
|
657
|
+
* Get the last document based on the current orderBy conditions
|
|
658
|
+
* Requires at least one orderBy() to be set
|
|
659
|
+
* Reverses the orderBy direction internally to fetch the last document efficiently
|
|
660
|
+
* @returns Last document with id and data, or null if no documents match
|
|
661
|
+
*/
|
|
662
|
+
last(): Promise<{
|
|
663
|
+
id: string;
|
|
664
|
+
data: Record<string, any>;
|
|
665
|
+
} | null>;
|
|
647
666
|
/**
|
|
648
667
|
* Update the first document matching the query conditions
|
|
649
668
|
* @param updateData - Data to update
|
package/dist/index.d.ts
CHANGED
|
@@ -644,6 +644,25 @@ declare class BatchUpdater {
|
|
|
644
644
|
id: string;
|
|
645
645
|
data: Record<string, any>;
|
|
646
646
|
}[]>;
|
|
647
|
+
/**
|
|
648
|
+
* Get the first document based on the current orderBy conditions
|
|
649
|
+
* Requires at least one orderBy() to be set
|
|
650
|
+
* @returns First document with id and data, or null if no documents match
|
|
651
|
+
*/
|
|
652
|
+
first(): Promise<{
|
|
653
|
+
id: string;
|
|
654
|
+
data: Record<string, any>;
|
|
655
|
+
} | null>;
|
|
656
|
+
/**
|
|
657
|
+
* Get the last document based on the current orderBy conditions
|
|
658
|
+
* Requires at least one orderBy() to be set
|
|
659
|
+
* Reverses the orderBy direction internally to fetch the last document efficiently
|
|
660
|
+
* @returns Last document with id and data, or null if no documents match
|
|
661
|
+
*/
|
|
662
|
+
last(): Promise<{
|
|
663
|
+
id: string;
|
|
664
|
+
data: Record<string, any>;
|
|
665
|
+
} | null>;
|
|
647
666
|
/**
|
|
648
667
|
* Update the first document matching the query conditions
|
|
649
668
|
* @param updateData - Data to update
|
package/dist/index.js
CHANGED
|
@@ -416,6 +416,56 @@ var BatchUpdater = class {
|
|
|
416
416
|
data: snap.data()
|
|
417
417
|
}));
|
|
418
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* Get the first document based on the current orderBy conditions
|
|
421
|
+
* Requires at least one orderBy() to be set
|
|
422
|
+
* @returns First document with id and data, or null if no documents match
|
|
423
|
+
*/
|
|
424
|
+
async first() {
|
|
425
|
+
this.validateSetup();
|
|
426
|
+
if (this.orderByConditions.length === 0) {
|
|
427
|
+
throw new Error("first() requires at least one orderBy() condition");
|
|
428
|
+
}
|
|
429
|
+
const query = this.buildQuery().limit(1);
|
|
430
|
+
const snapshot = await query.get();
|
|
431
|
+
if (snapshot.empty) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
const doc = snapshot.docs[0];
|
|
435
|
+
return { id: doc.id, data: doc.data() };
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Get the last document based on the current orderBy conditions
|
|
439
|
+
* Requires at least one orderBy() to be set
|
|
440
|
+
* Reverses the orderBy direction internally to fetch the last document efficiently
|
|
441
|
+
* @returns Last document with id and data, or null if no documents match
|
|
442
|
+
*/
|
|
443
|
+
async last() {
|
|
444
|
+
this.validateSetup();
|
|
445
|
+
if (this.orderByConditions.length === 0) {
|
|
446
|
+
throw new Error("last() requires at least one orderBy() condition");
|
|
447
|
+
}
|
|
448
|
+
let query = this.isCollectionGroup ? this.firestore.collectionGroup(this.collectionPath) : this.firestore.collection(this.collectionPath);
|
|
449
|
+
for (const condition of this.conditions) {
|
|
450
|
+
query = query.where(condition.field, condition.operator, condition.value);
|
|
451
|
+
}
|
|
452
|
+
for (const orderBy of this.orderByConditions) {
|
|
453
|
+
query = query.orderBy(
|
|
454
|
+
orderBy.field,
|
|
455
|
+
orderBy.direction === "asc" ? "desc" : "asc"
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
if (this.selectedFields && this.selectedFields.length > 0) {
|
|
459
|
+
query = query.select(...this.selectedFields);
|
|
460
|
+
}
|
|
461
|
+
query = query.limit(1);
|
|
462
|
+
const snapshot = await query.get();
|
|
463
|
+
if (snapshot.empty) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
const doc = snapshot.docs[0];
|
|
467
|
+
return { id: doc.id, data: doc.data() };
|
|
468
|
+
}
|
|
419
469
|
/**
|
|
420
470
|
* Update the first document matching the query conditions
|
|
421
471
|
* @param updateData - Data to update
|
package/dist/index.mjs
CHANGED
|
@@ -371,6 +371,56 @@ var BatchUpdater = class {
|
|
|
371
371
|
data: snap.data()
|
|
372
372
|
}));
|
|
373
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Get the first document based on the current orderBy conditions
|
|
376
|
+
* Requires at least one orderBy() to be set
|
|
377
|
+
* @returns First document with id and data, or null if no documents match
|
|
378
|
+
*/
|
|
379
|
+
async first() {
|
|
380
|
+
this.validateSetup();
|
|
381
|
+
if (this.orderByConditions.length === 0) {
|
|
382
|
+
throw new Error("first() requires at least one orderBy() condition");
|
|
383
|
+
}
|
|
384
|
+
const query = this.buildQuery().limit(1);
|
|
385
|
+
const snapshot = await query.get();
|
|
386
|
+
if (snapshot.empty) {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
const doc = snapshot.docs[0];
|
|
390
|
+
return { id: doc.id, data: doc.data() };
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Get the last document based on the current orderBy conditions
|
|
394
|
+
* Requires at least one orderBy() to be set
|
|
395
|
+
* Reverses the orderBy direction internally to fetch the last document efficiently
|
|
396
|
+
* @returns Last document with id and data, or null if no documents match
|
|
397
|
+
*/
|
|
398
|
+
async last() {
|
|
399
|
+
this.validateSetup();
|
|
400
|
+
if (this.orderByConditions.length === 0) {
|
|
401
|
+
throw new Error("last() requires at least one orderBy() condition");
|
|
402
|
+
}
|
|
403
|
+
let query = this.isCollectionGroup ? this.firestore.collectionGroup(this.collectionPath) : this.firestore.collection(this.collectionPath);
|
|
404
|
+
for (const condition of this.conditions) {
|
|
405
|
+
query = query.where(condition.field, condition.operator, condition.value);
|
|
406
|
+
}
|
|
407
|
+
for (const orderBy of this.orderByConditions) {
|
|
408
|
+
query = query.orderBy(
|
|
409
|
+
orderBy.field,
|
|
410
|
+
orderBy.direction === "asc" ? "desc" : "asc"
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
if (this.selectedFields && this.selectedFields.length > 0) {
|
|
414
|
+
query = query.select(...this.selectedFields);
|
|
415
|
+
}
|
|
416
|
+
query = query.limit(1);
|
|
417
|
+
const snapshot = await query.get();
|
|
418
|
+
if (snapshot.empty) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const doc = snapshot.docs[0];
|
|
422
|
+
return { id: doc.id, data: doc.data() };
|
|
423
|
+
}
|
|
374
424
|
/**
|
|
375
425
|
* Update the first document matching the query conditions
|
|
376
426
|
* @param updateData - Data to update
|