appwrite-utils-cli 0.0.52 → 0.0.54

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.md CHANGED
@@ -132,6 +132,7 @@ This setup ensures that developers have robust tools at their fingertips to mana
132
132
 
133
133
  ### Changelog
134
134
 
135
+ - 0.0.54: Various fixes in here
135
136
  - 0.0.50: Actually fixed the slight bug, it was really in the `mergeObjects`
136
137
  - 0.0.49: Fixed a slight bug with `dataLoader` not mapping updates correctly with `updateMapping`
137
138
  - 0.0.48: Added `--transfer`, `--fromdb <targetDatabaseId>`, `--targetdb <targetDatabaseId>`, `--transferendpoint <transferEndpoint>`, `--transferproject <transferProjectId>`, `--transferkey <transferApiKey>`. Additionally, I've added `--fromcoll <collectionId>` and `--targetcoll <collectionId>`. These allow you to do a few things. First, you can now transfer databases in the same project, and from local to a remote project. Second, you can now specify specific collections to transfer from one place to another, with all of their data. If `--fromcoll` and `--targetcoll` are ommitted, it will transfer the databases. During the database transfer, it will create any missing collections, attributes, and indices.
@@ -295,6 +295,7 @@ export declare const getMigrationCollectionSchemas: () => {
295
295
  targetKey: string;
296
296
  oldKey?: string | undefined;
297
297
  oldKeys?: string[] | undefined;
298
+ valueToSet?: any;
298
299
  fileData?: {
299
300
  path: string;
300
301
  name: string;
@@ -548,6 +549,7 @@ export declare const getMigrationCollectionSchemas: () => {
548
549
  targetKey: string;
549
550
  oldKey?: string | undefined;
550
551
  oldKeys?: string[] | undefined;
552
+ valueToSet?: any;
551
553
  fileData?: {
552
554
  path: string;
553
555
  name: string;
@@ -88,7 +88,7 @@ export const fetchAndCacheCollectionByName = async (db, dbId, collectionName) =>
88
88
  };
89
89
  export const wipeDatabase = async (database, databaseId) => {
90
90
  console.log(`Wiping database: ${databaseId}`);
91
- const { collections: existingCollections } = await tryAwaitWithRetry(async () => await database.listCollections(databaseId));
91
+ const existingCollections = await fetchAllCollections(databaseId, database);
92
92
  let collectionsDeleted = [];
93
93
  for (const { $id: collectionId, name: name } of existingCollections) {
94
94
  console.log(`Deleting collection: ${collectionId}`);
@@ -32,6 +32,7 @@ export declare const convertObjectByAttributeMappings: (obj: Record<string, any>
32
32
  targetKey: string;
33
33
  oldKey?: string | undefined;
34
34
  oldKeys?: string[] | undefined;
35
+ valueToSet?: any;
35
36
  fileData?: {
36
37
  path: string;
37
38
  name: string;
@@ -89,7 +89,10 @@ export const convertObjectByAttributeMappings = (obj, attributeMappings) => {
89
89
  return current;
90
90
  };
91
91
  for (const mapping of attributeMappings) {
92
- if (Array.isArray(mapping.oldKeys)) {
92
+ if (mapping.valueToSet !== undefined) {
93
+ result[mapping.targetKey] = mapping.valueToSet;
94
+ }
95
+ else if (Array.isArray(mapping.oldKeys)) {
93
96
  // Collect and flatten values from multiple oldKeys
94
97
  const values = mapping.oldKeys
95
98
  .map((oldKey) => resolveValue(obj, oldKey))
@@ -192,14 +192,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
192
192
  type: z.ZodLiteral<"ip">;
193
193
  error: z.ZodOptional<z.ZodDefault<z.ZodString>>;
194
194
  required: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
195
- array: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>; /**
196
- * Prepares the data for creating documents in a collection.
197
- * This involves loading the data, transforming it, and handling ID mappings.
198
- *
199
- * @param db - The database configuration.
200
- * @param collection - The collection configuration.
201
- * @param importDef - The import definition containing the attribute mappings and other relevant info.
202
- */
195
+ array: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
203
196
  xdefault: z.ZodOptional<z.ZodNullable<z.ZodString>>;
204
197
  description: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
205
198
  }, "strip", z.ZodTypeAny, {
@@ -401,6 +394,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
401
394
  oldKey: z.ZodOptional<z.ZodString>;
402
395
  oldKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
403
396
  targetKey: z.ZodString;
397
+ valueToSet: z.ZodOptional<z.ZodAny>;
404
398
  fileData: z.ZodOptional<z.ZodObject<{
405
399
  name: z.ZodString;
406
400
  path: z.ZodString;
@@ -436,6 +430,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
436
430
  targetKey: string;
437
431
  oldKey?: string | undefined;
438
432
  oldKeys?: string[] | undefined;
433
+ valueToSet?: any;
439
434
  fileData?: {
440
435
  path: string;
441
436
  name: string;
@@ -453,6 +448,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
453
448
  targetKey: string;
454
449
  oldKey?: string | undefined;
455
450
  oldKeys?: string[] | undefined;
451
+ valueToSet?: any;
456
452
  fileData?: {
457
453
  path: string;
458
454
  name: string;
@@ -474,6 +470,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
474
470
  targetKey: string;
475
471
  oldKey?: string | undefined;
476
472
  oldKeys?: string[] | undefined;
473
+ valueToSet?: any;
477
474
  fileData?: {
478
475
  path: string;
479
476
  name: string;
@@ -507,6 +504,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
507
504
  targetKey: string;
508
505
  oldKey?: string | undefined;
509
506
  oldKeys?: string[] | undefined;
507
+ valueToSet?: any;
510
508
  fileData?: {
511
509
  path: string;
512
510
  name: string;
@@ -657,6 +655,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
657
655
  targetKey: string;
658
656
  oldKey?: string | undefined;
659
657
  oldKeys?: string[] | undefined;
658
+ valueToSet?: any;
660
659
  fileData?: {
661
660
  path: string;
662
661
  name: string;
@@ -811,6 +810,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
811
810
  targetKey: string;
812
811
  oldKey?: string | undefined;
813
812
  oldKeys?: string[] | undefined;
813
+ valueToSet?: any;
814
814
  fileData?: {
815
815
  path: string;
816
816
  name: string;
@@ -884,6 +884,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
884
884
  oldKey: z.ZodOptional<z.ZodString>;
885
885
  oldKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
886
886
  targetKey: z.ZodString;
887
+ valueToSet: z.ZodOptional<z.ZodAny>;
887
888
  fileData: z.ZodOptional<z.ZodObject<{
888
889
  name: z.ZodString;
889
890
  path: z.ZodString;
@@ -919,6 +920,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
919
920
  targetKey: string;
920
921
  oldKey?: string | undefined;
921
922
  oldKeys?: string[] | undefined;
923
+ valueToSet?: any;
922
924
  fileData?: {
923
925
  path: string;
924
926
  name: string;
@@ -936,6 +938,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
936
938
  targetKey: string;
937
939
  oldKey?: string | undefined;
938
940
  oldKeys?: string[] | undefined;
941
+ valueToSet?: any;
939
942
  fileData?: {
940
943
  path: string;
941
944
  name: string;
@@ -957,6 +960,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
957
960
  targetKey: string;
958
961
  oldKey?: string | undefined;
959
962
  oldKeys?: string[] | undefined;
963
+ valueToSet?: any;
960
964
  fileData?: {
961
965
  path: string;
962
966
  name: string;
@@ -990,6 +994,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
990
994
  targetKey: string;
991
995
  oldKey?: string | undefined;
992
996
  oldKeys?: string[] | undefined;
997
+ valueToSet?: any;
993
998
  fileData?: {
994
999
  path: string;
995
1000
  name: string;
@@ -1030,6 +1035,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
1030
1035
  targetKey: string;
1031
1036
  oldKey?: string | undefined;
1032
1037
  oldKeys?: string[] | undefined;
1038
+ valueToSet?: any;
1033
1039
  fileData?: {
1034
1040
  path: string;
1035
1041
  name: string;
@@ -1068,6 +1074,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
1068
1074
  targetKey: string;
1069
1075
  oldKey?: string | undefined;
1070
1076
  oldKeys?: string[] | undefined;
1077
+ valueToSet?: any;
1071
1078
  fileData?: {
1072
1079
  path: string;
1073
1080
  name: string;
@@ -1110,6 +1117,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
1110
1117
  targetKey: string;
1111
1118
  oldKey?: string | undefined;
1112
1119
  oldKeys?: string[] | undefined;
1120
+ valueToSet?: any;
1113
1121
  fileData?: {
1114
1122
  path: string;
1115
1123
  name: string;
@@ -1259,6 +1267,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
1259
1267
  targetKey: string;
1260
1268
  oldKey?: string | undefined;
1261
1269
  oldKeys?: string[] | undefined;
1270
+ valueToSet?: any;
1262
1271
  fileData?: {
1263
1272
  path: string;
1264
1273
  name: string;
@@ -1303,6 +1312,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
1303
1312
  targetKey: string;
1304
1313
  oldKey?: string | undefined;
1305
1314
  oldKeys?: string[] | undefined;
1315
+ valueToSet?: any;
1306
1316
  fileData?: {
1307
1317
  path: string;
1308
1318
  name: string;
@@ -1455,6 +1465,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
1455
1465
  targetKey: string;
1456
1466
  oldKey?: string | undefined;
1457
1467
  oldKeys?: string[] | undefined;
1468
+ valueToSet?: any;
1458
1469
  fileData?: {
1459
1470
  path: string;
1460
1471
  name: string;
@@ -1506,6 +1517,7 @@ export declare class DataLoader {
1506
1517
  targetKey: string;
1507
1518
  oldKey?: string | undefined;
1508
1519
  oldKeys?: string[] | undefined;
1520
+ valueToSet?: any;
1509
1521
  fileData?: {
1510
1522
  path: string;
1511
1523
  name: string;
@@ -1655,6 +1667,7 @@ export declare class DataLoader {
1655
1667
  targetKey: string;
1656
1668
  oldKey?: string | undefined;
1657
1669
  oldKeys?: string[] | undefined;
1670
+ valueToSet?: any;
1658
1671
  fileData?: {
1659
1672
  path: string;
1660
1673
  name: string;
@@ -1726,7 +1739,15 @@ export declare class DataLoader {
1726
1739
  setupMaps(dbId: string): Promise<void>;
1727
1740
  getAllUsers(): Promise<import("node-appwrite").Models.User<import("node-appwrite").Models.Preferences>[]>;
1728
1741
  start(dbId: string): Promise<void>;
1729
- dealWithMergedUsers(): void;
1742
+ /**
1743
+ * Deals with merged users by iterating through all collections in the configuration.
1744
+ * We have merged users if there are duplicate emails or phones in the import data.
1745
+ * This function will iterate through all collections that are the same name as the
1746
+ * users collection and pull out their primaryKeyField's. It will then loop through
1747
+ * each collection and find any documents that have a
1748
+ *
1749
+ * @return {void} This function does not return anything.
1750
+ */
1730
1751
  updateOldReferencesForNew(): void;
1731
1752
  private writeMapsToJsonFile;
1732
1753
  /**
@@ -1791,6 +1812,7 @@ export declare class DataLoader {
1791
1812
  targetKey: string;
1792
1813
  oldKey?: string | undefined;
1793
1814
  oldKeys?: string[] | undefined;
1815
+ valueToSet?: any;
1794
1816
  fileData?: {
1795
1817
  path: string;
1796
1818
  name: string;
@@ -1812,6 +1834,7 @@ export declare class DataLoader {
1812
1834
  targetKey: string;
1813
1835
  oldKey?: string | undefined;
1814
1836
  oldKeys?: string[] | undefined;
1837
+ valueToSet?: any;
1815
1838
  fileData?: {
1816
1839
  path: string;
1817
1840
  name: string;
@@ -348,83 +348,54 @@ export class DataLoader {
348
348
  this.writeMapsToJsonFile();
349
349
  }
350
350
  }
351
- dealWithMergedUsers() {
352
- const usersCollectionKey = this.getCollectionKey(this.config.usersCollectionName);
353
- const usersCollectionPrimaryKeyFields = new Set();
354
- if (!this.config.collections) {
355
- console.log("No collections found in configuration.");
356
- return;
357
- }
358
- let needsUpdate = false;
359
- let numUpdates = 0;
360
- // Collect primary key fields from the users collection definitions
361
- this.config.collections.forEach((collection) => {
362
- if (this.getCollectionKey(collection.name) === usersCollectionKey) {
363
- const collectionImportDefs = collection.importDefs;
364
- if (!collectionImportDefs || !collectionImportDefs.length) {
365
- return;
366
- }
367
- collectionImportDefs.forEach((importDef) => {
368
- if (importDef.primaryKeyField) {
369
- usersCollectionPrimaryKeyFields.add(importDef.primaryKeyField);
370
- }
371
- });
372
- }
373
- });
374
- console.log(`Primary key fields collected for users collection: ${[
375
- ...usersCollectionPrimaryKeyFields,
376
- ]}`);
377
- // Iterate over all collections to update references based on merged users
378
- this.config.collections.forEach((collection) => {
379
- const collectionData = this.importMap.get(this.getCollectionKey(collection.name));
380
- if (!collectionData || !collectionData.data) {
381
- console.log(`No data found for collection ${collection.name}`);
382
- return;
383
- }
384
- const collectionImportDefs = collection.importDefs;
385
- if (!collectionImportDefs || !collectionImportDefs.length) {
386
- console.log(`No import definitions found for collection ${collection.name}`);
387
- return;
388
- }
389
- collectionImportDefs.forEach((importDef) => {
390
- importDef.idMappings?.forEach((idMapping) => {
391
- if (this.getCollectionKey(idMapping.targetCollection) ===
392
- usersCollectionKey) {
393
- const fieldToSetKey = idMapping.fieldToSet || idMapping.sourceField;
394
- const targetFieldKey = idMapping.targetFieldToMatch || idMapping.targetField;
395
- if (usersCollectionPrimaryKeyFields.has(targetFieldKey)) {
396
- console.log(`Processing collection ${collection.name} with target field ${targetFieldKey}`);
397
- // Process each item in the collection
398
- collectionData.data.forEach((item) => {
399
- const oldId = item.finalData[idMapping.sourceField] ||
400
- item.context[idMapping.sourceField];
401
- if (oldId === undefined || oldId === null) {
402
- console.log(`Skipping item with undefined or null oldId in collection ${collection.name}`);
403
- return;
404
- }
405
- const newId = this.mergedUserMap.get(`${oldId}`);
406
- if (newId) {
407
- needsUpdate = true;
408
- numUpdates++;
409
- console.log(`Updating old ID ${oldId} to new ID ${newId} in collection ${collection.name}`);
410
- // Update context to use new user ID
411
- item.finalData[fieldToSetKey] = newId;
412
- item.context[fieldToSetKey] = newId;
413
- }
414
- else {
415
- console.log(`No new ID found for old ID ${oldId} in mergedUserMap.`);
416
- }
417
- });
418
- }
419
- }
420
- });
421
- });
422
- if (needsUpdate) {
423
- console.log(`Updated ${numUpdates} references for collection ${collection.name}`);
424
- this.importMap.set(this.getCollectionKey(collection.name), collectionData);
425
- }
426
- });
427
- }
351
+ /**
352
+ * Deals with merged users by iterating through all collections in the configuration.
353
+ * We have merged users if there are duplicate emails or phones in the import data.
354
+ * This function will iterate through all collections that are the same name as the
355
+ * users collection and pull out their primaryKeyField's. It will then loop through
356
+ * each collection and find any documents that have a
357
+ *
358
+ * @return {void} This function does not return anything.
359
+ */
360
+ // dealWithMergedUsers() {
361
+ // const usersCollectionKey = this.getCollectionKey(
362
+ // this.config.usersCollectionName
363
+ // );
364
+ // const usersCollectionData = this.importMap.get(usersCollectionKey);
365
+ // if (!this.config.collections) {
366
+ // console.log("No collections found in configuration.");
367
+ // return;
368
+ // }
369
+ // let needsUpdate = false;
370
+ // let numUpdates = 0;
371
+ // for (const collectionConfig of this.config.collections) {
372
+ // const collectionKey = this.getCollectionKey(collectionConfig.name);
373
+ // const collectionData = this.importMap.get(collectionKey);
374
+ // const collectionImportDefs = collectionConfig.importDefs;
375
+ // const collectionIdMappings = collectionImportDefs
376
+ // .map((importDef) => importDef.idMappings)
377
+ // .flat()
378
+ // .filter((idMapping) => idMapping !== undefined && idMapping !== null);
379
+ // if (!collectionData || !collectionData.data) continue;
380
+ // for (const dataItem of collectionData.data) {
381
+ // for (const idMapping of collectionIdMappings) {
382
+ // // We know it's the users collection here
383
+ // if (this.getCollectionKey(idMapping.targetCollection) === usersCollectionKey) {
384
+ // const targetFieldKey = idMapping.targetFieldToMatch || idMapping.targetField;
385
+ // if (targetFieldKey === )
386
+ // const targetValue = dataItem.finalData[targetFieldKey];
387
+ // const targetCollectionData = this.importMap.get(this.getCollectionKey(idMapping.targetCollection));
388
+ // if (!targetCollectionData || !targetCollectionData.data) continue;
389
+ // const foundData = targetCollectionData.data.filter(({ context }) => {
390
+ // const targetValue = context[targetFieldKey];
391
+ // const isMatch = `${targetValue}` === `${valueToMatch}`;
392
+ // return isMatch && targetValue !== undefined && targetValue !== null;
393
+ // });
394
+ // }
395
+ // }
396
+ // }
397
+ // }
398
+ // }
428
399
  updateOldReferencesForNew() {
429
400
  if (!this.config.collections) {
430
401
  return;
@@ -491,7 +462,12 @@ export class DataLoader {
491
462
  else {
492
463
  // Merge arrays if new data is non-empty array and filter for uniqueness
493
464
  collectionData.data[i].finalData[fieldToSetKey] = [
494
- ...new Set([...currentDataFiltered, ...newData].filter((value) => `${value}` !== `${valueToMatch}`)),
465
+ ...new Set([
466
+ ...(Array.isArray(currentDataFiltered)
467
+ ? currentDataFiltered
468
+ : [currentDataFiltered]),
469
+ ...newData,
470
+ ].filter((value) => `${value}` !== `${valueToMatch}`)),
495
471
  ];
496
472
  }
497
473
  }
@@ -19,6 +19,7 @@ export declare const ContextObject: z.ZodObject<{
19
19
  oldKey: z.ZodOptional<z.ZodString>;
20
20
  oldKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
21
  targetKey: z.ZodString;
22
+ valueToSet: z.ZodOptional<z.ZodAny>;
22
23
  fileData: z.ZodOptional<z.ZodObject<{
23
24
  name: z.ZodString;
24
25
  path: z.ZodString;
@@ -54,6 +55,7 @@ export declare const ContextObject: z.ZodObject<{
54
55
  targetKey: string;
55
56
  oldKey?: string | undefined;
56
57
  oldKeys?: string[] | undefined;
58
+ valueToSet?: any;
57
59
  fileData?: {
58
60
  path: string;
59
61
  name: string;
@@ -71,6 +73,7 @@ export declare const ContextObject: z.ZodObject<{
71
73
  targetKey: string;
72
74
  oldKey?: string | undefined;
73
75
  oldKeys?: string[] | undefined;
76
+ valueToSet?: any;
74
77
  fileData?: {
75
78
  path: string;
76
79
  name: string;
@@ -93,6 +96,7 @@ export declare const ContextObject: z.ZodObject<{
93
96
  targetKey: string;
94
97
  oldKey?: string | undefined;
95
98
  oldKeys?: string[] | undefined;
99
+ valueToSet?: any;
96
100
  fileData?: {
97
101
  path: string;
98
102
  name: string;
@@ -116,6 +120,7 @@ export declare const ContextObject: z.ZodObject<{
116
120
  targetKey: string;
117
121
  oldKey?: string | undefined;
118
122
  oldKeys?: string[] | undefined;
123
+ valueToSet?: any;
119
124
  fileData?: {
120
125
  path: string;
121
126
  name: string;
@@ -136,6 +136,9 @@ export const startSetup = async (database, storage, config, setupOptions, appwri
136
136
  await backupDatabase(database, db.$id, storage);
137
137
  }
138
138
  deletedCollections = await wipeDatabase(database, db.$id);
139
+ // Add a delay to ensure the deletion process completes
140
+ await new Promise((resolve) => setTimeout(resolve, 5000));
141
+ console.log(`Waited a few seconds to let the database wipe complete...`);
139
142
  }
140
143
  if (processDatabase) {
141
144
  await createOrUpdateCollections(database, db.$id, config, deletedCollections);
@@ -105,6 +105,7 @@ export const tryAwaitWithRetry = async (createFunction, attemptNum = 0, throwErr
105
105
  if (throwError) {
106
106
  throw error;
107
107
  }
108
+ console.error("Error during retryAwait function: " + error);
108
109
  // @ts-ignore
109
110
  return Promise.resolve();
110
111
  }
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.52",
4
+ "version": "0.0.54",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@types/inquirer": "^9.0.7",
36
- "appwrite-utils": "^0.2.7",
36
+ "appwrite-utils": "^0.2.8",
37
37
  "commander": "^12.0.0",
38
38
  "inquirer": "^9.2.20",
39
39
  "js-yaml": "^4.1.0",
@@ -129,9 +129,7 @@ export const wipeDatabase = async (
129
129
  databaseId: string
130
130
  ): Promise<{ collectionId: string; collectionName: string }[]> => {
131
131
  console.log(`Wiping database: ${databaseId}`);
132
- const { collections: existingCollections } = await tryAwaitWithRetry(
133
- async () => await database.listCollections(databaseId)
134
- );
132
+ const existingCollections = await fetchAllCollections(databaseId, database);
135
133
  let collectionsDeleted: { collectionId: string; collectionName: string }[] =
136
134
  [];
137
135
  for (const { $id: collectionId, name: name } of existingCollections) {
@@ -103,7 +103,9 @@ export const convertObjectByAttributeMappings = (
103
103
  };
104
104
 
105
105
  for (const mapping of attributeMappings) {
106
- if (Array.isArray(mapping.oldKeys)) {
106
+ if (mapping.valueToSet !== undefined) {
107
+ result[mapping.targetKey] = mapping.valueToSet;
108
+ } else if (Array.isArray(mapping.oldKeys)) {
107
109
  // Collect and flatten values from multiple oldKeys
108
110
  const values = mapping.oldKeys
109
111
  .map((oldKey) => resolveValue(obj, oldKey))
@@ -428,122 +428,57 @@ export class DataLoader {
428
428
  }
429
429
  }
430
430
 
431
- dealWithMergedUsers() {
432
- const usersCollectionKey = this.getCollectionKey(
433
- this.config.usersCollectionName
434
- );
435
- const usersCollectionPrimaryKeyFields = new Set();
436
-
437
- if (!this.config.collections) {
438
- console.log("No collections found in configuration.");
439
- return;
440
- }
441
-
442
- let needsUpdate = false;
443
- let numUpdates = 0;
444
-
445
- // Collect primary key fields from the users collection definitions
446
- this.config.collections.forEach((collection) => {
447
- if (this.getCollectionKey(collection.name) === usersCollectionKey) {
448
- const collectionImportDefs = collection.importDefs;
449
- if (!collectionImportDefs || !collectionImportDefs.length) {
450
- return;
451
- }
452
- collectionImportDefs.forEach((importDef) => {
453
- if (importDef.primaryKeyField) {
454
- usersCollectionPrimaryKeyFields.add(importDef.primaryKeyField);
455
- }
456
- });
457
- }
458
- });
459
-
460
- console.log(
461
- `Primary key fields collected for users collection: ${[
462
- ...usersCollectionPrimaryKeyFields,
463
- ]}`
464
- );
465
-
466
- // Iterate over all collections to update references based on merged users
467
- this.config.collections.forEach((collection) => {
468
- const collectionData = this.importMap.get(
469
- this.getCollectionKey(collection.name)
470
- );
471
-
472
- if (!collectionData || !collectionData.data) {
473
- console.log(`No data found for collection ${collection.name}`);
474
- return;
475
- }
476
-
477
- const collectionImportDefs = collection.importDefs;
478
- if (!collectionImportDefs || !collectionImportDefs.length) {
479
- console.log(
480
- `No import definitions found for collection ${collection.name}`
481
- );
482
- return;
483
- }
484
-
485
- collectionImportDefs.forEach((importDef) => {
486
- importDef.idMappings?.forEach((idMapping) => {
487
- if (
488
- this.getCollectionKey(idMapping.targetCollection) ===
489
- usersCollectionKey
490
- ) {
491
- const fieldToSetKey = idMapping.fieldToSet || idMapping.sourceField;
492
- const targetFieldKey =
493
- idMapping.targetFieldToMatch || idMapping.targetField;
494
-
495
- if (usersCollectionPrimaryKeyFields.has(targetFieldKey)) {
496
- console.log(
497
- `Processing collection ${collection.name} with target field ${targetFieldKey}`
498
- );
499
-
500
- // Process each item in the collection
501
- collectionData.data.forEach((item) => {
502
- const oldId =
503
- item.finalData[idMapping.sourceField] ||
504
- item.context[idMapping.sourceField];
505
-
506
- if (oldId === undefined || oldId === null) {
507
- console.log(
508
- `Skipping item with undefined or null oldId in collection ${collection.name}`
509
- );
510
- return;
511
- }
512
-
513
- const newId = this.mergedUserMap.get(`${oldId}`);
514
-
515
- if (newId) {
516
- needsUpdate = true;
517
- numUpdates++;
518
- console.log(
519
- `Updating old ID ${oldId} to new ID ${newId} in collection ${collection.name}`
520
- );
521
-
522
- // Update context to use new user ID
523
- item.finalData[fieldToSetKey] = newId;
524
- item.context[fieldToSetKey] = newId;
525
- } else {
526
- console.log(
527
- `No new ID found for old ID ${oldId} in mergedUserMap.`
528
- );
529
- }
530
- });
531
- }
532
- }
533
- });
534
- });
535
-
536
- if (needsUpdate) {
537
- console.log(
538
- `Updated ${numUpdates} references for collection ${collection.name}`
539
- );
540
- this.importMap.set(
541
- this.getCollectionKey(collection.name),
542
- collectionData
543
- );
544
- }
545
- });
546
- }
431
+ /**
432
+ * Deals with merged users by iterating through all collections in the configuration.
433
+ * We have merged users if there are duplicate emails or phones in the import data.
434
+ * This function will iterate through all collections that are the same name as the
435
+ * users collection and pull out their primaryKeyField's. It will then loop through
436
+ * each collection and find any documents that have a
437
+ *
438
+ * @return {void} This function does not return anything.
439
+ */
440
+ // dealWithMergedUsers() {
441
+ // const usersCollectionKey = this.getCollectionKey(
442
+ // this.config.usersCollectionName
443
+ // );
444
+ // const usersCollectionData = this.importMap.get(usersCollectionKey);
445
+
446
+ // if (!this.config.collections) {
447
+ // console.log("No collections found in configuration.");
448
+ // return;
449
+ // }
450
+
451
+ // let needsUpdate = false;
452
+ // let numUpdates = 0;
453
+
454
+ // for (const collectionConfig of this.config.collections) {
455
+ // const collectionKey = this.getCollectionKey(collectionConfig.name);
456
+ // const collectionData = this.importMap.get(collectionKey);
457
+ // const collectionImportDefs = collectionConfig.importDefs;
458
+ // const collectionIdMappings = collectionImportDefs
459
+ // .map((importDef) => importDef.idMappings)
460
+ // .flat()
461
+ // .filter((idMapping) => idMapping !== undefined && idMapping !== null);
462
+ // if (!collectionData || !collectionData.data) continue;
463
+ // for (const dataItem of collectionData.data) {
464
+ // for (const idMapping of collectionIdMappings) {
465
+ // // We know it's the users collection here
466
+ // if (this.getCollectionKey(idMapping.targetCollection) === usersCollectionKey) {
467
+ // const targetFieldKey = idMapping.targetFieldToMatch || idMapping.targetField;
468
+ // if (targetFieldKey === )
469
+ // const targetValue = dataItem.finalData[targetFieldKey];
470
+ // const targetCollectionData = this.importMap.get(this.getCollectionKey(idMapping.targetCollection));
471
+ // if (!targetCollectionData || !targetCollectionData.data) continue;
472
+ // const foundData = targetCollectionData.data.filter(({ context }) => {
473
+ // const targetValue = context[targetFieldKey];
474
+ // const isMatch = `${targetValue}` === `${valueToMatch}`;
475
+ // return isMatch && targetValue !== undefined && targetValue !== null;
476
+ // });
477
+ // }
478
+ // }
479
+ // }
480
+ // }
481
+ // }
547
482
 
548
483
  updateOldReferencesForNew() {
549
484
  if (!this.config.collections) {
@@ -655,7 +590,12 @@ export class DataLoader {
655
590
  // Merge arrays if new data is non-empty array and filter for uniqueness
656
591
  collectionData.data[i].finalData[fieldToSetKey] = [
657
592
  ...new Set(
658
- [...currentDataFiltered, ...newData].filter(
593
+ [
594
+ ...(Array.isArray(currentDataFiltered)
595
+ ? currentDataFiltered
596
+ : [currentDataFiltered]),
597
+ ...newData,
598
+ ].filter(
659
599
  (value: any) => `${value}` !== `${valueToMatch}`
660
600
  )
661
601
  ),
@@ -216,6 +216,9 @@ export const startSetup = async (
216
216
  await backupDatabase(database, db.$id, storage);
217
217
  }
218
218
  deletedCollections = await wipeDatabase(database, db.$id);
219
+ // Add a delay to ensure the deletion process completes
220
+ await new Promise((resolve) => setTimeout(resolve, 5000));
221
+ console.log(`Waited a few seconds to let the database wipe complete...`);
219
222
  }
220
223
 
221
224
  if (processDatabase) {
@@ -163,6 +163,7 @@ export const tryAwaitWithRetry = async <T>(
163
163
  if (throwError) {
164
164
  throw error;
165
165
  }
166
+ console.error("Error during retryAwait function: " + error);
166
167
  // @ts-ignore
167
168
  return Promise.resolve();
168
169
  }