@njdamstra/appwrite-utils-cli 1.11.3 → 1.11.4
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.
|
@@ -4,6 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
+
import pLimit from "p-limit";
|
|
7
8
|
import { MessageFormatter, tryAwaitWithRetry, } from "@njdamstra/appwrite-utils-helpers";
|
|
8
9
|
import { ProgressManager } from "../shared/progressManager.js";
|
|
9
10
|
import { MigrationPlanSchema, MigrationCheckpointSchema, suggestTargetType, generateBackupKey, } from "./migrateStringsTypes.js";
|
|
@@ -461,6 +462,7 @@ async function copyAttributeData(adapter, databaseId, collectionId, sourceKey, t
|
|
|
461
462
|
title: ` Copy ${sourceKey} → ${targetKey}`,
|
|
462
463
|
})
|
|
463
464
|
: undefined;
|
|
465
|
+
const limit = pLimit(5);
|
|
464
466
|
while (true) {
|
|
465
467
|
const queries = [Query.limit(batchSize)];
|
|
466
468
|
if (lastId)
|
|
@@ -469,34 +471,18 @@ async function copyAttributeData(adapter, databaseId, collectionId, sourceKey, t
|
|
|
469
471
|
const docs = res?.documents || res?.rows || [];
|
|
470
472
|
if (docs.length === 0)
|
|
471
473
|
break;
|
|
472
|
-
//
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
rows,
|
|
485
|
-
}));
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
for (const doc of docs) {
|
|
490
|
-
if (doc[sourceKey] === undefined)
|
|
491
|
-
continue;
|
|
492
|
-
await tryAwaitWithRetry(() => adapter.updateRow({
|
|
493
|
-
databaseId,
|
|
494
|
-
tableId: collectionId,
|
|
495
|
-
id: doc.$id,
|
|
496
|
-
data: { [targetKey]: doc[sourceKey] },
|
|
497
|
-
}));
|
|
498
|
-
}
|
|
499
|
-
}
|
|
474
|
+
// Partial update: copy sourceKey → targetKey using updateRow (not bulkUpsert
|
|
475
|
+
// which requires complete document structure and fails on partial payloads)
|
|
476
|
+
const updatePromises = docs
|
|
477
|
+
.filter((d) => d[sourceKey] !== undefined)
|
|
478
|
+
.map((d) => limit(() => tryAwaitWithRetry(() => adapter.updateRow({
|
|
479
|
+
databaseId,
|
|
480
|
+
tableId: collectionId,
|
|
481
|
+
id: d.$id,
|
|
482
|
+
data: { [targetKey]: d[sourceKey] },
|
|
483
|
+
}), 0, true // throwError — surface 400s immediately
|
|
484
|
+
)));
|
|
485
|
+
await Promise.all(updatePromises);
|
|
500
486
|
totalCopied += docs.length;
|
|
501
487
|
lastId = docs[docs.length - 1].$id;
|
|
502
488
|
progress?.update(totalCopied);
|
|
@@ -519,7 +505,7 @@ async function verifyDataCopy(adapter, databaseId, collectionId, sourceKey, targ
|
|
|
519
505
|
}));
|
|
520
506
|
const docs = res?.documents || res?.rows || [];
|
|
521
507
|
for (const doc of docs) {
|
|
522
|
-
if (
|
|
508
|
+
if (!(sourceKey in doc))
|
|
523
509
|
continue;
|
|
524
510
|
if (doc[sourceKey] !== doc[targetKey]) {
|
|
525
511
|
throw new Error(`Verification failed: doc ${doc.$id} has ${sourceKey}=${JSON.stringify(doc[sourceKey])} but ${targetKey}=${JSON.stringify(doc[targetKey])}`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@njdamstra/appwrite-utils-cli",
|
|
3
3
|
"description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
|
|
4
|
-
"version": "1.11.
|
|
4
|
+
"version": "1.11.4",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
@@ -4,6 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
+
import pLimit from "p-limit";
|
|
7
8
|
import {
|
|
8
9
|
type DatabaseAdapter,
|
|
9
10
|
MessageFormatter,
|
|
@@ -688,6 +689,8 @@ async function copyAttributeData(
|
|
|
688
689
|
})
|
|
689
690
|
: undefined;
|
|
690
691
|
|
|
692
|
+
const limit = pLimit(5);
|
|
693
|
+
|
|
691
694
|
while (true) {
|
|
692
695
|
const queries: string[] = [Query.limit(batchSize)];
|
|
693
696
|
if (lastId) queries.push(Query.cursorAfter(lastId));
|
|
@@ -699,37 +702,26 @@ async function copyAttributeData(
|
|
|
699
702
|
const docs = res?.documents || res?.rows || [];
|
|
700
703
|
if (docs.length === 0) break;
|
|
701
704
|
|
|
702
|
-
//
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if (doc[sourceKey] === undefined) continue;
|
|
723
|
-
await tryAwaitWithRetry(() =>
|
|
724
|
-
adapter.updateRow({
|
|
725
|
-
databaseId,
|
|
726
|
-
tableId: collectionId,
|
|
727
|
-
id: doc.$id,
|
|
728
|
-
data: { [targetKey]: doc[sourceKey] },
|
|
729
|
-
})
|
|
730
|
-
);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
705
|
+
// Partial update: copy sourceKey → targetKey using updateRow (not bulkUpsert
|
|
706
|
+
// which requires complete document structure and fails on partial payloads)
|
|
707
|
+
const updatePromises = docs
|
|
708
|
+
.filter((d: any) => d[sourceKey] !== undefined)
|
|
709
|
+
.map((d: any) =>
|
|
710
|
+
limit(() =>
|
|
711
|
+
tryAwaitWithRetry(
|
|
712
|
+
() =>
|
|
713
|
+
adapter.updateRow({
|
|
714
|
+
databaseId,
|
|
715
|
+
tableId: collectionId,
|
|
716
|
+
id: d.$id,
|
|
717
|
+
data: { [targetKey]: d[sourceKey] },
|
|
718
|
+
}),
|
|
719
|
+
0,
|
|
720
|
+
true // throwError — surface 400s immediately
|
|
721
|
+
)
|
|
722
|
+
)
|
|
723
|
+
);
|
|
724
|
+
await Promise.all(updatePromises);
|
|
733
725
|
|
|
734
726
|
totalCopied += docs.length;
|
|
735
727
|
lastId = docs[docs.length - 1].$id;
|
|
@@ -763,7 +755,7 @@ async function verifyDataCopy(
|
|
|
763
755
|
);
|
|
764
756
|
const docs = res?.documents || res?.rows || [];
|
|
765
757
|
for (const doc of docs) {
|
|
766
|
-
if (
|
|
758
|
+
if (!(sourceKey in doc)) continue;
|
|
767
759
|
if (doc[sourceKey] !== doc[targetKey]) {
|
|
768
760
|
throw new Error(
|
|
769
761
|
`Verification failed: doc ${doc.$id} has ${sourceKey}=${JSON.stringify(doc[sourceKey])} but ${targetKey}=${JSON.stringify(doc[targetKey])}`
|