appwrite-utils-cli 0.0.266 → 0.0.268

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
File without changes
@@ -148,18 +148,18 @@ export const createOrUpdateCollections = async (database, databaseId, config, de
148
148
  const foundColl = deletedCollections.find((coll) => coll.collectionName.toLowerCase().trim().replace(" ", "") ===
149
149
  collection.name.toLowerCase().trim().replace(" ", ""));
150
150
  if (foundColl) {
151
- const collectionId = foundColl.collectionId || ID.unique();
151
+ const collectionId = collection.$id || foundColl.collectionId || ID.unique();
152
152
  console.log(`Processing collection: ${collection.name} with ID: ${collectionId}`);
153
153
  collectionToUse = await database.createCollection(databaseId, collectionId, collection.name, permissions, collection.documentSecurity, collection.enabled);
154
154
  nameToIdMapping.set(collection.name, collectionToUse.$id);
155
155
  }
156
156
  else {
157
- collectionToUse = await database.createCollection(databaseId, ID.unique(), collection.name, permissions, collection.documentSecurity, collection.enabled);
157
+ collectionToUse = await database.createCollection(databaseId, collection.$id || ID.unique(), collection.name, permissions, collection.documentSecurity, collection.enabled);
158
158
  nameToIdMapping.set(collection.name, collectionToUse.$id);
159
159
  }
160
160
  }
161
161
  else {
162
- collectionToUse = await database.createCollection(databaseId, ID.unique(), collection.name, permissions, collection.documentSecurity, collection.enabled);
162
+ collectionToUse = await database.createCollection(databaseId, collection.$id || ID.unique(), collection.name, permissions, collection.documentSecurity, collection.enabled);
163
163
  nameToIdMapping.set(collection.name, collectionToUse.$id);
164
164
  }
165
165
  }
@@ -1589,6 +1589,8 @@ export declare class DataLoader {
1589
1589
  setupMaps(dbId: string): Promise<void>;
1590
1590
  getAllUsers(): Promise<import("node-appwrite").Models.User<import("node-appwrite").Models.Preferences>[]>;
1591
1591
  start(dbId: string): Promise<void>;
1592
+ dealWithMergedUsers(): Promise<void>;
1593
+ updateOldReferencesForNew(): Promise<void>;
1592
1594
  updateReferencesInRelatedCollections(): Promise<void>;
1593
1595
  findNewIdForOldId(oldId: string, idMapping: IdMapping, importDef: ImportDef): any;
1594
1596
  private writeMapsToJsonFile;
@@ -252,7 +252,8 @@ export class DataLoader {
252
252
  }
253
253
  }
254
254
  console.log("Running update references");
255
- await this.updateReferencesInRelatedCollections();
255
+ await this.dealWithMergedUsers();
256
+ await this.updateOldReferencesForNew();
256
257
  console.log("Done running update references");
257
258
  }
258
259
  // for (const collection of this.config.collections) {
@@ -265,6 +266,99 @@ export class DataLoader {
265
266
  this.writeMapsToJsonFile();
266
267
  }
267
268
  }
