appwrite-utils-cli 0.0.32 → 0.0.34
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 +103 -97
- package/dist/migrations/backup.d.ts +2 -0
- package/dist/migrations/dataLoader.d.ts +40 -4
- package/dist/migrations/dataLoader.js +119 -126
- package/dist/migrations/importController.js +54 -50
- package/dist/migrations/schemaStrings.js +38 -38
- package/dist/migrations/users.js +4 -0
- package/package.json +54 -54
- package/src/main.ts +83 -83
- package/src/migrations/dataLoader.ts +140 -169
- package/src/migrations/importController.ts +62 -63
- package/src/migrations/openapi.ts +83 -83
- package/src/migrations/schemaStrings.ts +473 -473
- package/src/migrations/users.ts +4 -0
- package/src/utilsController.ts +194 -194
|
@@ -124,7 +124,7 @@ export class DataLoader {
|
|
|
124
124
|
result[key] = updateValue;
|
|
125
125
|
}
|
|
126
126
|
// If the update value is nullish, keep the original value unless it doesn't exist
|
|
127
|
-
else if (sourceValue === undefined) {
|
|
127
|
+
else if (sourceValue === undefined || sourceValue === null) {
|
|
128
128
|
result[key] = updateValue;
|
|
129
129
|
}
|
|
130
130
|
});
|
|
@@ -298,6 +298,10 @@ export class DataLoader {
|
|
|
298
298
|
let isUsersCollection =
|
|
299
299
|
this.getCollectionKey(this.config.usersCollectionName) ===
|
|
300
300
|
this.getCollectionKey(collection.name);
|
|
301
|
+
const collectionDefs = collection.importDefs;
|
|
302
|
+
if (!collectionDefs || !collectionDefs.length) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
301
305
|
// Process create and update definitions for the collection
|
|
302
306
|
const createDefs = collection.importDefs.filter(
|
|
303
307
|
(def: ImportDef) => def.type === "create" || !def.type
|
|
@@ -331,8 +335,8 @@ export class DataLoader {
|
|
|
331
335
|
}
|
|
332
336
|
}
|
|
333
337
|
console.log("Running update references");
|
|
334
|
-
|
|
335
|
-
|
|
338
|
+
this.dealWithMergedUsers();
|
|
339
|
+
this.updateOldReferencesForNew();
|
|
336
340
|
console.log("Done running update references");
|
|
337
341
|
}
|
|
338
342
|
// for (const collection of this.config.collections) {
|
|
@@ -346,7 +350,7 @@ export class DataLoader {
|
|
|
346
350
|
}
|
|
347
351
|
}
|
|
348
352
|
|
|
349
|
-
|
|
353
|
+
dealWithMergedUsers() {
|
|
350
354
|
const usersCollectionKey = this.getCollectionKey(
|
|
351
355
|
this.config.usersCollectionName
|
|
352
356
|
);
|
|
@@ -357,7 +361,11 @@ export class DataLoader {
|
|
|
357
361
|
// Collect primary key fields from the users collection definitions
|
|
358
362
|
this.config.collections.forEach((collection) => {
|
|
359
363
|
if (this.getCollectionKey(collection.name) === usersCollectionKey) {
|
|
360
|
-
collection.importDefs
|
|
364
|
+
const collectionImportDefs = collection.importDefs;
|
|
365
|
+
if (!collectionImportDefs || !collectionImportDefs.length) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
collectionImportDefs.forEach((importDef) => {
|
|
361
369
|
if (importDef.primaryKeyField) {
|
|
362
370
|
usersCollectionPrimaryKeyFields.add(importDef.primaryKeyField);
|
|
363
371
|
}
|
|
@@ -371,23 +379,29 @@ export class DataLoader {
|
|
|
371
379
|
this.getCollectionKey(collection.name)
|
|
372
380
|
);
|
|
373
381
|
if (!collectionData || !collectionData.data) return;
|
|
374
|
-
|
|
375
|
-
|
|
382
|
+
const collectionImportDefs = collection.importDefs;
|
|
383
|
+
if (!collectionImportDefs || !collectionImportDefs.length) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
collectionImportDefs.forEach((importDef) => {
|
|
376
387
|
importDef.idMappings?.forEach((idMapping) => {
|
|
377
388
|
if (
|
|
378
389
|
this.getCollectionKey(idMapping.targetCollection) ===
|
|
379
390
|
usersCollectionKey
|
|
380
391
|
) {
|
|
381
|
-
|
|
392
|
+
const targetFieldKey =
|
|
393
|
+
idMapping.targetFieldToMatch || idMapping.targetField;
|
|
394
|
+
if (usersCollectionPrimaryKeyFields.has(targetFieldKey)) {
|
|
382
395
|
// Process each item in the collection
|
|
383
396
|
collectionData.data.forEach((item) => {
|
|
384
397
|
const oldId = item.context[idMapping.sourceField];
|
|
385
|
-
const newId = this.mergedUserMap.get(oldId);
|
|
398
|
+
const newId = this.mergedUserMap.get(`${oldId}`);
|
|
386
399
|
|
|
387
400
|
if (newId) {
|
|
388
401
|
// Update context to use new user ID
|
|
389
|
-
item.
|
|
390
|
-
|
|
402
|
+
item.finalData[
|
|
403
|
+
idMapping.fieldToSet || idMapping.sourceField
|
|
404
|
+
] = newId;
|
|
391
405
|
}
|
|
392
406
|
});
|
|
393
407
|
}
|
|
@@ -401,6 +415,7 @@ export class DataLoader {
|
|
|
401
415
|
if (!this.config.collections) {
|
|
402
416
|
return;
|
|
403
417
|
}
|
|
418
|
+
|
|
404
419
|
for (const collectionConfig of this.config.collections) {
|
|
405
420
|
const collectionKey = this.getCollectionKey(collectionConfig.name);
|
|
406
421
|
const collectionData = this.importMap.get(collectionKey);
|
|
@@ -424,29 +439,41 @@ export class DataLoader {
|
|
|
424
439
|
);
|
|
425
440
|
const fieldToSetKey =
|
|
426
441
|
idMapping.fieldToSet || idMapping.sourceField;
|
|
442
|
+
const targetFieldKey =
|
|
443
|
+
idMapping.targetFieldToMatch || idMapping.targetField;
|
|
427
444
|
const valueToMatch =
|
|
428
445
|
collectionData.data[i].context[idMapping.sourceField];
|
|
429
446
|
|
|
447
|
+
// Skip if value to match is missing or empty
|
|
430
448
|
if (!valueToMatch || _.isEmpty(valueToMatch)) continue;
|
|
431
449
|
|
|
450
|
+
const isFieldToSetArray = collectionConfig.attributes.find(
|
|
451
|
+
(attribute) => attribute.key === fieldToSetKey
|
|
452
|
+
)?.array;
|
|
453
|
+
|
|
432
454
|
const targetCollectionData =
|
|
433
455
|
this.importMap.get(targetCollectionKey);
|
|
434
456
|
if (!targetCollectionData || !targetCollectionData.data)
|
|
435
457
|
continue;
|
|
436
458
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
459
|
+
// Find matching data in the target collection
|
|
460
|
+
const foundData = targetCollectionData.data.filter(
|
|
461
|
+
({ context }) => {
|
|
462
|
+
const targetValue = context[targetFieldKey];
|
|
463
|
+
const isMatch = `${targetValue}` === `${valueToMatch}`;
|
|
464
|
+
// Ensure the targetValue is defined and not null
|
|
465
|
+
return (
|
|
466
|
+
isMatch &&
|
|
467
|
+
targetValue !== undefined &&
|
|
468
|
+
targetValue !== null
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
);
|
|
446
472
|
|
|
473
|
+
// Log and skip if no matching data found
|
|
447
474
|
if (!foundData.length) {
|
|
448
475
|
console.log(
|
|
449
|
-
`No data found for collection: ${targetCollectionKey}
|
|
476
|
+
`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}`
|
|
450
477
|
);
|
|
451
478
|
logger.error(
|
|
452
479
|
`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(
|
|
@@ -460,143 +487,72 @@ export class DataLoader {
|
|
|
460
487
|
|
|
461
488
|
needsUpdate = true;
|
|
462
489
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
foundData[0].finalData;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
if (needsUpdate) {
|
|
480
|
-
this.importMap.set(collectionKey, collectionData);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
async updateReferencesInRelatedCollections() {
|
|
486
|
-
if (!this.config.collections) {
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
// Iterate over each collection configuration
|
|
490
|
-
for (const collectionConfig of this.config.collections) {
|
|
491
|
-
const collectionKey = this.getCollectionKey(collectionConfig.name);
|
|
492
|
-
const collectionData = this.importMap.get(collectionKey);
|
|
493
|
-
|
|
494
|
-
if (!collectionData || !collectionData.data) continue;
|
|
495
|
-
|
|
496
|
-
console.log(
|
|
497
|
-
`Updating references for collection: ${collectionConfig.name}`
|
|
498
|
-
);
|
|
490
|
+
const getCurrentDataFiltered = (currentData: any) => {
|
|
491
|
+
if (Array.isArray(currentData.finalData[fieldToSetKey])) {
|
|
492
|
+
return currentData.finalData[fieldToSetKey].filter(
|
|
493
|
+
(data: any) => `${data}` !== `${valueToMatch}`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
return currentData.finalData[fieldToSetKey];
|
|
497
|
+
};
|
|
499
498
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
499
|
+
// Get the current data to be updated
|
|
500
|
+
const currentDataFiltered = getCurrentDataFiltered(
|
|
501
|
+
collectionData.data[i]
|
|
502
|
+
);
|
|
503
503
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
// Iterate over each idMapping defined for the current import definition
|
|
509
|
-
for (const idMapping of importDef.idMappings) {
|
|
510
|
-
const oldIds = Array.isArray(
|
|
511
|
-
item.context[idMapping.sourceField]
|
|
512
|
-
)
|
|
513
|
-
? item.context[idMapping.sourceField]
|
|
514
|
-
: [item.context[idMapping.sourceField]];
|
|
515
|
-
const resolvedNewIds: string[] = [];
|
|
516
|
-
|
|
517
|
-
oldIds.forEach((oldId: any) => {
|
|
518
|
-
// Attempt to find a new ID for the old ID
|
|
519
|
-
let newIdForOldId = this.findNewIdForOldId(
|
|
520
|
-
oldId,
|
|
521
|
-
idMapping,
|
|
522
|
-
importDef
|
|
523
|
-
);
|
|
504
|
+
// Extract the new data to set
|
|
505
|
+
const newData = foundData.map(
|
|
506
|
+
(data) => data.context[idMapping.targetField]
|
|
507
|
+
);
|
|
524
508
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
509
|
+
// Handle cases where current data is an array
|
|
510
|
+
if (isFieldToSetArray) {
|
|
511
|
+
if (!currentDataFiltered) {
|
|
512
|
+
// Set new data if current data is undefined
|
|
513
|
+
collectionData.data[i].finalData[fieldToSetKey] =
|
|
514
|
+
Array.isArray(newData) ? newData : [newData];
|
|
530
515
|
} else {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
516
|
+
// Merge arrays if new data is non-empty array and filter for uniqueness
|
|
517
|
+
collectionData.data[i].finalData[fieldToSetKey] = [
|
|
518
|
+
...new Set(
|
|
519
|
+
[...currentDataFiltered, ...newData].filter(
|
|
520
|
+
(value: any) => `${value}` !== `${valueToMatch}`
|
|
521
|
+
)
|
|
522
|
+
),
|
|
523
|
+
];
|
|
524
|
+
}
|
|
525
|
+
} else {
|
|
526
|
+
if (!currentDataFiltered) {
|
|
527
|
+
// Set new data if current data is undefined
|
|
528
|
+
collectionData.data[i].finalData[fieldToSetKey] =
|
|
529
|
+
Array.isArray(newData) ? newData[0] : newData;
|
|
530
|
+
} else if (Array.isArray(newData) && newData.length > 0) {
|
|
531
|
+
// Convert current data to array and merge if new data is non-empty array, then filter for uniqueness
|
|
532
|
+
// and take the first value, because it's an array and the attribute is not an array
|
|
533
|
+
collectionData.data[i].finalData[fieldToSetKey] = [
|
|
534
|
+
...new Set(
|
|
535
|
+
[currentDataFiltered, ...newData].filter(
|
|
536
|
+
(value: any) => `${value}` !== `${valueToMatch}`
|
|
537
|
+
)
|
|
538
|
+
),
|
|
539
|
+
].slice(0, 1)[0];
|
|
540
|
+
} else if (!Array.isArray(newData) && newData !== undefined) {
|
|
541
|
+
// Simply update the field if new data is not an array and defined
|
|
542
|
+
collectionData.data[i].finalData[fieldToSetKey] = newData;
|
|
534
543
|
}
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
if (resolvedNewIds.length) {
|
|
538
|
-
const targetField =
|
|
539
|
-
idMapping.fieldToSet || idMapping.targetField;
|
|
540
|
-
const isArray = collectionConfig.attributes.some(
|
|
541
|
-
(attribute) =>
|
|
542
|
-
attribute.key === targetField && attribute.array
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
// Set the target field based on whether it's an array or single value
|
|
546
|
-
item.finalData[targetField] = isArray
|
|
547
|
-
? resolvedNewIds
|
|
548
|
-
: resolvedNewIds[0];
|
|
549
|
-
needsUpdate = true;
|
|
550
544
|
}
|
|
551
545
|
}
|
|
552
546
|
}
|
|
553
547
|
}
|
|
554
548
|
}
|
|
555
|
-
|
|
556
|
-
// Update the importMap if changes were made to the item
|
|
557
|
-
if (needsUpdate) {
|
|
558
|
-
this.importMap.set(collectionKey, collectionData);
|
|
559
|
-
logger.info(
|
|
560
|
-
`Updated item: ${JSON.stringify(item.finalData, undefined, 2)}`
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
findNewIdForOldId(oldId: string, idMapping: IdMapping, importDef: ImportDef) {
|
|
568
|
-
// First, check if this ID mapping is related to the users collection.
|
|
569
|
-
const targetCollectionKey = this.getCollectionKey(
|
|
570
|
-
idMapping.targetCollection
|
|
571
|
-
);
|
|
572
|
-
const isUsersCollection =
|
|
573
|
-
targetCollectionKey ===
|
|
574
|
-
this.getCollectionKey(this.config.usersCollectionName);
|
|
575
|
-
|
|
576
|
-
// If handling users, check the mergedUserMap for any existing new ID.
|
|
577
|
-
if (isUsersCollection) {
|
|
578
|
-
for (const [newUserId, oldIds] of this.mergedUserMap.entries()) {
|
|
579
|
-
if (oldIds.includes(oldId)) {
|
|
580
|
-
return newUserId;
|
|
581
|
-
}
|
|
582
549
|
}
|
|
583
|
-
}
|
|
584
550
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
const foundEntry = targetCollectionData.data.find(
|
|
589
|
-
(entry) => entry.context[importDef.primaryKeyField] === oldId
|
|
590
|
-
);
|
|
591
|
-
if (foundEntry) {
|
|
592
|
-
return foundEntry.context.docId; // Assuming `docId` stores the new ID after import
|
|
551
|
+
// Update the import map if any changes were made
|
|
552
|
+
if (needsUpdate) {
|
|
553
|
+
this.importMap.set(collectionKey, collectionData);
|
|
593
554
|
}
|
|
594
555
|
}
|
|
595
|
-
|
|
596
|
-
logger.error(
|
|
597
|
-
`No corresponding new ID found for ${oldId} in ${targetCollectionKey}`
|
|
598
|
-
);
|
|
599
|
-
return null; // Return null if no new ID is found
|
|
600
556
|
}
|
|
601
557
|
|
|
602
558
|
private writeMapsToJsonFile() {
|
|
@@ -662,7 +618,6 @@ export class DataLoader {
|
|
|
662
618
|
primaryKeyField: string,
|
|
663
619
|
newId: string
|
|
664
620
|
): Promise<any> {
|
|
665
|
-
// Transform the item data based on the attribute mappings
|
|
666
621
|
let transformedItem = this.transformData(item, attributeMappings);
|
|
667
622
|
const userData = AuthUserCreateSchema.safeParse(transformedItem);
|
|
668
623
|
if (!userData.success) {
|
|
@@ -679,48 +634,64 @@ export class DataLoader {
|
|
|
679
634
|
const phone = userData.data.phone;
|
|
680
635
|
let existingId: string | undefined;
|
|
681
636
|
|
|
682
|
-
// Check for duplicate email and
|
|
683
|
-
if (email && email
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
637
|
+
// Check for duplicate email and phone
|
|
638
|
+
if (email && this.emailToUserIdMap.has(email)) {
|
|
639
|
+
existingId = this.emailToUserIdMap.get(email);
|
|
640
|
+
} else if (phone && this.phoneToUserIdMap.has(phone)) {
|
|
641
|
+
existingId = this.phoneToUserIdMap.get(phone);
|
|
642
|
+
} else {
|
|
643
|
+
if (email) this.emailToUserIdMap.set(email, newId);
|
|
644
|
+
if (phone) this.phoneToUserIdMap.set(phone, newId);
|
|
689
645
|
}
|
|
690
646
|
|
|
691
|
-
// Check for duplicate phone and add to phoneToUserIdMap if not found
|
|
692
|
-
if (phone && phone.length > 0) {
|
|
693
|
-
if (this.phoneToUserIdMap.has(phone)) {
|
|
694
|
-
existingId = this.phoneToUserIdMap.get(phone);
|
|
695
|
-
} else {
|
|
696
|
-
this.phoneToUserIdMap.set(phone, newId);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
if (!existingId) {
|
|
700
|
-
existingId = newId;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// If existingId is found, add to mergedUserMap
|
|
704
647
|
if (existingId) {
|
|
705
648
|
userData.data.userId = existingId;
|
|
706
649
|
const mergedUsers = this.mergedUserMap.get(existingId) || [];
|
|
707
650
|
mergedUsers.push(`${item[primaryKeyField]}`);
|
|
708
651
|
this.mergedUserMap.set(existingId, mergedUsers);
|
|
652
|
+
const userFound = this.importMap
|
|
653
|
+
.get(this.getCollectionKey("users"))
|
|
654
|
+
?.data.find((userDataExisting) => {
|
|
655
|
+
let userIdToMatch: string | undefined;
|
|
656
|
+
if (userDataExisting?.finalData?.userId) {
|
|
657
|
+
userIdToMatch = userDataExisting?.finalData?.userId;
|
|
658
|
+
} else if (userDataExisting?.finalData?.docId) {
|
|
659
|
+
userIdToMatch = userDataExisting?.finalData?.docId;
|
|
660
|
+
} else if (userDataExisting?.context?.userId) {
|
|
661
|
+
userIdToMatch = userDataExisting.context.userId;
|
|
662
|
+
} else if (userDataExisting?.context?.docId) {
|
|
663
|
+
userIdToMatch = userDataExisting.context.docId;
|
|
664
|
+
}
|
|
665
|
+
return userIdToMatch === existingId;
|
|
666
|
+
});
|
|
667
|
+
if (userFound) {
|
|
668
|
+
userFound.finalData.userId = existingId;
|
|
669
|
+
}
|
|
670
|
+
return [
|
|
671
|
+
transformedItem,
|
|
672
|
+
existingId,
|
|
673
|
+
{
|
|
674
|
+
rawData: userFound?.rawData,
|
|
675
|
+
finalData: userFound?.finalData,
|
|
676
|
+
},
|
|
677
|
+
];
|
|
678
|
+
} else {
|
|
679
|
+
existingId = newId;
|
|
680
|
+
userData.data.userId = existingId;
|
|
709
681
|
}
|
|
710
682
|
|
|
711
|
-
// Remove user-specific keys from the transformed item
|
|
712
683
|
const userKeys = ["email", "phone", "name", "labels", "prefs"];
|
|
713
684
|
userKeys.forEach((key) => {
|
|
714
685
|
if (transformedItem.hasOwnProperty(key)) {
|
|
715
686
|
delete transformedItem[key];
|
|
716
687
|
}
|
|
717
688
|
});
|
|
689
|
+
|
|
718
690
|
const usersMap = this.importMap.get(this.getCollectionKey("users"));
|
|
719
691
|
const userDataToAdd = {
|
|
720
692
|
rawData: item,
|
|
721
693
|
finalData: userData.data,
|
|
722
694
|
};
|
|
723
|
-
// Directly update the importMap with the new user data, without pushing to usersMap.data first
|
|
724
695
|
this.importMap.set(this.getCollectionKey("users"), {
|
|
725
696
|
data: [...(usersMap?.data || []), userDataToAdd],
|
|
726
697
|
});
|
|
@@ -808,14 +779,14 @@ export class DataLoader {
|
|
|
808
779
|
if (!existingId) {
|
|
809
780
|
// No existing user ID, generate a new unique ID
|
|
810
781
|
existingId = this.getTrueUniqueId(this.getCollectionKey("users"));
|
|
811
|
-
transformedItem.
|
|
782
|
+
transformedItem.docId = existingId; // Assign the new ID to the transformed data's docId field
|
|
812
783
|
}
|
|
813
784
|
|
|
814
785
|
// Create a context object for the item, including the new ID
|
|
815
786
|
let context = this.createContext(db, collection, item, existingId);
|
|
816
787
|
|
|
817
788
|
// Merge the transformed data into the context
|
|
818
|
-
context = { ...context, ...transformedItem };
|
|
789
|
+
context = { ...context, ...transformedItem, ...userData.finalData };
|
|
819
790
|
|
|
820
791
|
// If a primary key field is defined, handle the ID mapping and check for duplicates
|
|
821
792
|
if (importDef.primaryKeyField) {
|
|
@@ -137,53 +137,62 @@ export class ImportController {
|
|
|
137
137
|
const usersData = usersDataMap?.data;
|
|
138
138
|
const usersController = new UsersController(this.config, this.database);
|
|
139
139
|
if (usersData) {
|
|
140
|
-
console.log("Found users data");
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (!(dataLoader.userExistsMap.get(userId) === true)) {
|
|
155
|
-
const userId =
|
|
156
|
-
userBatch.finalData.userId ||
|
|
157
|
-
userBatch.context.userId ||
|
|
158
|
-
userBatch.context.docId;
|
|
159
|
-
if (!userBatch.finalData.userId) {
|
|
160
|
-
userBatch.finalData.userId = userId;
|
|
161
|
-
}
|
|
162
|
-
return usersController
|
|
163
|
-
.createUserAndReturn(userBatch.finalData)
|
|
164
|
-
.then(() => console.log("Created user"))
|
|
165
|
-
.catch((error) => {
|
|
166
|
-
logger.error(
|
|
167
|
-
"Error creating user:",
|
|
168
|
-
error,
|
|
169
|
-
"\nUser data is ",
|
|
170
|
-
userBatch.finalData
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
} else {
|
|
174
|
-
console.log("Skipped existing user: ", userId);
|
|
175
|
-
return Promise.resolve();
|
|
176
|
-
}
|
|
177
|
-
}
|
|
140
|
+
console.log("Found users data", usersData.length);
|
|
141
|
+
const userDataBatches = createBatches(usersData);
|
|
142
|
+
for (const batch of userDataBatches) {
|
|
143
|
+
console.log("Importing users batch", batch.length);
|
|
144
|
+
const userBatchPromises = batch
|
|
145
|
+
.filter((item) => {
|
|
146
|
+
let itemId: string | undefined;
|
|
147
|
+
if (item.finalData.userId) {
|
|
148
|
+
itemId = item.finalData.userId;
|
|
149
|
+
} else if (item.finalData.docId) {
|
|
150
|
+
itemId = item.finalData.docId;
|
|
151
|
+
}
|
|
152
|
+
if (!itemId) {
|
|
153
|
+
return false;
|
|
178
154
|
}
|
|
155
|
+
return (
|
|
156
|
+
item &&
|
|
157
|
+
item.finalData &&
|
|
158
|
+
!dataLoader.userExistsMap.has(itemId)
|
|
159
|
+
);
|
|
179
160
|
})
|
|
180
|
-
.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
161
|
+
.map((item) => {
|
|
162
|
+
return usersController.createUserAndReturn(item.finalData);
|
|
163
|
+
});
|
|
164
|
+
await Promise.all(userBatchPromises);
|
|
165
|
+
for (const item of batch) {
|
|
166
|
+
if (item && item.finalData) {
|
|
167
|
+
dataLoader.userExistsMap.set(
|
|
168
|
+
item.finalData.userId ||
|
|
169
|
+
item.finalData.docId ||
|
|
170
|
+
item.context.userId ||
|
|
171
|
+
item.context.docId,
|
|
172
|
+
true
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
console.log("Finished importing users batch", batch.length);
|
|
186
177
|
}
|
|
178
|
+
// for (let i = 0; i < usersData.length; i++) {
|
|
179
|
+
// const user = usersData[i];
|
|
180
|
+
// if (user.finalData) {
|
|
181
|
+
// const userId =
|
|
182
|
+
// user.finalData.userId ||
|
|
183
|
+
// user.context.userId ||
|
|
184
|
+
// user.context.docId;
|
|
185
|
+
// if (!dataLoader.userExistsMap.has(userId)) {
|
|
186
|
+
// if (!user.finalData.userId) {
|
|
187
|
+
// user.finalData.userId = userId;
|
|
188
|
+
// }
|
|
189
|
+
// await usersController.createUserAndReturn(user.finalData);
|
|
190
|
+
// dataLoader.userExistsMap.set(userId, true);
|
|
191
|
+
// } else {
|
|
192
|
+
// console.log("Skipped existing user: ", userId);
|
|
193
|
+
// }
|
|
194
|
+
// }
|
|
195
|
+
// }
|
|
187
196
|
console.log("Finished importing users");
|
|
188
197
|
}
|
|
189
198
|
}
|
|
@@ -216,10 +225,10 @@ export class ImportController {
|
|
|
216
225
|
console.log(`Processing batch ${i + 1} of ${dataSplit.length}`);
|
|
217
226
|
const batchPromises = batches.map((item) => {
|
|
218
227
|
const id =
|
|
219
|
-
item.context.docId ||
|
|
220
|
-
item.context.userId ||
|
|
221
228
|
item.finalData.docId ||
|
|
222
|
-
item.finalData.userId
|
|
229
|
+
item.finalData.userId ||
|
|
230
|
+
item.context.docId ||
|
|
231
|
+
item.context.userId;
|
|
223
232
|
if (item.finalData.hasOwnProperty("userId")) {
|
|
224
233
|
delete item.finalData.userId;
|
|
225
234
|
}
|
|
@@ -229,22 +238,12 @@ export class ImportController {
|
|
|
229
238
|
if (!item.finalData) {
|
|
230
239
|
return Promise.resolve();
|
|
231
240
|
}
|
|
232
|
-
return this.database
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
.catch((error) => {
|
|
239
|
-
console.error(
|
|
240
|
-
`Error creating item in ${collection.name}:`,
|
|
241
|
-
error,
|
|
242
|
-
"\nItem data is ",
|
|
243
|
-
item.finalData
|
|
244
|
-
);
|
|
245
|
-
throw error;
|
|
246
|
-
// Optionally, log the failed item for retry or review
|
|
247
|
-
});
|
|
241
|
+
return this.database.createDocument(
|
|
242
|
+
db.$id,
|
|
243
|
+
collection.$id,
|
|
244
|
+
id,
|
|
245
|
+
item.finalData
|
|
246
|
+
);
|
|
248
247
|
});
|
|
249
248
|
// Wait for all promises in the current batch to resolve
|
|
250
249
|
await Promise.allSettled(batchPromises);
|