appwrite-utils-cli 1.7.9 → 1.8.1

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +14 -199
  2. package/README.md +87 -30
  3. package/dist/adapters/AdapterFactory.js +5 -25
  4. package/dist/adapters/DatabaseAdapter.d.ts +17 -2
  5. package/dist/adapters/LegacyAdapter.d.ts +2 -1
  6. package/dist/adapters/LegacyAdapter.js +212 -16
  7. package/dist/adapters/TablesDBAdapter.d.ts +2 -12
  8. package/dist/adapters/TablesDBAdapter.js +261 -57
  9. package/dist/cli/commands/databaseCommands.js +4 -3
  10. package/dist/cli/commands/functionCommands.js +17 -8
  11. package/dist/collections/attributes.js +447 -125
  12. package/dist/collections/methods.js +197 -186
  13. package/dist/collections/tableOperations.d.ts +86 -0
  14. package/dist/collections/tableOperations.js +434 -0
  15. package/dist/collections/transferOperations.d.ts +3 -2
  16. package/dist/collections/transferOperations.js +93 -12
  17. package/dist/config/yamlConfig.d.ts +221 -88
  18. package/dist/examples/yamlTerminologyExample.d.ts +1 -1
  19. package/dist/examples/yamlTerminologyExample.js +6 -3
  20. package/dist/functions/fnConfigDiscovery.d.ts +3 -0
  21. package/dist/functions/fnConfigDiscovery.js +108 -0
  22. package/dist/interactiveCLI.js +18 -15
  23. package/dist/main.js +211 -73
  24. package/dist/migrations/appwriteToX.d.ts +88 -23
  25. package/dist/migrations/comprehensiveTransfer.d.ts +2 -0
  26. package/dist/migrations/comprehensiveTransfer.js +83 -6
  27. package/dist/migrations/dataLoader.d.ts +227 -69
  28. package/dist/migrations/dataLoader.js +3 -3
  29. package/dist/migrations/importController.js +3 -3
  30. package/dist/migrations/relationships.d.ts +8 -2
  31. package/dist/migrations/services/ImportOrchestrator.js +3 -3
  32. package/dist/migrations/transfer.js +159 -37
  33. package/dist/shared/attributeMapper.d.ts +20 -0
  34. package/dist/shared/attributeMapper.js +203 -0
  35. package/dist/shared/selectionDialogs.js +8 -4
  36. package/dist/storage/schemas.d.ts +354 -92
  37. package/dist/utils/configDiscovery.js +4 -3
  38. package/dist/utils/versionDetection.d.ts +0 -4
  39. package/dist/utils/versionDetection.js +41 -173
  40. package/dist/utils/yamlConverter.js +89 -16
  41. package/dist/utils/yamlLoader.d.ts +1 -1
  42. package/dist/utils/yamlLoader.js +6 -2
  43. package/dist/utilsController.js +56 -19
  44. package/package.json +4 -4
  45. package/src/adapters/AdapterFactory.ts +119 -143
  46. package/src/adapters/DatabaseAdapter.ts +18 -3
  47. package/src/adapters/LegacyAdapter.ts +236 -105
  48. package/src/adapters/TablesDBAdapter.ts +773 -643
  49. package/src/cli/commands/databaseCommands.ts +13 -12
  50. package/src/cli/commands/functionCommands.ts +23 -14
  51. package/src/collections/attributes.ts +2054 -1611
  52. package/src/collections/methods.ts +208 -293
  53. package/src/collections/tableOperations.ts +506 -0
  54. package/src/collections/transferOperations.ts +218 -144
  55. package/src/examples/yamlTerminologyExample.ts +10 -5
  56. package/src/functions/fnConfigDiscovery.ts +103 -0
  57. package/src/interactiveCLI.ts +25 -20
  58. package/src/main.ts +549 -194
  59. package/src/migrations/comprehensiveTransfer.ts +126 -50
  60. package/src/migrations/dataLoader.ts +3 -3
  61. package/src/migrations/importController.ts +3 -3
  62. package/src/migrations/services/ImportOrchestrator.ts +3 -3
  63. package/src/migrations/transfer.ts +148 -131
  64. package/src/shared/attributeMapper.ts +229 -0
  65. package/src/shared/selectionDialogs.ts +29 -25
  66. package/src/utils/configDiscovery.ts +9 -3
  67. package/src/utils/versionDetection.ts +74 -228
  68. package/src/utils/yamlConverter.ts +94 -17
  69. package/src/utils/yamlLoader.ts +11 -4
  70. package/src/utilsController.ts +80 -30
