appwrite-utils-cli 0.0.257 → 0.0.259

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
@@ -405,8 +427,6 @@ export class DataLoader {
405
427
  const mergedUsers = this.mergedUserMap.get(existingId) || [];
406
428
  mergedUsers.push(`${item[primaryKeyField]}`);
407
429
  this.mergedUserMap.set(existingId, mergedUsers);
408
- transformedItem["userId"] = existingId;
409
- transformedItem["docId"] = existingId;
410
430
  }
411
431
  // Remove user-specific keys from the transformed item
412
432
  const userKeys = ["email", "phone", "name", "labels", "prefs"];
@@ -658,7 +678,7 @@ export class DataLoader {
658
678
  }
659
679
  for (const item of rawData) {
660
680
  // Transform the item data based on the attribute mappings
661
- const transformedData = await this.transformData(item, importDef.attributeMappings);
681
+ let transformedData = await this.transformData(item, importDef.attributeMappings);
662
682
  let newId;
663
683
  let oldId;
664
684
  // Determine the new ID for the item based on the primary key field or update mapping
@@ -690,9 +710,17 @@ export class DataLoader {
690
710
  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...`);
691
711
  continue;
692
712
  }
713
+ const itemDataToUpdate = this.importMap
714
+ .get(this.getCollectionKey(collection.name))
715
+ ?.data.find((data) => data.rawData[importDef.primaryKeyField] === oldId);
716
+ if (!itemDataToUpdate) {
717
+ 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...`);
718
+ continue;
719
+ }
720
+ transformedData = this.mergeObjects(itemDataToUpdate.finalData, transformedData);
693
721
  // Create a context object for the item, including the new ID and transformed data
694
722
  let context = this.createContext(db, collection, item, newId);
695
- context = { ...context, ...transformedData };
723
+ context = this.mergeObjects(context, transformedData);
696
724
  // Validate the item before proceeding
697
725
  const isValid = await this.importDataActions.validateItem(item, importDef.attributeMappings, context);
698
726
  // 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.257",
4
+ "version": "0.0.259",
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
@@ -512,8 +540,6 @@ export class DataLoader {
512
540
  const mergedUsers = this.mergedUserMap.get(existingId) || [];
513
541
  mergedUsers.push(`${item[primaryKeyField]}`);
514
542
  this.mergedUserMap.set(existingId, mergedUsers);
515
- transformedItem["userId"] = existingId;
516
- transformedItem["docId"] = existingId;
517
543
  }
518
544
 
519
545
  // Remove user-specific keys from the transformed item
@@ -876,7 +902,7 @@ export class DataLoader {
876
902
  }
877
903
  for (const item of rawData) {
878
904
  // Transform the item data based on the attribute mappings
879
- const transformedData = await this.transformData(
905
+ let transformedData = await this.transformData(
880
906
  item,
881
907
  importDef.attributeMappings
882
908
  );
@@ -923,9 +949,30 @@ export class DataLoader {
923
949
  );
924
950
  continue;
925
951
  }
952
+ const itemDataToUpdate = this.importMap
953
+ .get(this.getCollectionKey(collection.name))
954
+ ?.data.find(
955
+ (data) => data.rawData[importDef.primaryKeyField] === oldId
956
+ );
957
+ if (!itemDataToUpdate) {
958
+ logger.error(
959
+ `No data found for collection ${
960
+ collection.name
961
+ } for updateDef ${JSON.stringify(
962
+ item,
963
+ null,
964
+ 2
965
+ )} but it says it's supposed to have one...`
966
+ );
967
+ continue;
968
+ }
969
+ transformedData = this.mergeObjects(
970
+ itemDataToUpdate.finalData,
971
+ transformedData
972
+ );
926
973
  // Create a context object for the item, including the new ID and transformed data
927
974
  let context = this.createContext(db, collection, item, newId);
928
- context = { ...context, ...transformedData };
975
+ context = this.mergeObjects(context, transformedData);
929
976
  // Validate the item before proceeding
930
977
  const isValid = await this.importDataActions.validateItem(
931
978
  item,