appwrite-utils-cli 0.0.32 → 0.0.33
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 +98 -97
- package/dist/migrations/backup.d.ts +2 -0
- package/dist/migrations/dataLoader.d.ts +22 -4
- package/dist/migrations/dataLoader.js +73 -102
- package/dist/migrations/schemaStrings.js +38 -38
- package/dist/migrations/users.js +3 -0
- package/package.json +54 -54
- package/src/main.ts +83 -83
- package/src/migrations/dataLoader.ts +97 -144
- package/src/migrations/openapi.ts +83 -83
- package/src/migrations/schemaStrings.ts +473 -473
- package/src/migrations/users.ts +3 -0
- package/src/utilsController.ts +194 -194
package/src/main.ts
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { program } from "commander";
|
|
3
|
-
import { UtilsController } from "./utilsController.js";
|
|
4
|
-
|
|
5
|
-
// Setup the main CLI program
|
|
6
|
-
program
|
|
7
|
-
.version("1.0.0")
|
|
8
|
-
.description("Utility CLI for Appwrite configurations and operations")
|
|
9
|
-
.option("--endpoint <endpoint>", "Set the Appwrite endpoint", undefined)
|
|
10
|
-
.option("--project <project>", "Set the Appwrite project ID", undefined)
|
|
11
|
-
.option("--key <key>", "Set the Appwrite API key", undefined)
|
|
12
|
-
.option("--backup", "Perform a backup before executing the command", false)
|
|
13
|
-
.option("--dev", "Run in development environment", false)
|
|
14
|
-
.option("--prod", "Run in production environment", false)
|
|
15
|
-
.option("--staging", "Run in staging environment", false)
|
|
16
|
-
.option("--sync", "Synchronize configurations", false)
|
|
17
|
-
.option("--wipe", "Wipe databases", false)
|
|
18
|
-
.option("--wipe-docs", "Wipe documents", false)
|
|
19
|
-
.option("--wipe-users", "Wipe users", false)
|
|
20
|
-
.option("--generate", "Generate schemas", false)
|
|
21
|
-
.option("--import", "Import data", false)
|
|
22
|
-
.option("--write-data", "Write data to file", false)
|
|
23
|
-
.option("-h, --help", "Display help for command", false);
|
|
24
|
-
|
|
25
|
-
program.on("--help", () => {
|
|
26
|
-
console.log("");
|
|
27
|
-
console.log("Examples:");
|
|
28
|
-
console.log(
|
|
29
|
-
" $ npx appwrite-utils-cli appwrite-migrate --sync --endpoint https://appwrite.example.com --project 123456 --key 7890"
|
|
30
|
-
);
|
|
31
|
-
console.log(
|
|
32
|
-
" $ npx appwrite-utils-cli appwrite-migrate --sync --dev --backup"
|
|
33
|
-
);
|
|
34
|
-
console.log(
|
|
35
|
-
" $ npx appwrite-utils-cli appwrite-migrate --wipe --wipe-docs --wipe-users --dev"
|
|
36
|
-
);
|
|
37
|
-
console.log(
|
|
38
|
-
" $ npx appwrite-utils-cli appwrite-migrate --generate --import --write-data --dev"
|
|
39
|
-
);
|
|
40
|
-
console.log(
|
|
41
|
-
" $ npx appwrite-utils-cli appwrite-migrate --sync --generate --import --write-data --dev --backup"
|
|
42
|
-
);
|
|
43
|
-
console.log(" $ npx appwrite-utils-cli appwrite-create");
|
|
44
|
-
console.log(
|
|
45
|
-
"For more information, visit https://github.com/zachhandley/appwrite-utils"
|
|
46
|
-
);
|
|
47
|
-
console.log("");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// Parse and handle options
|
|
51
|
-
program.action(async (options) => {
|
|
52
|
-
const currentUserDir = process.cwd();
|
|
53
|
-
const controller = new UtilsController(currentUserDir);
|
|
54
|
-
try {
|
|
55
|
-
// Convert Commander options to the format expected by UtilsController
|
|
56
|
-
const setupOptions = {
|
|
57
|
-
sync: options.sync,
|
|
58
|
-
runProd: options.prod,
|
|
59
|
-
runStaging: options.staging,
|
|
60
|
-
runDev: options.dev,
|
|
61
|
-
doBackup: options.backup,
|
|
62
|
-
wipeDatabases: options.wipe,
|
|
63
|
-
wipeDocumentStorage: options.wipeDocs,
|
|
64
|
-
wipeUsers: options.wipeUsers,
|
|
65
|
-
generateSchemas: options.generate,
|
|
66
|
-
generateMockData: false, // Assuming this needs to be set based on other conditions
|
|
67
|
-
importData: options.import,
|
|
68
|
-
checkDuplicates: false, // Assuming this needs to be set based on other conditions
|
|
69
|
-
shouldWriteFile: options.writeData,
|
|
70
|
-
endpoint: options.endpoint,
|
|
71
|
-
project: options.project,
|
|
72
|
-
key: options.key,
|
|
73
|
-
};
|
|
74
|
-
console.log("Running operation...", setupOptions);
|
|
75
|
-
|
|
76
|
-
await controller.run(setupOptions);
|
|
77
|
-
console.log("Operation completed successfully.");
|
|
78
|
-
} catch (error) {
|
|
79
|
-
console.error("Error during operation:", error);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
program.parse(process.argv);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from "commander";
|
|
3
|
+
import { UtilsController } from "./utilsController.js";
|
|
4
|
+
|
|
5
|
+
// Setup the main CLI program
|
|
6
|
+
program
|
|
7
|
+
.version("1.0.0")
|
|
8
|
+
.description("Utility CLI for Appwrite configurations and operations")
|
|
9
|
+
.option("--endpoint <endpoint>", "Set the Appwrite endpoint", undefined)
|
|
10
|
+
.option("--project <project>", "Set the Appwrite project ID", undefined)
|
|
11
|
+
.option("--key <key>", "Set the Appwrite API key", undefined)
|
|
12
|
+
.option("--backup", "Perform a backup before executing the command", false)
|
|
13
|
+
.option("--dev", "Run in development environment", false)
|
|
14
|
+
.option("--prod", "Run in production environment", false)
|
|
15
|
+
.option("--staging", "Run in staging environment", false)
|
|
16
|
+
.option("--sync", "Synchronize configurations", false)
|
|
17
|
+
.option("--wipe", "Wipe databases", false)
|
|
18
|
+
.option("--wipe-docs", "Wipe documents", false)
|
|
19
|
+
.option("--wipe-users", "Wipe users", false)
|
|
20
|
+
.option("--generate", "Generate schemas", false)
|
|
21
|
+
.option("--import", "Import data", false)
|
|
22
|
+
.option("--write-data", "Write data to file", false)
|
|
23
|
+
.option("-h, --help", "Display help for command", false);
|
|
24
|
+
|
|
25
|
+
program.on("--help", () => {
|
|
26
|
+
console.log("");
|
|
27
|
+
console.log("Examples:");
|
|
28
|
+
console.log(
|
|
29
|
+
" $ npx appwrite-utils-cli appwrite-migrate --sync --endpoint https://appwrite.example.com --project 123456 --key 7890"
|
|
30
|
+
);
|
|
31
|
+
console.log(
|
|
32
|
+
" $ npx appwrite-utils-cli appwrite-migrate --sync --dev --backup"
|
|
33
|
+
);
|
|
34
|
+
console.log(
|
|
35
|
+
" $ npx appwrite-utils-cli appwrite-migrate --wipe --wipe-docs --wipe-users --dev"
|
|
36
|
+
);
|
|
37
|
+
console.log(
|
|
38
|
+
" $ npx appwrite-utils-cli appwrite-migrate --generate --import --write-data --dev"
|
|
39
|
+
);
|
|
40
|
+
console.log(
|
|
41
|
+
" $ npx appwrite-utils-cli appwrite-migrate --sync --generate --import --write-data --dev --backup"
|
|
42
|
+
);
|
|
43
|
+
console.log(" $ npx appwrite-utils-cli appwrite-create");
|
|
44
|
+
console.log(
|
|
45
|
+
"For more information, visit https://github.com/zachhandley/appwrite-utils"
|
|
46
|
+
);
|
|
47
|
+
console.log("");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Parse and handle options
|
|
51
|
+
program.action(async (options) => {
|
|
52
|
+
const currentUserDir = process.cwd();
|
|
53
|
+
const controller = new UtilsController(currentUserDir);
|
|
54
|
+
try {
|
|
55
|
+
// Convert Commander options to the format expected by UtilsController
|
|
56
|
+
const setupOptions = {
|
|
57
|
+
sync: options.sync,
|
|
58
|
+
runProd: options.prod,
|
|
59
|
+
runStaging: options.staging,
|
|
60
|
+
runDev: options.dev,
|
|
61
|
+
doBackup: options.backup,
|
|
62
|
+
wipeDatabases: options.wipe,
|
|
63
|
+
wipeDocumentStorage: options.wipeDocs,
|
|
64
|
+
wipeUsers: options.wipeUsers,
|
|
65
|
+
generateSchemas: options.generate,
|
|
66
|
+
generateMockData: false, // Assuming this needs to be set based on other conditions
|
|
67
|
+
importData: options.import,
|
|
68
|
+
checkDuplicates: false, // Assuming this needs to be set based on other conditions
|
|
69
|
+
shouldWriteFile: options.writeData,
|
|
70
|
+
endpoint: options.endpoint,
|
|
71
|
+
project: options.project,
|
|
72
|
+
key: options.key,
|
|
73
|
+
};
|
|
74
|
+
console.log("Running operation...", setupOptions);
|
|
75
|
+
|
|
76
|
+
await controller.run(setupOptions);
|
|
77
|
+
console.log("Operation completed successfully.");
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("Error during operation:", error);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
program.parse(process.argv);
|
|
@@ -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,14 +379,19 @@ 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];
|
|
@@ -386,8 +399,7 @@ export class DataLoader {
|
|
|
386
399
|
|
|
387
400
|
if (newId) {
|
|
388
401
|
// Update context to use new user ID
|
|
389
|
-
item.context[idMapping.fieldToSet ||
|
|
390
|
-
newId;
|
|
402
|
+
item.context[idMapping.fieldToSet || targetFieldKey] = newId;
|
|
391
403
|
}
|
|
392
404
|
});
|
|
393
405
|
}
|
|
@@ -401,6 +413,7 @@ export class DataLoader {
|
|
|
401
413
|
if (!this.config.collections) {
|
|
402
414
|
return;
|
|
403
415
|
}
|
|
416
|
+
|
|
404
417
|
for (const collectionConfig of this.config.collections) {
|
|
405
418
|
const collectionKey = this.getCollectionKey(collectionConfig.name);
|
|
406
419
|
const collectionData = this.importMap.get(collectionKey);
|
|
@@ -424,29 +437,41 @@ export class DataLoader {
|
|
|
424
437
|
);
|
|
425
438
|
const fieldToSetKey =
|
|
426
439
|
idMapping.fieldToSet || idMapping.sourceField;
|
|
440
|
+
const targetFieldKey =
|
|
441
|
+
idMapping.targetFieldToMatch || idMapping.targetField;
|
|
427
442
|
const valueToMatch =
|
|
428
443
|
collectionData.data[i].context[idMapping.sourceField];
|
|
429
444
|
|
|
445
|
+
// Skip if value to match is missing or empty
|
|
430
446
|
if (!valueToMatch || _.isEmpty(valueToMatch)) continue;
|
|
431
447
|
|
|
448
|
+
const isFieldToSetArray = collectionConfig.attributes.find(
|
|
449
|
+
(attribute) => attribute.key === fieldToSetKey
|
|
450
|
+
)?.array;
|
|
451
|
+
|
|
432
452
|
const targetCollectionData =
|
|
433
453
|
this.importMap.get(targetCollectionKey);
|
|
434
454
|
if (!targetCollectionData || !targetCollectionData.data)
|
|
435
455
|
continue;
|
|
436
456
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
457
|
+
// Find matching data in the target collection
|
|
458
|
+
const foundData = targetCollectionData.data.filter(
|
|
459
|
+
({ context }) => {
|
|
460
|
+
const targetValue = context[targetFieldKey];
|
|
461
|
+
const isMatch = `${targetValue}` === `${valueToMatch}`;
|
|
462
|
+
// Ensure the targetValue is defined and not null
|
|
463
|
+
return (
|
|
464
|
+
isMatch &&
|
|
465
|
+
targetValue !== undefined &&
|
|
466
|
+
targetValue !== null
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
);
|
|
446
470
|
|
|
471
|
+
// Log and skip if no matching data found
|
|
447
472
|
if (!foundData.length) {
|
|
448
473
|
console.log(
|
|
449
|
-
`No data found for collection: ${targetCollectionKey}
|
|
474
|
+
`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
475
|
);
|
|
451
476
|
logger.error(
|
|
452
477
|
`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(
|
|
@@ -460,143 +485,71 @@ export class DataLoader {
|
|
|
460
485
|
|
|
461
486
|
needsUpdate = true;
|
|
462
487
|
|
|
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
|
-
);
|
|
488
|
+
const getCurrentDataFiltered = (currentData: any) => {
|
|
489
|
+
if (Array.isArray(currentData.finalData[fieldToSetKey])) {
|
|
490
|
+
return currentData.finalData[fieldToSetKey].filter(
|
|
491
|
+
(data: any) => `${data}` !== `${valueToMatch}`
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
return currentData.finalData[fieldToSetKey];
|
|
495
|
+
};
|
|
499
496
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
497
|
+
// Get the current data to be updated
|
|
498
|
+
const currentDataFiltered = getCurrentDataFiltered(
|
|
499
|
+
collectionData.data[i]
|
|
500
|
+
);
|
|
503
501
|
|
|
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
|
-
);
|
|
502
|
+
// Extract the new data to set
|
|
503
|
+
const newData = foundData.map(
|
|
504
|
+
(data) => data.context[idMapping.targetField]
|
|
505
|
+
);
|
|
524
506
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
507
|
+
// Handle cases where current data is an array
|
|
508
|
+
if (isFieldToSetArray) {
|
|
509
|
+
if (!currentDataFiltered) {
|
|
510
|
+
// Set new data if current data is undefined
|
|
511
|
+
collectionData.data[i].finalData[fieldToSetKey] =
|
|
512
|
+
Array.isArray(newData) ? newData : [newData];
|
|
530
513
|
} else {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
514
|
+
// Merge arrays if new data is non-empty array and filter for uniqueness
|
|
515
|
+
collectionData.data[i].finalData[fieldToSetKey] = [
|
|
516
|
+
...new Set(
|
|
517
|
+
[...currentDataFiltered, ...newData].filter(
|
|
518
|
+
(value: any) => `${value}` !== `${valueToMatch}`
|
|
519
|
+
)
|
|
520
|
+
),
|
|
521
|
+
];
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
if (!currentDataFiltered) {
|
|
525
|
+
// Set new data if current data is undefined
|
|
526
|
+
collectionData.data[i].finalData[fieldToSetKey] =
|
|
527
|
+
Array.isArray(newData) ? newData : [newData];
|
|
528
|
+
} else if (Array.isArray(newData) && newData.length > 0) {
|
|
529
|
+
// Convert current data to array and merge if new data is non-empty array, then filter for uniqueness
|
|
530
|
+
collectionData.data[i].finalData[fieldToSetKey] = [
|
|
531
|
+
...new Set(
|
|
532
|
+
[currentDataFiltered, ...newData].filter(
|
|
533
|
+
(value: any) => `${value}` !== `${valueToMatch}`
|
|
534
|
+
)
|
|
535
|
+
),
|
|
536
|
+
];
|
|
537
|
+
} else if (!Array.isArray(newData) && newData !== undefined) {
|
|
538
|
+
// Simply update the field if new data is not an array and defined
|
|
539
|
+
collectionData.data[i].finalData[fieldToSetKey] = newData;
|
|
534
540
|
}
|
|
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
541
|
}
|
|
551
542
|
}
|
|
552
543
|
}
|
|
553
544
|
}
|
|
554
545
|
}
|
|
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
546
|
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
547
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
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
|
-
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// If not a user or no merged ID found, check the regular ID mapping from old to new.
|
|
586
|
-
const targetCollectionData = this.importMap.get(targetCollectionKey);
|
|
587
|
-
if (targetCollectionData) {
|
|
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
|
|
548
|
+
// Update the import map if any changes were made
|
|
549
|
+
if (needsUpdate) {
|
|
550
|
+
this.importMap.set(collectionKey, collectionData);
|
|
593
551
|
}
|
|
594
552
|
}
|
|
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
553
|
}
|
|
601
554
|
|
|
602
555
|
private writeMapsToJsonFile() {
|
|
@@ -808,14 +761,14 @@ export class DataLoader {
|
|
|
808
761
|
if (!existingId) {
|
|
809
762
|
// No existing user ID, generate a new unique ID
|
|
810
763
|
existingId = this.getTrueUniqueId(this.getCollectionKey("users"));
|
|
811
|
-
transformedItem.
|
|
764
|
+
transformedItem.docId = existingId; // Assign the new ID to the transformed data's docId field
|
|
812
765
|
}
|
|
813
766
|
|
|
814
767
|
// Create a context object for the item, including the new ID
|
|
815
768
|
let context = this.createContext(db, collection, item, existingId);
|
|
816
769
|
|
|
817
770
|
// Merge the transformed data into the context
|
|
818
|
-
context = { ...context, ...transformedItem };
|
|
771
|
+
context = { ...context, ...transformedItem, ...userData.finalData };
|
|
819
772
|
|
|
820
773
|
// If a primary key field is defined, handle the ID mapping and check for duplicates
|
|
821
774
|
if (importDef.primaryKeyField) {
|