appwrite-utils-cli 0.0.252 → 0.0.253

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/dist/main.js CHANGED
@@ -13,6 +13,7 @@ async function main() {
13
13
  let generateSchemas = false;
14
14
  let importData = false;
15
15
  let wipeDocuments = false;
16
+ let shouldWriteFile = false;
16
17
  if (args.includes("--prod")) {
17
18
  runProd = true;
18
19
  }
@@ -40,6 +41,9 @@ async function main() {
40
41
  if (args.includes("--wipe-users") || args.includes("--wipeUsers")) {
41
42
  wipeUsers = true;
42
43
  }
44
+ if (args.includes("--write-data") || args.includes("--writeData")) {
45
+ shouldWriteFile = true;
46
+ }
43
47
  if (args.includes("--init")) {
44
48
  await controller.run({
45
49
  runProd: runProd,
@@ -53,6 +57,7 @@ async function main() {
53
57
  generateMockData: false,
54
58
  importData: false,
55
59
  checkDuplicates: false,
60
+ shouldWriteFile: shouldWriteFile,
56
61
  });
57
62
  }
58
63
  else {
@@ -68,6 +73,7 @@ async function main() {
68
73
  wipeUsers: wipeUsers,
69
74
  importData: importData,
70
75
  checkDuplicates: false,
76
+ shouldWriteFile: shouldWriteFile,
71
77
  });
72
78
  }
73
79
  }
@@ -1559,7 +1559,8 @@ export declare class DataLoader {
1559
1559
  private emailToUserIdMap;
1560
1560
  private phoneToUserIdMap;
1561
1561
  userExistsMap: Map<string, boolean>;
1562
- constructor(appwriteFolderPath: string, importDataActions: ImportDataActions, database: Databases, config: AppwriteConfig);
1562
+ private shouldWriteFile;
1563
+ constructor(appwriteFolderPath: string, importDataActions: ImportDataActions, database: Databases, config: AppwriteConfig, shouldWriteFile?: boolean);
1563
1564
  getCollectionKey(name: string): string;
1564
1565
  loadData(importDef: ImportDef): Promise<any[]>;
1565
1566
  checkMapValuesForId(newId: string, collectionName: string): string | false;
@@ -1578,7 +1579,7 @@ export declare class DataLoader {
1578
1579
  getAllUsers(): Promise<import("node-appwrite").Models.User<import("node-appwrite").Models.Preferences>[]>;
1579
1580
  start(dbId: string): Promise<void>;
1580
1581
  updateReferencesInRelatedCollections(): Promise<void>;
1581
- updateObjectWithNonNullishValues(sourceObject: Record<string, any>, inputObject: Record<string, any>): void;
1582
+ private writeMapsToJsonFile;
1582
1583
  /**
1583
1584
  * Prepares user data by checking for duplicates based on email or phone, adding to a duplicate map if found,
1584
1585
  * and then returning the transformed item without user-specific keys.
@@ -45,13 +45,15 @@ export class DataLoader {
45
45
  emailToUserIdMap = new Map();
46
46
  phoneToUserIdMap = new Map();
47
47
  userExistsMap = new Map();
48
+ shouldWriteFile = false;
48
49
  // Constructor to initialize the DataLoader with necessary configurations
49
- constructor(appwriteFolderPath, importDataActions, database, config) {
50
+ constructor(appwriteFolderPath, importDataActions, database, config, shouldWriteFile) {
50
51
  this.appwriteFolderPath = appwriteFolderPath;
51
52
  this.importDataActions = importDataActions;
52
53
  this.database = database;
53
54
  this.usersController = new UsersController(config, database);
54
55
  this.config = config;
56
+ this.shouldWriteFile = shouldWriteFile || false;
55
57
  }
56
58
  // Helper method to generate a consistent key for collections
57
59
  getCollectionKey(name) {
@@ -156,7 +158,14 @@ export class DataLoader {
156
158
  async getAllUsers() {
157
159
  const users = new UsersController(this.config, this.database);
158
160
  const allUsers = await users.getAllUsers();
161
+ // Iterate over the users and setup our maps ahead of time for email and phone
159
162
  for (const user of allUsers) {
163
+ if (user.email) {
164
+ this.emailToUserIdMap.set(user.email, user.$id);
165
+ }
166
+ if (user.phone) {
167
+ this.phoneToUserIdMap.set(user.phone, user.$id);
168
+ }
160
169
  this.userExistsMap.set(user.$id, true);
161
170
  }
162
171
  return allUsers;
@@ -169,15 +178,6 @@ export class DataLoader {
169
178
  await this.setupMaps(dbId);
170
179
  const allUsers = await this.getAllUsers();
171
180
  console.log(`Fetched ${allUsers.length} users`);
172
- // Iterate over the users and setup our maps ahead of time for email and phone
173
- for (const user of allUsers) {
174
- if (user.email) {
175
- this.emailToUserIdMap.set(user.email, user.$id);
176
- }
177
- if (user.phone) {
178
- this.phoneToUserIdMap.set(user.phone, user.$id);
179
- }
180
- }
181
181
  // Iterate over the configured databases to find the matching one
182
182
  for (const db of this.config.databases) {
183
183
  if (db.$id !== dbId) {
@@ -222,7 +222,9 @@ export class DataLoader {
222
222
  console.log("---------------------------------");
223
223
  console.log(`Data setup for database: ${dbId} completed`);
224
224
  console.log("---------------------------------");
225
- // this.writeMapsToJsonFile();
225
+ if (this.shouldWriteFile) {
226
+ this.writeMapsToJsonFile();
227
+ }
226
228
  }
227
229
  async updateReferencesInRelatedCollections() {
228
230
  // Iterate over each collection configuration
@@ -299,24 +301,6 @@ export class DataLoader {
299
301
  }
300
302
  }
301
303
  }
302
- updateObjectWithNonNullishValues(sourceObject, inputObject) {
303
- // Iterate through the keys of the inputObject
304
- for (const key of Object.keys(inputObject)) {
305
- const inputValue = inputObject[key];
306
- const sourceValue = sourceObject[key];
307
- // Check if the inputObject's value for the current key is non-nullish
308
- // and either the key doesn't exist in the sourceObject or its value is nullish
309
- if (inputValue !== null &&
310
- inputValue !== undefined &&
311
- inputValue !== "" &&
312
- (sourceValue === null ||
313
- sourceValue === undefined ||
314
- sourceValue === "")) {
315
- // Update the sourceObject with the inputObject's value for the current key
316
- sourceObject[key] = inputValue;
317
- }
318
- }
319
- }
320
304
  // async updateReferencesInRelatedCollections() {
321
305
  // // Process each collection defined in the config
322
306
  // for (const collection of this.config.collections) {
@@ -368,43 +352,36 @@ export class DataLoader {
368
352
  // }
369
353
  // }
370
354
  // }
371
- // private writeMapsToJsonFile() {
372
- // const outputDir = path.resolve(process.cwd());
373
- // const outputFile = path.join(outputDir, "dataLoaderOutput.json");
374
- // const dataToWrite = {
375
- // dataFromCollections: Array.from(this.importMap.entries()).map(
376
- // ([key, value]) => {
377
- // return {
378
- // collection: key,
379
- // data: value.data.map((item: any) => item.finalData),
380
- // };
381
- // }
382
- // ),
383
- // // Convert Maps to arrays of entries for serialization
384
- // mergedUserMap: Array.from(this.mergedUserMap.entries()),
385
- // // emailToUserIdMap: Array.from(this.emailToUserIdMap.entries()),
386
- // // phoneToUserIdMap: Array.from(this.phoneToUserIdMap.entries()),
387
- // };
388
- // // Use JSON.stringify with a replacer function to handle Maps
389
- // const replacer = (key: any, value: any) => {
390
- // if (value instanceof Map) {
391
- // return Array.from(value.entries());
392
- // }
393
- // return value;
394
- // };
395
- // fs.writeFile(
396
- // outputFile,
397
- // JSON.stringify(dataToWrite, replacer, 2),
398
- // "utf8",
399
- // (err) => {
400
- // if (err) {
401
- // console.error("Error writing data to JSON file:", err);
402
- // return;
403
- // }
404
- // console.log(`Data successfully written to ${outputFile}`);
405
- // }
406
- // );
407
- // }
355
+ writeMapsToJsonFile() {
356
+ const outputDir = path.resolve(process.cwd());
357
+ const outputFile = path.join(outputDir, "dataLoaderOutput.json");
358
+ const dataToWrite = {
359
+ dataFromCollections: Array.from(this.importMap.entries()).map(([key, value]) => {
360
+ return {
361
+ collection: key,
362
+ data: value.data.map((item) => item.finalData),
363
+ };
364
+ }),
365
+ // Convert Maps to arrays of entries for serialization
366
+ mergedUserMap: Array.from(this.mergedUserMap.entries()),
367
+ // emailToUserIdMap: Array.from(this.emailToUserIdMap.entries()),
368
+ // phoneToUserIdMap: Array.from(this.phoneToUserIdMap.entries()),
369
+ };
370
+ // Use JSON.stringify with a replacer function to handle Maps
371
+ const replacer = (key, value) => {
372
+ if (value instanceof Map) {
373
+ return Array.from(value.entries());
374
+ }
375
+ return value;
376
+ };
377
+ fs.writeFile(outputFile, JSON.stringify(dataToWrite, replacer, 2), "utf8", (err) => {
378
+ if (err) {
379
+ console.error("Error writing data to JSON file:", err);
380
+ return;
381
+ }
382
+ console.log(`Data successfully written to ${outputFile}`);
383
+ });
384
+ }
408
385
  /**
409
386
  * Prepares user data by checking for duplicates based on email or phone, adding to a duplicate map if found,
410
387
  * and then returning the transformed item without user-specific keys.
@@ -499,6 +476,7 @@ export class DataLoader {
499
476
  this.oldIdToNewIdPerCollectionMap
500
477
  .set(this.getCollectionKey(collection.name), oldIdToNewIdMap)
501
478
  .get(this.getCollectionKey(collection.name));
479
+ console.log(`${collection.name} -- collectionOldIdToNewIdMap: ${collectionOldIdToNewIdMap}`);
502
480
  if (!operationId) {
503
481
  throw new Error(`No import operation found for collection ${collection.name}`);
504
482
  }
@@ -528,7 +506,6 @@ export class DataLoader {
528
506
  // No existing user ID, generate a new unique ID
529
507
  existingId = this.getTrueUniqueId(this.getCollectionKey("users"));
530
508
  transformedItem.userId = existingId; // Assign the new ID to the transformed data's userId field
531
- transformedItem.docId = existingId;
532
509
  }
533
510
  // Create a context object for the item, including the new ID
534
511
  let context = this.createContext(db, collection, item, existingId);
@@ -542,7 +519,12 @@ export class DataLoader {
542
519
  .get(this.getCollectionKey(collection.name))
543
520
  ?.has(`${oldId}`)) {
544
521
  // Found a duplicate oldId, now decide how to merge or handle these duplicates
545
- this.updateObjectWithNonNullishValues(currentData.data[0].finalData, transformedItem);
522
+ for (const data of currentData.data) {
523
+ if (data.finalData.docId === oldId ||
524
+ data.finalData.userId === oldId) {
525
+ Object.assign(data.finalData, transformedItem);
526
+ }
527
+ }
546
528
  }
547
529
  else {
548
530
  // No duplicate found, simply map the oldId to the new itemId
@@ -556,7 +538,8 @@ export class DataLoader {
556
538
  if ((currentUserData.data[i].finalData.docId === existingId ||
557
539
  currentUserData.data[i].finalData.userId === existingId) &&
558
540
  !_.isEqual(currentUserData.data[i], userData)) {
559
- this.updateObjectWithNonNullishValues(currentUserData.data[i].finalData, userData.finalData);
541
+ Object.assign(currentUserData.data[i].finalData, transformedItem);
542
+ Object.assign(currentUserData.data[i].rawData, item);
560
543
  console.log("Merging user data", currentUserData.data[i].finalData);
561
544
  this.importMap.set(this.getCollectionKey("users"), currentUserData);
562
545
  }
@@ -572,7 +555,10 @@ export class DataLoader {
572
555
  for (let i = 0; i < currentData.data.length; i++) {
573
556
  if (currentData.data[i].finalData.docId === existingId ||
574
557
  currentData.data[i].finalData.userId === existingId) {
575
- this.updateObjectWithNonNullishValues(currentData.data[i].finalData, transformedItem);
558
+ currentData.data[i].finalData = {
559
+ ...currentData.data[i].finalData,
560
+ ...transformedItem,
561
+ };
576
562
  currentData.data[i].importDef = newImportDef;
577
563
  this.importMap.set(this.getCollectionKey(collection.name), currentData);
578
564
  this.oldIdToNewIdPerCollectionMap.set(this.getCollectionKey(collection.name), collectionOldIdToNewIdMap);
@@ -722,9 +708,8 @@ export class DataLoader {
722
708
  }
723
709
  }
724
710
  else {
725
- const currentCollectionData = this.importMap.get(this.getCollectionKey(collection.name));
726
- const foundItem = currentCollectionData?.data.find((dataItem) => dataItem.rawData[importDef.primaryKeyField] === oldId);
727
- newId = foundItem ? oldIdToNewIdMap?.get(`${oldId}`) : undefined;
711
+ logger.error(`No old ID found (to update another document with) in prepareUpdateData for ${collection.name}, ${JSON.stringify(item, null, 2)}`);
712
+ continue;
728
713
  }
729
714
  // Log an error and continue to the next item if no new ID is found
730
715
  if (!newId) {
@@ -58,7 +58,7 @@ export class ImportController {
58
58
  console.log(`Starting import data for database: ${db.name}`);
59
59
  console.log(`---------------------------------`);
60
60
  // await this.importCollections(db);
61
- const dataLoader = new DataLoader(this.appwriteFolderPath, this.importDataActions, this.database, this.config);
61
+ const dataLoader = new DataLoader(this.appwriteFolderPath, this.importDataActions, this.database, this.config, this.setupOptions.shouldWriteFile);
62
62
  await dataLoader.start(db.$id);
63
63
  await this.importCollections(db, dataLoader);
64
64
  await resolveAndUpdateRelationships(db.$id, this.database, this.config);
@@ -13,6 +13,7 @@ export interface SetupOptions {
13
13
  generateMockData: boolean;
14
14
  importData: boolean;
15
15
  checkDuplicates: boolean;
16
+ shouldWriteFile: boolean;
16
17
  }
17
18
  export declare class UtilsController {
18
19
  private appwriteFolderPath;
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.252",
4
+ "version": "0.0.253",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
package/src/main.ts CHANGED
@@ -16,6 +16,7 @@ async function main() {
16
16
  let generateSchemas = false;
17
17
  let importData = false;
18
18
  let wipeDocuments = false;
19
+ let shouldWriteFile = false;
19
20
  if (args.includes("--prod")) {
20
21
  runProd = true;
21
22
  }
@@ -43,6 +44,9 @@ async function main() {
43
44
  if (args.includes("--wipe-users") || args.includes("--wipeUsers")) {
44
45
  wipeUsers = true;
45
46
  }
47
+ if (args.includes("--write-data") || args.includes("--writeData")) {
48
+ shouldWriteFile = true;
49
+ }
46
50
  if (args.includes("--init")) {
47
51
  await controller.run({
48
52
  runProd: runProd,
@@ -56,6 +60,7 @@ async function main() {
56
60
  generateMockData: false,
57
61
  importData: false,
58
62
  checkDuplicates: false,
63
+ shouldWriteFile: shouldWriteFile,
59
64
  });
60
65
  } else {
61
66
  await controller.run({
@@ -70,6 +75,7 @@ async function main() {
70
75
  wipeUsers: wipeUsers,
71
76
  importData: importData,
72
77
  checkDuplicates: false,
78
+ shouldWriteFile: shouldWriteFile,
73
79
  });
74
80
  }
75
81
  }
@@ -63,19 +63,22 @@ export class DataLoader {
63
63
  private emailToUserIdMap = new Map<string, string>();
64
64
  private phoneToUserIdMap = new Map<string, string>();
65
65
  userExistsMap = new Map<string, boolean>();
66
+ private shouldWriteFile = false;
66
67
 
67
68
  // Constructor to initialize the DataLoader with necessary configurations
68
69
  constructor(
69
70
  appwriteFolderPath: string,
70
71
  importDataActions: ImportDataActions,
71
72
  database: Databases,
72
- config: AppwriteConfig
73
+ config: AppwriteConfig,
74
+ shouldWriteFile?: boolean
73
75
  ) {
74
76
  this.appwriteFolderPath = appwriteFolderPath;
75
77
  this.importDataActions = importDataActions;
76
78
  this.database = database;
77
79
  this.usersController = new UsersController(config, database);
78
80
  this.config = config;
81
+ this.shouldWriteFile = shouldWriteFile || false;
79
82
  }
80
83
 
81
84
  // Helper method to generate a consistent key for collections
@@ -213,7 +216,14 @@ export class DataLoader {
213
216
  async getAllUsers() {
214
217
  const users = new UsersController(this.config, this.database);
215
218
  const allUsers = await users.getAllUsers();
219
+ // Iterate over the users and setup our maps ahead of time for email and phone
216
220
  for (const user of allUsers) {
221
+ if (user.email) {
222
+ this.emailToUserIdMap.set(user.email, user.$id);
223
+ }
224
+ if (user.phone) {
225
+ this.phoneToUserIdMap.set(user.phone, user.$id);
226
+ }
217
227
  this.userExistsMap.set(user.$id, true);
218
228
  }
219
229
  return allUsers;
@@ -227,15 +237,6 @@ export class DataLoader {
227
237
  await this.setupMaps(dbId);
228
238
  const allUsers = await this.getAllUsers();
229
239
  console.log(`Fetched ${allUsers.length} users`);
230
- // Iterate over the users and setup our maps ahead of time for email and phone
231
- for (const user of allUsers) {
232
- if (user.email) {
233
- this.emailToUserIdMap.set(user.email, user.$id);
234
- }
235
- if (user.phone) {
236
- this.phoneToUserIdMap.set(user.phone, user.$id);
237
- }
238
- }
239
240
  // Iterate over the configured databases to find the matching one
240
241
  for (const db of this.config.databases) {
241
242
  if (db.$id !== dbId) {
@@ -290,7 +291,9 @@ export class DataLoader {
290
291
  console.log("---------------------------------");
291
292
  console.log(`Data setup for database: ${dbId} completed`);
292
293
  console.log("---------------------------------");
293
- // this.writeMapsToJsonFile();
294
+ if (this.shouldWriteFile) {
295
+ this.writeMapsToJsonFile();
296
+ }
294
297
  }
295
298
 
296
299
  async updateReferencesInRelatedCollections() {
@@ -389,31 +392,6 @@ export class DataLoader {
389
392
  }
390
393
  }
391
394
 
392
- updateObjectWithNonNullishValues(
393
- sourceObject: Record<string, any>,
394
- inputObject: Record<string, any>
395
- ): void {
396
- // Iterate through the keys of the inputObject
397
- for (const key of Object.keys(inputObject)) {
398
- const inputValue = inputObject[key];
399
- const sourceValue = sourceObject[key];
400
-
401
- // Check if the inputObject's value for the current key is non-nullish
402
- // and either the key doesn't exist in the sourceObject or its value is nullish
403
- if (
404
- inputValue !== null &&
405
- inputValue !== undefined &&
406
- inputValue !== "" &&
407
- (sourceValue === null ||
408
- sourceValue === undefined ||
409
- sourceValue === "")
410
- ) {
411
- // Update the sourceObject with the inputObject's value for the current key
412
- sourceObject[key] = inputValue;
413
- }
414
- }
415
- }
416
-
417
395
  // async updateReferencesInRelatedCollections() {
418
396
  // // Process each collection defined in the config
419
397
  // for (const collection of this.config.collections) {
@@ -471,46 +449,46 @@ export class DataLoader {
471
449
  // }
472
450
  // }
473
451
 
474
- // private writeMapsToJsonFile() {
475
- // const outputDir = path.resolve(process.cwd());
476
- // const outputFile = path.join(outputDir, "dataLoaderOutput.json");
452
+ private writeMapsToJsonFile() {
453
+ const outputDir = path.resolve(process.cwd());
454
+ const outputFile = path.join(outputDir, "dataLoaderOutput.json");
477
455
 
478
- // const dataToWrite = {
479
- // dataFromCollections: Array.from(this.importMap.entries()).map(
480
- // ([key, value]) => {
481
- // return {
482
- // collection: key,
483
- // data: value.data.map((item: any) => item.finalData),
484
- // };
485
- // }
486
- // ),
487
- // // Convert Maps to arrays of entries for serialization
488
- // mergedUserMap: Array.from(this.mergedUserMap.entries()),
489
- // // emailToUserIdMap: Array.from(this.emailToUserIdMap.entries()),
490
- // // phoneToUserIdMap: Array.from(this.phoneToUserIdMap.entries()),
491
- // };
456
+ const dataToWrite = {
457
+ dataFromCollections: Array.from(this.importMap.entries()).map(
458
+ ([key, value]) => {
459
+ return {
460
+ collection: key,
461
+ data: value.data.map((item: any) => item.finalData),
462
+ };
463
+ }
464
+ ),
465
+ // Convert Maps to arrays of entries for serialization
466
+ mergedUserMap: Array.from(this.mergedUserMap.entries()),
467
+ // emailToUserIdMap: Array.from(this.emailToUserIdMap.entries()),
468
+ // phoneToUserIdMap: Array.from(this.phoneToUserIdMap.entries()),
469
+ };
492
470
 
493
- // // Use JSON.stringify with a replacer function to handle Maps
494
- // const replacer = (key: any, value: any) => {
495
- // if (value instanceof Map) {
496
- // return Array.from(value.entries());
497
- // }
498
- // return value;
499
- // };
471
+ // Use JSON.stringify with a replacer function to handle Maps
472
+ const replacer = (key: any, value: any) => {
473
+ if (value instanceof Map) {
474
+ return Array.from(value.entries());
475
+ }
476
+ return value;
477
+ };
500
478
 
501
- // fs.writeFile(
502
- // outputFile,
503
- // JSON.stringify(dataToWrite, replacer, 2),
504
- // "utf8",
505
- // (err) => {
506
- // if (err) {
507
- // console.error("Error writing data to JSON file:", err);
508
- // return;
509
- // }
510
- // console.log(`Data successfully written to ${outputFile}`);
511
- // }
512
- // );
513
- // }
479
+ fs.writeFile(
480
+ outputFile,
481
+ JSON.stringify(dataToWrite, replacer, 2),
482
+ "utf8",
483
+ (err) => {
484
+ if (err) {
485
+ console.error("Error writing data to JSON file:", err);
486
+ return;
487
+ }
488
+ console.log(`Data successfully written to ${outputFile}`);
489
+ }
490
+ );
491
+ }
514
492
 
515
493
  /**
516
494
  * Prepares user data by checking for duplicates based on email or phone, adding to a duplicate map if found,
@@ -630,6 +608,9 @@ export class DataLoader {
630
608
  this.oldIdToNewIdPerCollectionMap
631
609
  .set(this.getCollectionKey(collection.name), oldIdToNewIdMap)
632
610
  .get(this.getCollectionKey(collection.name));
611
+ console.log(
612
+ `${collection.name} -- collectionOldIdToNewIdMap: ${collectionOldIdToNewIdMap}`
613
+ );
633
614
  if (!operationId) {
634
615
  throw new Error(
635
616
  `No import operation found for collection ${collection.name}`
@@ -679,7 +660,6 @@ export class DataLoader {
679
660
  // No existing user ID, generate a new unique ID
680
661
  existingId = this.getTrueUniqueId(this.getCollectionKey("users"));
681
662
  transformedItem.userId = existingId; // Assign the new ID to the transformed data's userId field
682
- transformedItem.docId = existingId;
683
663
  }
684
664
 
685
665
  // Create a context object for the item, including the new ID
@@ -699,10 +679,14 @@ export class DataLoader {
699
679
  ?.has(`${oldId}`)
700
680
  ) {
701
681
  // Found a duplicate oldId, now decide how to merge or handle these duplicates
702
- this.updateObjectWithNonNullishValues(
703
- currentData.data[0].finalData,
704
- transformedItem
705
- );
682
+ for (const data of currentData.data) {
683
+ if (
684
+ data.finalData.docId === oldId ||
685
+ data.finalData.userId === oldId
686
+ ) {
687
+ Object.assign(data.finalData, transformedItem);
688
+ }
689
+ }
706
690
  } else {
707
691
  // No duplicate found, simply map the oldId to the new itemId
708
692
  collectionOldIdToNewIdMap?.set(`${oldId}`, `${existingId}`);
@@ -718,10 +702,8 @@ export class DataLoader {
718
702
  currentUserData.data[i].finalData.userId === existingId) &&
719
703
  !_.isEqual(currentUserData.data[i], userData)
720
704
  ) {
721
- this.updateObjectWithNonNullishValues(
722
- currentUserData.data[i].finalData,
723
- userData.finalData
724
- );
705
+ Object.assign(currentUserData.data[i].finalData, transformedItem);
706
+ Object.assign(currentUserData.data[i].rawData, item);
725
707
  console.log("Merging user data", currentUserData.data[i].finalData);
726
708
  this.importMap.set(this.getCollectionKey("users"), currentUserData);
727
709
  }
@@ -744,10 +726,10 @@ export class DataLoader {
744
726
  currentData.data[i].finalData.docId === existingId ||
745
727
  currentData.data[i].finalData.userId === existingId
746
728
  ) {
747
- this.updateObjectWithNonNullishValues(
748
- currentData.data[i].finalData,
749
- transformedItem
750
- );
729
+ currentData.data[i].finalData = {
730
+ ...currentData.data[i].finalData,
731
+ ...transformedItem,
732
+ };
751
733
  currentData.data[i].importDef = newImportDef;
752
734
  this.importMap.set(
753
735
  this.getCollectionKey(collection.name),
@@ -962,13 +944,12 @@ export class DataLoader {
962
944
  }
963
945
  }
964
946
  } else {
965
- const currentCollectionData = this.importMap.get(
966
- this.getCollectionKey(collection.name)
967
- );
968
- const foundItem = currentCollectionData?.data.find(
969
- (dataItem) => dataItem.rawData[importDef.primaryKeyField] === oldId
947
+ logger.error(
948
+ `No old ID found (to update another document with) in prepareUpdateData for ${
949
+ collection.name
950
+ }, ${JSON.stringify(item, null, 2)}`
970
951
  );
971
- newId = foundItem ? oldIdToNewIdMap?.get(`${oldId}`) : undefined;
952
+ continue;
972
953
  }
973
954
  // Log an error and continue to the next item if no new ID is found
974
955
  if (!newId) {
@@ -107,7 +107,8 @@ export class ImportController {
107
107
  this.appwriteFolderPath,
108
108
  this.importDataActions,
109
109
  this.database,
110
- this.config
110
+ this.config,
111
+ this.setupOptions.shouldWriteFile
111
112
  );
112
113
  await dataLoader.start(db.$id);
113
114
  await this.importCollections(db, dataLoader);
@@ -46,6 +46,7 @@ export interface SetupOptions {
46
46
  generateMockData: boolean;
47
47
  importData: boolean;
48
48
  checkDuplicates: boolean;
49
+ shouldWriteFile: boolean;
49
50
  }
50
51
 
51
52
  type CollectionConfig = AppwriteConfig["collections"];