269
+ async dealWithMergedUsers() {
270
+ const usersCollectionKey = this.getCollectionKey(this.config.usersCollectionName);
271
+ const usersCollectionPrimaryKeyFields = new Set();
272
+ // Collect primary key fields from the users collection definitions
273
+ this.config.collections.forEach((collection) => {
274
+ if (this.getCollectionKey(collection.name) === usersCollectionKey) {
275
+ collection.importDefs.forEach((importDef) => {
276
+ if (importDef.primaryKeyField) {
277
+ usersCollectionPrimaryKeyFields.add(importDef.primaryKeyField);
278
+ }
279
+ });
280
+ }
281
+ });
282
+ // Iterate over all collections to update references based on merged users
283
+ this.config.collections.forEach((collection) => {
284
+ const collectionData = this.importMap.get(this.getCollectionKey(collection.name));
285
+ if (!collectionData || !collectionData.data)
286
+ return;
287
+ collection.importDefs.forEach((importDef) => {
288
+ importDef.idMappings?.forEach((idMapping) => {
289
+ if (this.getCollectionKey(idMapping.targetCollection) ===
290
+ usersCollectionKey) {
291
+ if (usersCollectionPrimaryKeyFields.has(idMapping.targetField)) {
292
+ // Process each item in the collection
293
+ collectionData.data.forEach((item) => {
294
+ const oldId = item.context[idMapping.sourceField];
295
+ const newId = this.mergedUserMap.get(oldId);
296
+ if (newId) {
297
+ // Update context to use new user ID
298
+ item.context[idMapping.fieldToSet || idMapping.targetField] =
299
+ newId;
300
+ }
301
+ });
302
+ }
303
+ }
304
+ });
305
+ });
306
+ });
307
+ }
308
+ async updateOldReferencesForNew() {
309
+ for (const collectionConfig of this.config.collections) {
310
+ const collectionKey = this.getCollectionKey(collectionConfig.name);
311
+ const collectionData = this.importMap.get(collectionKey);
312
+ if (!collectionData || !collectionData.data)
313
+ continue;
314
+ console.log(`Updating references for collection: ${collectionConfig.name}`);
315
+ let needsUpdate = false;
316
+ // Iterate over each data item in the current collection
317
+ for (let i = 0; i < collectionData.data.length; i++) {
318
+ if (collectionConfig.importDefs) {
319
+ for (const importDef of collectionConfig.importDefs) {
320
+ if (importDef.idMappings) {
321
+ for (const idMapping of importDef.idMappings) {
322
+ const targetCollectionKey = this.getCollectionKey(idMapping.targetCollection);
323
+ const fieldToSetKey = idMapping.fieldToSet || idMapping.sourceField;
324
+ const valueToMatch = collectionData.data[i].context[idMapping.sourceField];
325
+ if (!valueToMatch || _.isEmpty(valueToMatch))
326
+ continue;
327
+ const targetCollectionData = this.importMap.get(targetCollectionKey);
328
+ if (!targetCollectionData || !targetCollectionData.data)
329
+ continue;
330
+ const foundData = targetCollectionData.data.filter((data) => {
331
+ const targetValue = data.context[idMapping.targetField];
332
+ const isMatch = `${targetValue}` === `${valueToMatch}`;
333
+ // Debugging output to understand what's being compared
334
+ logger.warn(`Comparing target: ${targetValue} with match: ${valueToMatch} - Result: ${isMatch}`);
335
+ return isMatch;
336
+ });
337
+ if (!foundData.length) {
338
+ console.log(`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey}`);
339
+ logger.error(`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(idMapping, null, 2)}`);
340
+ continue;
341
+ }
342
+ needsUpdate = true;
343
+ // Properly handle arrays and non-arrays
344
+ if (Array.isArray(collectionData.data[i].finalData[fieldToSetKey])) {
345
+ collectionData.data[i].finalData[fieldToSetKey] =
346
+ foundData.map((data) => data.finalData);
347
+ }
348
+ else {
349
+ collectionData.data[i].finalData[fieldToSetKey] =
350
+ foundData[0].finalData;
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ if (needsUpdate) {
358
+ this.importMap.set(collectionKey, collectionData);
359
+ }
360
+ }
361
+ }
268
362
  async updateReferencesInRelatedCollections() {
269
363
  // Iterate over each collection configuration
270
364
  for (const collectionConfig of this.config.collections) {
@@ -289,7 +383,8 @@ export class DataLoader {
289
383
  oldIds.forEach((oldId) => {
290
384
  // Attempt to find a new ID for the old ID
291
385
  let newIdForOldId = this.findNewIdForOldId(oldId, idMapping, importDef);
292
- if (newIdForOldId && !resolvedNewIds.includes(newIdForOldId)) {
386
+ if (newIdForOldId &&
387
+ !resolvedNewIds.includes(newIdForOldId)) {
293
388
  resolvedNewIds.push(newIdForOldId);
294
389
  }
295
390
  else {
@@ -298,9 +393,11 @@ export class DataLoader {
298
393
  });
299
394
  if (resolvedNewIds.length) {
300
395
  const targetField = idMapping.fieldToSet || idMapping.targetField;
301
- const isArray = collectionConfig.attributes.some(attribute => attribute.key === targetField && attribute.array);
396
+ const isArray = collectionConfig.attributes.some((attribute) => attribute.key === targetField && attribute.array);
302
397
  // Set the target field based on whether it's an array or single value
303
- item.finalData[targetField] = isArray ? resolvedNewIds : resolvedNewIds[0];
398
+ item.finalData[targetField] = isArray
399
+ ? resolvedNewIds
400
+ : resolvedNewIds[0];
304
401
  needsUpdate = true;
305
402
  }
306
403
  }
@@ -318,7 +415,8 @@ export class DataLoader {
318
415
  findNewIdForOldId(oldId, idMapping, importDef) {
319
416
  // First, check if this ID mapping is related to the users collection.
320
417
  const targetCollectionKey = this.getCollectionKey(idMapping.targetCollection);
321
- const isUsersCollection = targetCollectionKey === this.getCollectionKey(this.config.usersCollectionName);
418
+ const isUsersCollection = targetCollectionKey ===
419
+ this.getCollectionKey(this.config.usersCollectionName);
322
420
  // If handling users, check the mergedUserMap for any existing new ID.
323
421
  if (isUsersCollection) {
324
422
  for (const [newUserId, oldIds] of this.mergedUserMap.entries()) {
@@ -330,7 +428,7 @@ export class DataLoader {
330
428
  // If not a user or no merged ID found, check the regular ID mapping from old to new.
331
429
  const targetCollectionData = this.importMap.get(targetCollectionKey);
332
430
  if (targetCollectionData) {
333
- const foundEntry = targetCollectionData.data.find(entry => entry.context[importDef.primaryKeyField] === oldId);
431
+ const foundEntry = targetCollectionData.data.find((entry) => entry.context[importDef.primaryKeyField] === oldId);
334
432
  if (foundEntry) {
335
433
  return foundEntry.context.docId; // Assuming `docId` stores the new ID after import
336
434
  }
package/dist/setup.js CHANGED
File without changes
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.266",
4
+ "version": "0.0.268",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -198,7 +198,8 @@ export const createOrUpdateCollections = async (
198
198
  collection.name.toLowerCase().trim().replace(" ", "")
199
199
  );
200
200
  if (foundColl) {
201
- const collectionId = foundColl.collectionId || ID.unique();
201
+ const collectionId =
202
+ collection.$id || foundColl.collectionId || ID.unique();
202
203
  console.log(
203
204
  `Processing collection: ${collection.name} with ID: ${collectionId}`
204
205
  );
@@ -214,7 +215,7 @@ export const createOrUpdateCollections = async (
214
215
  } else {
215
216
  collectionToUse = await database.createCollection(
216
217
  databaseId,
217
- ID.unique(),
218
+ collection.$id || ID.unique(),
218
219
  collection.name,
219
220
  permissions,
220
221
  collection.documentSecurity,
@@ -225,7 +226,7 @@ export const createOrUpdateCollections = async (
225
226
  } else {
226
227
  collectionToUse = await database.createCollection(
227
228
  databaseId,
228
- ID.unique(),
229
+ collection.$id || ID.unique(),
229
230
  collection.name,
230
231
  permissions,
231
232
  collection.documentSecurity,
@@ -325,7 +325,8 @@ export class DataLoader {
325
325
  }
326
326
  }
327
327
  console.log("Running update references");
328
- await this.updateReferencesInRelatedCollections();
328
+ await this.dealWithMergedUsers();
329
+ await this.updateOldReferencesForNew();
329
330
  console.log("Done running update references");
330
331
  }
331
332
  // for (const collection of this.config.collections) {
@@ -339,98 +340,250 @@ export class DataLoader {
339
340
  }
340
341
  }
341
342
 
343
+ async dealWithMergedUsers() {
344
+ const usersCollectionKey = this.getCollectionKey(
345
+ this.config.usersCollectionName
346
+ );
347
+ const usersCollectionPrimaryKeyFields = new Set();
348
+
349
+ // Collect primary key fields from the users collection definitions
350
+ this.config.collections.forEach((collection) => {
351
+ if (this.getCollectionKey(collection.name) === usersCollectionKey) {
352
+ collection.importDefs.forEach((importDef) => {
353
+ if (importDef.primaryKeyField) {
354
+ usersCollectionPrimaryKeyFields.add(importDef.primaryKeyField);
355
+ }
356
+ });
357
+ }
358
+ });
359
+
360
+ // Iterate over all collections to update references based on merged users
361
+ this.config.collections.forEach((collection) => {
362
+ const collectionData = this.importMap.get(
363
+ this.getCollectionKey(collection.name)
364
+ );
365
+ if (!collectionData || !collectionData.data) return;
366
+
367
+ collection.importDefs.forEach((importDef) => {
368
+ importDef.idMappings?.forEach((idMapping) => {
369
+ if (
370
+ this.getCollectionKey(idMapping.targetCollection) ===
371
+ usersCollectionKey
372
+ ) {
373
+ if (usersCollectionPrimaryKeyFields.has(idMapping.targetField)) {
374
+ // Process each item in the collection
375
+ collectionData.data.forEach((item) => {
376
+ const oldId = item.context[idMapping.sourceField];
377
+ const newId = this.mergedUserMap.get(oldId);
378
+
379
+ if (newId) {
380
+ // Update context to use new user ID
381
+ item.context[idMapping.fieldToSet || idMapping.targetField] =
382
+ newId;
383
+ }
384
+ });
385
+ }
386
+ }
387
+ });
388
+ });
389
+ });
390
+ }
391
+
392
+ async updateOldReferencesForNew() {
393
+ for (const collectionConfig of this.config.collections) {
394
+ const collectionKey = this.getCollectionKey(collectionConfig.name);
395
+ const collectionData = this.importMap.get(collectionKey);
396
+
397
+ if (!collectionData || !collectionData.data) continue;
398
+
399
+ console.log(
400
+ `Updating references for collection: ${collectionConfig.name}`
401
+ );
402
+
403
+ let needsUpdate = false;
404
+
405
+ // Iterate over each data item in the current collection
406
+ for (let i = 0; i < collectionData.data.length; i++) {
407
+ if (collectionConfig.importDefs) {
408
+ for (const importDef of collectionConfig.importDefs) {
409
+ if (importDef.idMappings) {
410
+ for (const idMapping of importDef.idMappings) {
411
+ const targetCollectionKey = this.getCollectionKey(
412
+ idMapping.targetCollection
413
+ );
414
+ const fieldToSetKey =
415
+ idMapping.fieldToSet || idMapping.sourceField;
416
+ const valueToMatch =
417
+ collectionData.data[i].context[idMapping.sourceField];
418
+
419
+ if (!valueToMatch || _.isEmpty(valueToMatch)) continue;
420
+
421
+ const targetCollectionData =
422
+ this.importMap.get(targetCollectionKey);
423
+ if (!targetCollectionData || !targetCollectionData.data)
424
+ continue;
425
+
426
+ const foundData = targetCollectionData.data.filter((data) => {
427
+ const targetValue = data.context[idMapping.targetField];
428
+ const isMatch = `${targetValue}` === `${valueToMatch}`;
429
+ // Debugging output to understand what's being compared
430
+ logger.warn(
431
+ `Comparing target: ${targetValue} with match: ${valueToMatch} - Result: ${isMatch}`
432
+ );
433
+ return isMatch;
434
+ });
435
+
436
+ if (!foundData.length) {
437
+ console.log(
438
+ `No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey}`
439
+ );
440
+ logger.error(
441
+ `No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(
442
+ idMapping,
443
+ null,
444
+ 2
445
+ )}`
446
+ );
447
+ continue;
448
+ }
449
+
450
+ needsUpdate = true;
451
+
452
+ // Properly handle arrays and non-arrays
453
+ if (
454
+ Array.isArray(collectionData.data[i].finalData[fieldToSetKey])
455
+ ) {
456
+ collectionData.data[i].finalData[fieldToSetKey] =
457
+ foundData.map((data) => data.finalData);
458
+ } else {
459
+ collectionData.data[i].finalData[fieldToSetKey] =
460
+ foundData[0].finalData;
461
+ }
462
+ }
463
+ }
464
+ }
465
+ }
466
+ }
467
+
468
+ if (needsUpdate) {
469
+ this.importMap.set(collectionKey, collectionData);
470
+ }
471
+ }
472
+ }
473
+
342
474
  async updateReferencesInRelatedCollections() {
343
475
  // Iterate over each collection configuration
344
476
  for (const collectionConfig of this.config.collections) {
345
- const collectionKey = this.getCollectionKey(collectionConfig.name);
346
- const collectionData = this.importMap.get(collectionKey);
347
-
348
- if (!collectionData || !collectionData.data) continue;
349
-
350
- console.log(`Updating references for collection: ${collectionConfig.name}`);
351
-
352
- // Iterate over each data item in the current collection
353
- for (const item of collectionData.data) {
354
- let needsUpdate = false;
355
-
356
- // Check if the current collection has import definitions with idMappings
357
- if (collectionConfig.importDefs) {
358
- for (const importDef of collectionConfig.importDefs) {
359
- if (importDef.idMappings) {
360
- // Iterate over each idMapping defined for the current import definition
361
- for (const idMapping of importDef.idMappings) {
362
- const oldIds = Array.isArray(item.context[idMapping.sourceField])
363
- ? item.context[idMapping.sourceField]
364
- : [item.context[idMapping.sourceField]];
365
- const resolvedNewIds: string[] = [];
366
-
367
- oldIds.forEach((oldId: any) => {
368
- // Attempt to find a new ID for the old ID
369
- let newIdForOldId = this.findNewIdForOldId(
370
- oldId,
371
- idMapping,
372
- importDef
373
- );
374
-
375
- if (newIdForOldId && !resolvedNewIds.includes(newIdForOldId)) {
376
- resolvedNewIds.push(newIdForOldId);
377
- } else {
378
- logger.error(`No new ID found for old ID ${oldId} in collection ${collectionConfig.name}`);
379
- }
380
- });
381
-
382
- if (resolvedNewIds.length) {
383
- const targetField = idMapping.fieldToSet || idMapping.targetField;
384
- const isArray = collectionConfig.attributes.some(
385
- attribute => attribute.key === targetField && attribute.array
386
- );
387
-
388
- // Set the target field based on whether it's an array or single value
389
- item.finalData[targetField] = isArray ? resolvedNewIds : resolvedNewIds[0];
390
- needsUpdate = true;
391
- }
392
- }
393
- }
477
+ const collectionKey = this.getCollectionKey(collectionConfig.name);
478
+ const collectionData = this.importMap.get(collectionKey);
479
+
480
+ if (!collectionData || !collectionData.data) continue;
481
+
482
+ console.log(
483
+ `Updating references for collection: ${collectionConfig.name}`
484
+ );
485
+
486
+ // Iterate over each data item in the current collection
487
+ for (const item of collectionData.data) {
488
+ let needsUpdate = false;
489
+
490
+ // Check if the current collection has import definitions with idMappings
491
+ if (collectionConfig.importDefs) {
492
+ for (const importDef of collectionConfig.importDefs) {
493
+ if (importDef.idMappings) {
494
+ // Iterate over each idMapping defined for the current import definition
495
+ for (const idMapping of importDef.idMappings) {
496
+ const oldIds = Array.isArray(
497
+ item.context[idMapping.sourceField]
498
+ )
499
+ ? item.context[idMapping.sourceField]
500
+ : [item.context[idMapping.sourceField]];
501
+ const resolvedNewIds: string[] = [];
502
+
503
+ oldIds.forEach((oldId: any) => {
504
+ // Attempt to find a new ID for the old ID
505
+ let newIdForOldId = this.findNewIdForOldId(
506
+ oldId,
507
+ idMapping,
508
+ importDef
509
+ );
510
+
511
+ if (
512
+ newIdForOldId &&
513
+ !resolvedNewIds.includes(newIdForOldId)
514
+ ) {
515
+ resolvedNewIds.push(newIdForOldId);
516
+ } else {
517
+ logger.error(
518
+ `No new ID found for old ID ${oldId} in collection ${collectionConfig.name}`
519
+ );
520
+ }
521
+ });
522
+
523
+ if (resolvedNewIds.length) {
524
+ const targetField =
525
+ idMapping.fieldToSet || idMapping.targetField;
526
+ const isArray = collectionConfig.attributes.some(
527
+ (attribute) =>
528
+ attribute.key === targetField && attribute.array
529
+ );
530
+
531
+ // Set the target field based on whether it's an array or single value
532
+ item.finalData[targetField] = isArray
533
+ ? resolvedNewIds
534
+ : resolvedNewIds[0];
535
+ needsUpdate = true;
394
536
  }
537
+ }
395
538
  }
539
+ }
540
+ }
396
541
 
397
- // Update the importMap if changes were made to the item
398
- if (needsUpdate) {
399
- this.importMap.set(collectionKey, collectionData);
400
- logger.info(`Updated item: ${JSON.stringify(item.finalData, undefined, 2)}`);
401
- }
542
+ // Update the importMap if changes were made to the item
543
+ if (needsUpdate) {
544
+ this.importMap.set(collectionKey, collectionData);
545
+ logger.info(
546
+ `Updated item: ${JSON.stringify(item.finalData, undefined, 2)}`
547
+ );
402
548
  }
549
+ }
403
550
  }
404
- }
551
+ }
405
552
 
406
- findNewIdForOldId(oldId: string, idMapping: IdMapping, importDef: ImportDef) {
407
- // First, check if this ID mapping is related to the users collection.
408
- const targetCollectionKey = this.getCollectionKey(idMapping.targetCollection);
409
- const isUsersCollection = targetCollectionKey === this.getCollectionKey(this.config.usersCollectionName);
553
+ findNewIdForOldId(oldId: string, idMapping: IdMapping, importDef: ImportDef) {
554
+ // First, check if this ID mapping is related to the users collection.
555
+ const targetCollectionKey = this.getCollectionKey(
556
+ idMapping.targetCollection
557
+ );
558
+ const isUsersCollection =
559
+ targetCollectionKey ===
560
+ this.getCollectionKey(this.config.usersCollectionName);
410
561
 
411
- // If handling users, check the mergedUserMap for any existing new ID.
412
- if (isUsersCollection) {
562
+ // If handling users, check the mergedUserMap for any existing new ID.
563
+ if (isUsersCollection) {
413
564
  for (const [newUserId, oldIds] of this.mergedUserMap.entries()) {
414
- if (oldIds.includes(oldId)) {
415
- return newUserId;
416
- }
565
+ if (oldIds.includes(oldId)) {
566
+ return newUserId;
567
+ }
417
568
  }
418
- }
569
+ }
419
570
 
420
- // If not a user or no merged ID found, check the regular ID mapping from old to new.
421
- const targetCollectionData = this.importMap.get(targetCollectionKey);
422
- if (targetCollectionData) {
423
- const foundEntry = targetCollectionData.data.find(entry => entry.context[importDef.primaryKeyField] === oldId);
571
+ // If not a user or no merged ID found, check the regular ID mapping from old to new.
572
+ const targetCollectionData = this.importMap.get(targetCollectionKey);
573
+ if (targetCollectionData) {
574
+ const foundEntry = targetCollectionData.data.find(
575
+ (entry) => entry.context[importDef.primaryKeyField] === oldId
576
+ );
424
577
  if (foundEntry) {
425
- return foundEntry.context.docId; // Assuming `docId` stores the new ID after import
578
+ return foundEntry.context.docId; // Assuming `docId` stores the new ID after import
426
579
  }
427
- }
428
-
429
- logger.error(`No corresponding new ID found for ${oldId} in ${targetCollectionKey}`);
430
- return null; // Return null if no new ID is found
431
- }
432
-
580
+ }
433
581
 
582
+ logger.error(
583
+ `No corresponding new ID found for ${oldId} in ${targetCollectionKey}`
584
+ );
585
+ return null; // Return null if no new ID is found
586
+ }
434
587
 
435
588
  private writeMapsToJsonFile() {
436
589
  const outputDir = path.resolve(process.cwd());