appwrite-utils-cli 0.0.258 → 0.0.260
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.
@@ -1562,6 +1562,17 @@ export declare class DataLoader {
|
|
1562
1562
|
private shouldWriteFile;
|
1563
1563
|
constructor(appwriteFolderPath: string, importDataActions: ImportDataActions, database: Databases, config: AppwriteConfig, shouldWriteFile?: boolean);
|
1564
1564
|
getCollectionKey(name: string): string;
|
1565
|
+
/**
|
1566
|
+
* Merges two objects by updating the source object with the target object's values.
|
1567
|
+
* It iterates through the target object's keys and updates the source object if:
|
1568
|
+
* - The source object has the key.
|
1569
|
+
* - The target object's value for that key is not null, undefined, or an empty string.
|
1570
|
+
*
|
1571
|
+
* @param source - The source object to be updated.
|
1572
|
+
* @param target - The target object with values to update the source object.
|
1573
|
+
* @returns The updated source object.
|
1574
|
+
*/
|
1575
|
+
mergeObjects(source: Record<string, any>, target: Record<string, any>): Record<string, any>;
|
1565
1576
|
loadData(importDef: ImportDef): Promise<any[]>;
|
1566
1577
|
checkMapValuesForId(newId: string, collectionName: string): string | false;
|
1567
1578
|
getTrueUniqueId(collectionName: string): string;
|
@@ -59,6 +59,28 @@ export class DataLoader {
|
|
59
59
|
getCollectionKey(name) {
|
60
60
|
return name.toLowerCase().replace(" ", "");
|
61
61
|
}
|
62
|
+
/**
|
63
|
+
* Merges two objects by updating the source object with the target object's values.
|
64
|
+
* It iterates through the target object's keys and updates the source object if:
|
65
|
+
* - The source object has the key.
|
66
|
+
* - The target object's value for that key is not null, undefined, or an empty string.
|
67
|
+
*
|
68
|
+
* @param source - The source object to be updated.
|
69
|
+
* @param target - The target object with values to update the source object.
|
70
|
+
* @returns The updated source object.
|
71
|
+
*/
|
72
|
+
mergeObjects(source, target) {
|
73
|
+
Object.keys(target).forEach((key) => {
|
74
|
+
const targetValue = target[key];
|
75
|
+
if (source.hasOwnProperty(key) &&
|
76
|
+
targetValue !== null &&
|
77
|
+
targetValue !== undefined &&
|
78
|
+
targetValue !== "") {
|
79
|
+
source[key] = targetValue;
|
80
|
+
}
|
81
|
+
});
|
82
|
+
return source;
|
83
|
+
}
|
62
84
|
// Method to load data from a file specified in the import definition
|
63
85
|
async loadData(importDef) {
|
64
86
|
// Resolve the file path and check if the file exists
|
@@ -414,16 +436,11 @@ export class DataLoader {
|
|
414
436
|
}
|
415
437
|
});
|
416
438
|
const usersMap = this.importMap.get(this.getCollectionKey("users"));
|
417
|
-
if (usersMap) {
|
418
|
-
usersMap.data.push({
|
419
|
-
rawData: item,
|
420
|
-
finalData: userData.data,
|
421
|
-
});
|
422
|
-
}
|
423
439
|
const userDataToAdd = {
|
424
440
|
rawData: item,
|
425
441
|
finalData: userData.data,
|
426
442
|
};
|
443
|
+
// Directly update the importMap with the new user data, without pushing to usersMap.data first
|
427
444
|
this.importMap.set(this.getCollectionKey("users"), {
|
428
445
|
data: [...(usersMap?.data || []), userDataToAdd],
|
429
446
|
});
|
@@ -495,7 +512,7 @@ export class DataLoader {
|
|
495
512
|
for (const data of currentData.data) {
|
496
513
|
if (data.finalData.docId === oldId ||
|
497
514
|
data.finalData.userId === oldId) {
|
498
|
-
|
515
|
+
transformedItem = this.mergeObjects(data.finalData, transformedItem);
|
499
516
|
}
|
500
517
|
}
|
501
518
|
}
|
@@ -511,8 +528,7 @@ export class DataLoader {
|
|
511
528
|
if ((currentUserData.data[i].finalData.docId === existingId ||
|
512
529
|
currentUserData.data[i].finalData.userId === existingId) &&
|
513
530
|
!_.isEqual(currentUserData.data[i], userData)) {
|
514
|
-
|
515
|
-
Object.assign(currentUserData.data[i].rawData, item);
|
531
|
+
this.mergeObjects(currentUserData.data[i].finalData, userData.finalData);
|
516
532
|
console.log("Merging user data", currentUserData.data[i].finalData);
|
517
533
|
this.importMap.set(this.getCollectionKey("users"), currentUserData);
|
518
534
|
}
|
@@ -528,10 +544,8 @@ export class DataLoader {
|
|
528
544
|
for (let i = 0; i < currentData.data.length; i++) {
|
529
545
|
if (currentData.data[i].finalData.docId === existingId ||
|
530
546
|
currentData.data[i].finalData.userId === existingId) {
|
531
|
-
currentData.data[i].finalData =
|
532
|
-
|
533
|
-
...transformedItem,
|
534
|
-
};
|
547
|
+
currentData.data[i].finalData = this.mergeObjects(currentData.data[i].finalData, transformedItem);
|
548
|
+
currentData.data[i].context = context;
|
535
549
|
currentData.data[i].importDef = newImportDef;
|
536
550
|
this.importMap.set(this.getCollectionKey(collection.name), currentData);
|
537
551
|
this.oldIdToNewIdPerCollectionMap.set(this.getCollectionKey(collection.name), collectionOldIdToNewIdMap);
|
@@ -656,7 +670,7 @@ export class DataLoader {
|
|
656
670
|
}
|
657
671
|
for (const item of rawData) {
|
658
672
|
// Transform the item data based on the attribute mappings
|
659
|
-
|
673
|
+
let transformedData = await this.transformData(item, importDef.attributeMappings);
|
660
674
|
let newId;
|
661
675
|
let oldId;
|
662
676
|
// Determine the new ID for the item based on the primary key field or update mapping
|
@@ -688,9 +702,17 @@ export class DataLoader {
|
|
688
702
|
logger.error(`No new id found for collection ${collection.name} for updateDef ${JSON.stringify(item, null, 2)} but it says it's supposed to have one...`);
|
689
703
|
continue;
|
690
704
|
}
|
705
|
+
const itemDataToUpdate = this.importMap
|
706
|
+
.get(this.getCollectionKey(collection.name))
|
707
|
+
?.data.find((data) => data.rawData[importDef.primaryKeyField] === oldId);
|
708
|
+
if (!itemDataToUpdate) {
|
709
|
+
logger.error(`No data found for collection ${collection.name} for updateDef ${JSON.stringify(item, null, 2)} but it says it's supposed to have one...`);
|
710
|
+
continue;
|
711
|
+
}
|
712
|
+
transformedData = this.mergeObjects(itemDataToUpdate.finalData, transformedData);
|
691
713
|
// Create a context object for the item, including the new ID and transformed data
|
692
714
|
let context = this.createContext(db, collection, item, newId);
|
693
|
-
context =
|
715
|
+
context = this.mergeObjects(context, transformedData);
|
694
716
|
// Validate the item before proceeding
|
695
717
|
const isValid = await this.importDataActions.validateItem(item, importDef.attributeMappings, context);
|
696
718
|
// Log info and continue to the next item if it's invalid
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "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": "0.0.
|
4
|
+
"version": "0.0.260",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -86,6 +86,34 @@ export class DataLoader {
|
|
86
86
|
return name.toLowerCase().replace(" ", "");
|
87
87
|
}
|
88
88
|
|
89
|
+
/**
|
90
|
+
* Merges two objects by updating the source object with the target object's values.
|
91
|
+
* It iterates through the target object's keys and updates the source object if:
|
92
|
+
* - The source object has the key.
|
93
|
+
* - The target object's value for that key is not null, undefined, or an empty string.
|
94
|
+
*
|
95
|
+
* @param source - The source object to be updated.
|
96
|
+
* @param target - The target object with values to update the source object.
|
97
|
+
* @returns The updated source object.
|
98
|
+
*/
|
99
|
+
mergeObjects(
|
100
|
+
source: Record<string, any>,
|
101
|
+
target: Record<string, any>
|
102
|
+
): Record<string, any> {
|
103
|
+
Object.keys(target).forEach((key) => {
|
104
|
+
const targetValue = target[key];
|
105
|
+
if (
|
106
|
+
source.hasOwnProperty(key) &&
|
107
|
+
targetValue !== null &&
|
108
|
+
targetValue !== undefined &&
|
109
|
+
targetValue !== ""
|
110
|
+
) {
|
111
|
+
source[key] = targetValue;
|
112
|
+
}
|
113
|
+
});
|
114
|
+
return source;
|
115
|
+
}
|
116
|
+
|
89
117
|
// Method to load data from a file specified in the import definition
|
90
118
|
async loadData(importDef: ImportDef): Promise<any[]> {
|
91
119
|
// Resolve the file path and check if the file exists
|
@@ -522,16 +550,11 @@ export class DataLoader {
|
|
522
550
|
}
|
523
551
|
});
|
524
552
|
const usersMap = this.importMap.get(this.getCollectionKey("users"));
|
525
|
-
if (usersMap) {
|
526
|
-
usersMap.data.push({
|
527
|
-
rawData: item,
|
528
|
-
finalData: userData.data,
|
529
|
-
});
|
530
|
-
}
|
531
553
|
const userDataToAdd = {
|
532
554
|
rawData: item,
|
533
555
|
finalData: userData.data,
|
534
556
|
};
|
557
|
+
// Directly update the importMap with the new user data, without pushing to usersMap.data first
|
535
558
|
this.importMap.set(this.getCollectionKey("users"), {
|
536
559
|
data: [...(usersMap?.data || []), userDataToAdd],
|
537
560
|
});
|
@@ -644,7 +667,10 @@ export class DataLoader {
|
|
644
667
|
data.finalData.docId === oldId ||
|
645
668
|
data.finalData.userId === oldId
|
646
669
|
) {
|
647
|
-
|
670
|
+
transformedItem = this.mergeObjects(
|
671
|
+
data.finalData,
|
672
|
+
transformedItem
|
673
|
+
);
|
648
674
|
}
|
649
675
|
}
|
650
676
|
} else {
|
@@ -662,8 +688,10 @@ export class DataLoader {
|
|
662
688
|
currentUserData.data[i].finalData.userId === existingId) &&
|
663
689
|
!_.isEqual(currentUserData.data[i], userData)
|
664
690
|
) {
|
665
|
-
|
666
|
-
|
691
|
+
this.mergeObjects(
|
692
|
+
currentUserData.data[i].finalData,
|
693
|
+
userData.finalData
|
694
|
+
);
|
667
695
|
console.log("Merging user data", currentUserData.data[i].finalData);
|
668
696
|
this.importMap.set(this.getCollectionKey("users"), currentUserData);
|
669
697
|
}
|
@@ -686,10 +714,11 @@ export class DataLoader {
|
|
686
714
|
currentData.data[i].finalData.docId === existingId ||
|
687
715
|
currentData.data[i].finalData.userId === existingId
|
688
716
|
) {
|
689
|
-
currentData.data[i].finalData =
|
690
|
-
|
691
|
-
|
692
|
-
|
717
|
+
currentData.data[i].finalData = this.mergeObjects(
|
718
|
+
currentData.data[i].finalData,
|
719
|
+
transformedItem
|
720
|
+
);
|
721
|
+
currentData.data[i].context = context;
|
693
722
|
currentData.data[i].importDef = newImportDef;
|
694
723
|
this.importMap.set(
|
695
724
|
this.getCollectionKey(collection.name),
|
@@ -874,7 +903,7 @@ export class DataLoader {
|
|
874
903
|
}
|
875
904
|
for (const item of rawData) {
|
876
905
|
// Transform the item data based on the attribute mappings
|
877
|
-
|
906
|
+
let transformedData = await this.transformData(
|
878
907
|
item,
|
879
908
|
importDef.attributeMappings
|
880
909
|
);
|
@@ -921,9 +950,30 @@ export class DataLoader {
|
|
921
950
|
);
|
922
951
|
continue;
|
923
952
|
}
|
953
|
+
const itemDataToUpdate = this.importMap
|
954
|
+
.get(this.getCollectionKey(collection.name))
|
955
|
+
?.data.find(
|
956
|
+
(data) => data.rawData[importDef.primaryKeyField] === oldId
|
957
|
+
);
|
958
|
+
if (!itemDataToUpdate) {
|
959
|
+
logger.error(
|
960
|
+
`No data found for collection ${
|
961
|
+
collection.name
|
962
|
+
} for updateDef ${JSON.stringify(
|
963
|
+
item,
|
964
|
+
null,
|
965
|
+
2
|
966
|
+
)} but it says it's supposed to have one...`
|
967
|
+
);
|
968
|
+
continue;
|
969
|
+
}
|
970
|
+
transformedData = this.mergeObjects(
|
971
|
+
itemDataToUpdate.finalData,
|
972
|
+
transformedData
|
973
|
+
);
|
924
974
|
// Create a context object for the item, including the new ID and transformed data
|
925
975
|
let context = this.createContext(db, collection, item, newId);
|
926
|
-
context =
|
976
|
+
context = this.mergeObjects(context, transformedData);
|
927
977
|
// Validate the item before proceeding
|
928
978
|
const isValid = await this.importDataActions.validateItem(
|
929
979
|
item,
|