@@ -7,7 +7,7 @@
7
7
  * older Appwrite instances.
8
8
  */
9
9
 
10
- import { Query } from "node-appwrite";
10
+ import { Client, Databases, IndexType, Query, type Models, RelationshipType, RelationMutate } from "node-appwrite";
11
11
  import { chunk } from "es-toolkit";
12
12
  import {
13
13
  BaseAdapter,
@@ -39,12 +39,12 @@ import {
39
39
  * LegacyAdapter - Translates TablesDB calls to legacy Databases API
40
40
  */
41
41
  export class LegacyAdapter extends BaseAdapter {
42
- private databases: any;
42
+ private databases: Databases;
43
43
 
44
- constructor(client: any) {
44
+ constructor(client: Client) {
45
45
  super(client, 'legacy');
46
46
  // Assuming Databases service is available on the client
47
- this.databases = client;
47
+ this.databases = new Databases(client);
48
48
  }
49
49
 
50
50
  // Row (Document) Operations - Translate object notation to positional parameters
@@ -325,7 +325,7 @@ export class LegacyAdapter extends BaseAdapter {
325
325
  params.databaseId,
326
326
  params.tableId,
327
327
  params.key,
328
- params.type,
328
+ params.type as IndexType,
329
329
  params.attributes,
330
330
  params.orders || []
331
331
  );
@@ -369,122 +369,122 @@ export class LegacyAdapter extends BaseAdapter {
369
369
 
370
370
  switch (params.type.toLowerCase()) {
371
371
  case 'string':
372
- result = await this.databases.createStringAttribute(
373
- params.databaseId,
374
- params.tableId,
375
- params.key,
376
- params.size || 255,
377
- params.required ?? false,
378
- params.default,
379
- params.array ?? false,
380
- params.encrypt ?? false
381
- );
372
+ result = await this.databases.createStringAttribute({
373
+ databaseId: params.databaseId,
374
+ collectionId: params.tableId,
375
+ key: params.key,
376
+ size: params.size || 255,
377
+ required: params.required ?? false,
378
+ xdefault: params.default,
379
+ array: params.array ?? false,
380
+ encrypt: params.encrypt ?? false
381
+ });
382
382
  break;
383
383
 
384
384
  case 'integer':
385
- result = await this.databases.createIntegerAttribute(
386
- params.databaseId,
387
- params.tableId,
388
- params.key,
389
- params.required ?? false,
390
- params.min,
391
- params.max,
392
- params.default,
393
- params.array ?? false
394
- );
385
+ result = await this.databases.createIntegerAttribute({
386
+ databaseId: params.databaseId,
387
+ collectionId: params.tableId,
388
+ key: params.key,
389
+ required: params.required ?? false,
390
+ min: params.min,
391
+ max: params.max,
392
+ xdefault: params.default,
393
+ array: params.array ?? false
394
+ });
395
395
  break;
396
396
 
397
397
  case 'float':
398
398
  case 'double':
399
- result = await this.databases.createFloatAttribute(
400
- params.databaseId,
401
- params.tableId,
402
- params.key,
403
- params.required ?? false,
404
- params.min,
405
- params.max,
406
- params.default,
407
- params.array ?? false
408
- );
399
+ result = await this.databases.createFloatAttribute({
400
+ databaseId: params.databaseId,
401
+ collectionId: params.tableId,
402
+ key: params.key,
403
+ required: params.required ?? false,
404
+ min: params.min,
405
+ max: params.max,
406
+ xdefault: params.default,
407
+ array: params.array ?? false
408
+ });
409
409
  break;
410
410
 
411
411
  case 'boolean':
412
- result = await this.databases.createBooleanAttribute(
413
- params.databaseId,
414
- params.tableId,
415
- params.key,
416
- params.required ?? false,
417
- params.default,
418
- params.array ?? false
419
- );
412
+ result = await this.databases.createBooleanAttribute({
413
+ databaseId: params.databaseId,
414
+ collectionId: params.tableId,
415
+ key: params.key,
416
+ required: params.required ?? false,
417
+ xdefault: params.default,
418
+ array: params.array ?? false
419
+ });
420
420
  break;
421
421
 
422
422
  case 'datetime':
423
- result = await this.databases.createDatetimeAttribute(
424
- params.databaseId,
425
- params.tableId,
426
- params.key,
427
- params.required ?? false,
428
- params.default,
429
- params.array ?? false
430
- );
423
+ result = await this.databases.createDatetimeAttribute({
424
+ databaseId: params.databaseId,
425
+ collectionId: params.tableId,
426
+ key: params.key,
427
+ required: params.required ?? false,
428
+ xdefault: params.default,
429
+ array: params.array ?? false
430
+ });
431
431
  break;
432
432
 
433
433
  case 'email':
434
- result = await this.databases.createEmailAttribute(
435
- params.databaseId,
436
- params.tableId,
437
- params.key,
438
- params.required ?? false,
439
- params.default,
440
- params.array ?? false
441
- );
434
+ result = await this.databases.createEmailAttribute({
435
+ databaseId: params.databaseId,
436
+ collectionId: params.tableId,
437
+ key: params.key,
438
+ required: params.required ?? false,
439
+ xdefault: params.default,
440
+ array: params.array ?? false
441
+ });
442
442
  break;
443
443
 
444
444
  case 'enum':
445
- result = await this.databases.createEnumAttribute(
446
- params.databaseId,
447
- params.tableId,
448
- params.key,
449
- params.elements || [],
450
- params.required ?? false,
451
- params.default,
452
- params.array ?? false
453
- );
445
+ result = await this.databases.createEnumAttribute({
446
+ databaseId: params.databaseId,
447
+ collectionId: params.tableId,
448
+ key: params.key,
449
+ elements: params.elements || [],
450
+ required: params.required ?? false,
451
+ xdefault: params.default,
452
+ array: params.array ?? false
453
+ });
454
454
  break;
455
455
 
456
456
  case 'ip':
457
- result = await this.databases.createIpAttribute(
458
- params.databaseId,
459
- params.tableId,
460
- params.key,
461
- params.required ?? false,
462
- params.default,
463
- params.array ?? false
464
- );
457
+ result = await this.databases.createIpAttribute({
458
+ databaseId: params.databaseId,
459
+ collectionId: params.tableId,
460
+ key: params.key,
461
+ required: params.required ?? false,
462
+ xdefault: params.default,
463
+ array: params.array ?? false
464
+ });
465
465
  break;
466
466
 
467
467
  case 'url':
468
- result = await this.databases.createUrlAttribute(
469
- params.databaseId,
470
- params.tableId,
471
- params.key,
472
- params.required ?? false,
473
- params.default,
474
- params.array ?? false
475
- );
468
+ result = await this.databases.createUrlAttribute({
469
+ databaseId: params.databaseId,
470
+ collectionId: params.tableId,
471
+ key: params.key,
472
+ required: params.required ?? false,
473
+ xdefault: params.default,
474
+ array: params.array ?? false
475
+ });
476
476
  break;
477
477
 
478
478
  case 'relationship':
479
- result = await this.databases.createRelationshipAttribute(
480
- params.databaseId,
481
- params.tableId,
482
- params.key,
483
- params.relatedCollection || '',
484
- params.type || 'oneToOne',
485
- params.twoWay ?? false,
486
- params.onDelete || 'restrict'
487
- );
479
+ result = await this.databases.createRelationshipAttribute({
480
+ databaseId: params.databaseId,
481
+ collectionId: params.tableId,
482
+ key: params.key,
483
+ relatedCollectionId: params.relatedCollection || '',
484
+ type: (params.type || 'oneToOne') as RelationshipType,
485
+ twoWay: params.twoWay ?? false,
486
+ onDelete: params.onDelete || 'restrict'
487
+ });
488
488
  break;
489
489
 
490
490
  default:
@@ -506,17 +506,148 @@ export class LegacyAdapter extends BaseAdapter {
506
506
 
507
507
  async updateAttribute(params: UpdateAttributeParams): Promise<ApiResponse> {
508
508
  try {
509
- // TablesDB: updateAttribute({ databaseId, tableId, key, required, default })
510
- // Legacy: updateStringAttribute, updateIntegerAttribute, etc.
511
- // Note: Legacy API has type-specific update methods
512
- const result = await this.databases.updateStringAttribute(
513
- params.databaseId,
514
- params.tableId,
515
- params.key,
516
- params.required ?? false,
517
- params.default
518
- );
519
-
509
+ // Get the current collection to determine the attribute type
510
+ const collection = await this.databases.getCollection(params.databaseId, params.tableId);
511
+ const existingAttr = collection.attributes.find((attr: any) => attr.key === params.key);
512
+
513
+ if (!existingAttr) {
514
+ throw new AdapterError(
515
+ `Attribute '${params.key}' not found in collection '${params.tableId}'`,
516
+ 'ATTRIBUTE_NOT_FOUND'
517
+ );
518
+ }
519
+
520
+ let result;
521
+ const attributeType = existingAttr.type.toLowerCase();
522
+
523
+ // Use type-specific update methods based on attribute type with object notation
524
+ switch (attributeType) {
525
+ case 'string':
526
+ const stringAttr = existingAttr as Models.AttributeString;
527
+ result = await this.databases.updateStringAttribute({
528
+ databaseId: params.databaseId,
529
+ collectionId: params.tableId,
530
+ key: params.key,
531
+ required: params.required ?? stringAttr.required,
532
+ xdefault: params.default !== undefined ? params.default : stringAttr.default,
533
+ size: stringAttr.size
534
+ });
535
+ break;
536
+
537
+ case 'integer':
538
+ const integerAttr = existingAttr as Models.AttributeInteger;
539
+ result = await this.databases.updateIntegerAttribute({
540
+ databaseId: params.databaseId,
541
+ collectionId: params.tableId,
542
+ key: params.key,
543
+ required: params.required ?? integerAttr.required,
544
+ xdefault: params.default !== undefined ? params.default : integerAttr.default,
545
+ // Only include when explicitly provided to avoid resubmitting extreme values
546
+ ...(params.min !== undefined ? { min: params.min } : {}),
547
+ ...(params.max !== undefined ? { max: params.max } : {}),
548
+ });
549
+ break;
550
+
551
+ case 'float':
552
+ case 'double':
553
+ const floatAttr = existingAttr as Models.AttributeFloat;
554
+ result = await this.databases.updateFloatAttribute({
555
+ databaseId: params.databaseId,
556
+ collectionId: params.tableId,
557
+ key: params.key,
558
+ required: params.required ?? floatAttr.required,
559
+ xdefault: params.default !== undefined ? params.default : floatAttr.default,
560
+ ...(params.min !== undefined ? { min: params.min } : {}),
561
+ ...(params.max !== undefined ? { max: params.max } : {}),
562
+ });
563
+ break;
564
+
565
+ case 'boolean':
566
+ const booleanAttr = existingAttr as Models.AttributeBoolean;
567
+ result = await this.databases.updateBooleanAttribute({
568
+ databaseId: params.databaseId,
569
+ collectionId: params.tableId,
570
+ key: params.key,
571
+ required: params.required ?? booleanAttr.required,
572
+ xdefault: params.default !== undefined ? params.default : booleanAttr.default
573
+ });
574
+ break;
575
+
576
+ case 'datetime':
577
+ const datetimeAttr = existingAttr as Models.AttributeDatetime;
578
+ result = await this.databases.updateDatetimeAttribute({
579
+ databaseId: params.databaseId,
580
+ collectionId: params.tableId,
581
+ key: params.key,
582
+ required: params.required ?? datetimeAttr.required,
583
+ xdefault: params.default !== undefined ? params.default : datetimeAttr.default
584
+ });
585
+ break;
586
+
587
+ case 'email':
588
+ const emailAttr = existingAttr as Models.AttributeEmail;
589
+ result = await this.databases.updateEmailAttribute({
590
+ databaseId: params.databaseId,
591
+ collectionId: params.tableId,
592
+ key: params.key,
593
+ required: params.required ?? emailAttr.required,
594
+ xdefault: params.default !== undefined ? params.default : emailAttr.default
595
+ });
596
+ break;
597
+
598
+ case 'enum':
599
+ const enumAttr = existingAttr as Models.AttributeEnum;
600
+ console.log('Updating enum attribute with params:', params);
601
+ result = await this.databases.updateEnumAttribute({
602
+ databaseId: params.databaseId,
603
+ collectionId: params.tableId,
604
+ key: params.key,
605
+ elements: enumAttr.elements || [],
606
+ required: params.required ?? enumAttr.required,
607
+ xdefault: params.default !== undefined ? params.default : enumAttr.default
608
+ });
609
+ break;
610
+
611
+ case 'ip':
612
+ const ipAttr = existingAttr as Models.AttributeIp;
613
+ result = await this.databases.updateIpAttribute({
614
+ databaseId: params.databaseId,
615
+ collectionId: params.tableId,
616
+ key: params.key,
617
+ required: params.required ?? ipAttr.required,
618
+ xdefault: params.default !== undefined ? params.default : ipAttr.default
619
+ });
620
+ break;
621
+
622
+ case 'url':
623
+ const urlAttr = existingAttr as Models.AttributeUrl;
624
+ result = await this.databases.updateUrlAttribute({
625
+ databaseId: params.databaseId,
626
+ collectionId: params.tableId,
627
+ key: params.key,
628
+ required: params.required ?? urlAttr.required,
629
+ xdefault: params.default !== undefined ? params.default : urlAttr.default
630
+ });
631
+ break;
632
+
633
+ case 'relationship':
634
+ // Relationship attributes have different update method signature
635
+ const relationshipAttr = existingAttr as Models.AttributeRelationship;
636
+ result = await this.databases.updateRelationshipAttribute({
637
+ databaseId: params.databaseId,
638
+ collectionId: params.tableId,
639
+ key: params.key,
640
+ onDelete: relationshipAttr.onDelete as RelationMutate
641
+ });
642
+ break;
643
+
644
+ default:
645
+ throw new AdapterError(
646
+ `Unsupported attribute type for update: ${attributeType}`,
647
+ 'UNSUPPORTED_ATTRIBUTE_TYPE'
648
+ );
649
+ }
650
+
520
651
  return { data: result };
521
652
  } catch (error) {
522
653
  throw new AdapterError(
@@ -707,4 +838,4 @@ async bulkDeleteRows(params: BulkDeleteRowsParams): Promise<ApiResponse> {
707
838
  };
708
839
  }
709
840
  }
710
- }
841
+ }