appwrite-utils-cli 0.0.63 → 0.0.65
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.
@@ -623,6 +623,16 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
623
623
|
relatedCollection: string;
|
624
624
|
relationType: "oneToMany" | "manyToOne" | "oneToOne" | "manyToMany";
|
625
625
|
twoWay: boolean;
|
626
|
+
/**
|
627
|
+
* Generates attribute mappings with post-import actions based on the provided attribute mappings.
|
628
|
+
* This method checks each mapping for a fileData attribute and adds a post-import action to create a file
|
629
|
+
* and update the field with the file's ID if necessary.
|
630
|
+
*
|
631
|
+
* @param attributeMappings - The attribute mappings from the import definition.
|
632
|
+
* @param context - The context object containing information about the database, collection, and document.
|
633
|
+
* @param item - The item being imported, used for resolving template paths in fileData mappings.
|
634
|
+
* @returns The attribute mappings updated with any necessary post-import actions.
|
635
|
+
*/
|
626
636
|
twoWayKey: string;
|
627
637
|
onDelete: "setNull" | "cascade" | "restrict";
|
628
638
|
side: "parent" | "child";
|
@@ -1235,6 +1245,16 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
1235
1245
|
relatedCollection: string;
|
1236
1246
|
relationType: "oneToMany" | "manyToOne" | "oneToOne" | "manyToMany";
|
1237
1247
|
twoWay: boolean;
|
1248
|
+
/**
|
1249
|
+
* Generates attribute mappings with post-import actions based on the provided attribute mappings.
|
1250
|
+
* This method checks each mapping for a fileData attribute and adds a post-import action to create a file
|
1251
|
+
* and update the field with the file's ID if necessary.
|
1252
|
+
*
|
1253
|
+
* @param attributeMappings - The attribute mappings from the import definition.
|
1254
|
+
* @param context - The context object containing information about the database, collection, and document.
|
1255
|
+
* @param item - The item being imported, used for resolving template paths in fileData mappings.
|
1256
|
+
* @returns The attribute mappings updated with any necessary post-import actions.
|
1257
|
+
*/
|
1238
1258
|
twoWayKey: string;
|
1239
1259
|
onDelete: "setNull" | "cascade" | "restrict";
|
1240
1260
|
side: "parent" | "child";
|
@@ -1635,6 +1655,16 @@ export declare class DataLoader {
|
|
1635
1655
|
relatedCollection: string;
|
1636
1656
|
relationType: "oneToMany" | "manyToOne" | "oneToOne" | "manyToMany";
|
1637
1657
|
twoWay: boolean;
|
1658
|
+
/**
|
1659
|
+
* Generates attribute mappings with post-import actions based on the provided attribute mappings.
|
1660
|
+
* This method checks each mapping for a fileData attribute and adds a post-import action to create a file
|
1661
|
+
* and update the field with the file's ID if necessary.
|
1662
|
+
*
|
1663
|
+
* @param attributeMappings - The attribute mappings from the import definition.
|
1664
|
+
* @param context - The context object containing information about the database, collection, and document.
|
1665
|
+
* @param item - The item being imported, used for resolving template paths in fileData mappings.
|
1666
|
+
* @returns The attribute mappings updated with any necessary post-import actions.
|
1667
|
+
*/
|
1638
1668
|
twoWayKey: string;
|
1639
1669
|
onDelete: "setNull" | "cascade" | "restrict";
|
1640
1670
|
side: "parent" | "child";
|
@@ -278,6 +278,11 @@ export class DataLoader {
|
|
278
278
|
userId: user.$id,
|
279
279
|
docId: user.$id,
|
280
280
|
},
|
281
|
+
context: {
|
282
|
+
...user,
|
283
|
+
userId: user.$id,
|
284
|
+
docId: user.$id,
|
285
|
+
},
|
281
286
|
rawData: user,
|
282
287
|
});
|
283
288
|
this.importMap.set(this.getCollectionKey("users"), importData);
|
@@ -449,13 +454,6 @@ export class DataLoader {
|
|
449
454
|
targetValue !== undefined &&
|
450
455
|
targetValue !== null);
|
451
456
|
});
|
452
|
-
// Log and skip if no matching data found
|
453
|
-
if (!foundData.length) {
|
454
|
-
console.log(`No data found for collection ${collectionConfig.name}:\nTarget collection: ${targetCollectionKey}\nValue to match: ${valueToMatch}\nField to set: ${fieldToSetKey}\nTarget field to match: ${targetFieldKey}\nTarget field value: ${idMapping.targetField}`);
|
455
|
-
logger.info(`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(idMapping, null, 2)}`);
|
456
|
-
continue;
|
457
|
-
}
|
458
|
-
needsUpdate = true;
|
459
457
|
const getCurrentDataFiltered = (currentData) => {
|
460
458
|
if (Array.isArray(currentData.finalData[fieldToSetKey])) {
|
461
459
|
return currentData.finalData[fieldToSetKey].filter((data) => `${data}` !== `${valueToMatch}`);
|
@@ -464,6 +462,13 @@ export class DataLoader {
|
|
464
462
|
};
|
465
463
|
// Get the current data to be updated
|
466
464
|
const currentDataFiltered = getCurrentDataFiltered(collectionData.data[i]);
|
465
|
+
// Log and skip if no matching data found
|
466
|
+
if (!foundData.length) {
|
467
|
+
console.log(`No data found for collection ${collectionConfig.name}:\nTarget collection: ${targetCollectionKey}\nValue to match: ${valueToMatch}\nField to set: ${fieldToSetKey}\nTarget field to match: ${targetFieldKey}\nTarget field value: ${idMapping.targetField}`);
|
468
|
+
logger.info(`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(idMapping, null, 2)}`);
|
469
|
+
continue;
|
470
|
+
}
|
471
|
+
needsUpdate = true;
|
467
472
|
// Extract the new data to set
|
468
473
|
const newData = foundData.map((data) => {
|
469
474
|
const valueFound = this.getValueFromData(data.finalData, data.context, idMapping.targetField);
|
@@ -576,6 +581,11 @@ export class DataLoader {
|
|
576
581
|
* @returns The transformed item with user-specific keys removed.
|
577
582
|
*/
|
578
583
|
prepareUserData(item, attributeMappings, primaryKeyField, newId) {
|
584
|
+
if (this.userExistsMap.has(newId) ||
|
585
|
+
Array.from(this.emailToUserIdMap.values()).includes(newId) ||
|
586
|
+
Array.from(this.phoneToUserIdMap.values()).includes(newId)) {
|
587
|
+
newId = this.getTrueUniqueId(this.getCollectionKey("users"));
|
588
|
+
}
|
579
589
|
let transformedItem = this.transformData(item, attributeMappings);
|
580
590
|
const userData = AuthUserCreateSchema.safeParse(transformedItem);
|
581
591
|
if (!userData.success || !(userData.data.email && userData.data.phone)) {
|
@@ -808,7 +818,18 @@ export class DataLoader {
|
|
808
818
|
updatedData.data[i].context.userId === existingId) {
|
809
819
|
updatedData.data[i].finalData = this.mergeObjects(updatedData.data[i].finalData, transformedItem);
|
810
820
|
updatedData.data[i].context = this.mergeObjects(updatedData.data[i].context, context);
|
811
|
-
|
821
|
+
const mergedImportDef = {
|
822
|
+
...updatedData.data[i].importDef,
|
823
|
+
idMappings: [
|
824
|
+
...(updatedData.data[i].importDef?.idMappings || []),
|
825
|
+
...(newImportDef.idMappings || []),
|
826
|
+
],
|
827
|
+
attributeMappings: [
|
828
|
+
...(updatedData.data[i].importDef?.attributeMappings || []),
|
829
|
+
...(newImportDef.attributeMappings || []),
|
830
|
+
],
|
831
|
+
};
|
832
|
+
updatedData.data[i].importDef = mergedImportDef;
|
812
833
|
this.importMap.set(this.getCollectionKey(collection.name), updatedData);
|
813
834
|
this.oldIdToNewIdPerCollectionMap.set(this.getCollectionKey(collection.name), collectionOldIdToNewIdMap);
|
814
835
|
foundData = true;
|
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.65",
|
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.3.
|
36
|
+
"appwrite-utils": "^0.3.2",
|
37
37
|
"commander": "^12.0.0",
|
38
38
|
"inquirer": "^9.2.20",
|
39
39
|
"js-yaml": "^4.1.0",
|
@@ -348,6 +348,11 @@ export class DataLoader {
|
|
348
348
|
userId: user.$id,
|
349
349
|
docId: user.$id,
|
350
350
|
},
|
351
|
+
context: {
|
352
|
+
...user,
|
353
|
+
userId: user.$id,
|
354
|
+
docId: user.$id,
|
355
|
+
},
|
351
356
|
rawData: user,
|
352
357
|
});
|
353
358
|
this.importMap.set(this.getCollectionKey("users"), importData);
|
@@ -571,6 +576,20 @@ export class DataLoader {
|
|
571
576
|
);
|
572
577
|
}
|
573
578
|
);
|
579
|
+
|
580
|
+
const getCurrentDataFiltered = (currentData: any) => {
|
581
|
+
if (Array.isArray(currentData.finalData[fieldToSetKey])) {
|
582
|
+
return currentData.finalData[fieldToSetKey].filter(
|
583
|
+
(data: any) => `${data}` !== `${valueToMatch}`
|
584
|
+
);
|
585
|
+
}
|
586
|
+
return currentData.finalData[fieldToSetKey];
|
587
|
+
};
|
588
|
+
|
589
|
+
// Get the current data to be updated
|
590
|
+
const currentDataFiltered = getCurrentDataFiltered(
|
591
|
+
collectionData.data[i]
|
592
|
+
);
|
574
593
|
// Log and skip if no matching data found
|
575
594
|
if (!foundData.length) {
|
576
595
|
console.log(
|
@@ -588,20 +607,6 @@ export class DataLoader {
|
|
588
607
|
|
589
608
|
needsUpdate = true;
|
590
609
|
|
591
|
-
const getCurrentDataFiltered = (currentData: any) => {
|
592
|
-
if (Array.isArray(currentData.finalData[fieldToSetKey])) {
|
593
|
-
return currentData.finalData[fieldToSetKey].filter(
|
594
|
-
(data: any) => `${data}` !== `${valueToMatch}`
|
595
|
-
);
|
596
|
-
}
|
597
|
-
return currentData.finalData[fieldToSetKey];
|
598
|
-
};
|
599
|
-
|
600
|
-
// Get the current data to be updated
|
601
|
-
const currentDataFiltered = getCurrentDataFiltered(
|
602
|
-
collectionData.data[i]
|
603
|
-
);
|
604
|
-
|
605
610
|
// Extract the new data to set
|
606
611
|
const newData = foundData.map((data) => {
|
607
612
|
const valueFound = this.getValueFromData(
|
@@ -755,6 +760,13 @@ export class DataLoader {
|
|
755
760
|
finalData: z.infer<typeof AuthUserCreateSchema>;
|
756
761
|
};
|
757
762
|
} {
|
763
|
+
if (
|
764
|
+
this.userExistsMap.has(newId) ||
|
765
|
+
Array.from(this.emailToUserIdMap.values()).includes(newId) ||
|
766
|
+
Array.from(this.phoneToUserIdMap.values()).includes(newId)
|
767
|
+
) {
|
768
|
+
newId = this.getTrueUniqueId(this.getCollectionKey("users"));
|
769
|
+
}
|
758
770
|
let transformedItem = this.transformData(item, attributeMappings);
|
759
771
|
const userData = AuthUserCreateSchema.safeParse(transformedItem);
|
760
772
|
if (!userData.success || !(userData.data.email && userData.data.phone)) {
|
@@ -1057,10 +1069,18 @@ export class DataLoader {
|
|
1057
1069
|
updatedData.data[i].context,
|
1058
1070
|
context
|
1059
1071
|
);
|
1060
|
-
|
1061
|
-
updatedData.data[i].importDef,
|
1062
|
-
|
1063
|
-
|
1072
|
+
const mergedImportDef = {
|
1073
|
+
...updatedData.data[i].importDef,
|
1074
|
+
idMappings: [
|
1075
|
+
...(updatedData.data[i].importDef?.idMappings || []),
|
1076
|
+
...(newImportDef.idMappings || []),
|
1077
|
+
],
|
1078
|
+
attributeMappings: [
|
1079
|
+
...(updatedData.data[i].importDef?.attributeMappings || []),
|
1080
|
+
...(newImportDef.attributeMappings || []),
|
1081
|
+
],
|
1082
|
+
};
|
1083
|
+
updatedData.data[i].importDef = mergedImportDef as ImportDef;
|
1064
1084
|
this.importMap.set(
|
1065
1085
|
this.getCollectionKey(collection.name),
|
1066
1086
|
updatedData
|