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.
- package/CHANGELOG.md +14 -199
- package/README.md +87 -30
- package/dist/adapters/AdapterFactory.js +5 -25
- package/dist/adapters/DatabaseAdapter.d.ts +17 -2
- package/dist/adapters/LegacyAdapter.d.ts +2 -1
- package/dist/adapters/LegacyAdapter.js +212 -16
- package/dist/adapters/TablesDBAdapter.d.ts +2 -12
- package/dist/adapters/TablesDBAdapter.js +261 -57
- package/dist/cli/commands/databaseCommands.js +4 -3
- package/dist/cli/commands/functionCommands.js +17 -8
- package/dist/collections/attributes.js +447 -125
- package/dist/collections/methods.js +197 -186
- package/dist/collections/tableOperations.d.ts +86 -0
- package/dist/collections/tableOperations.js +434 -0
- package/dist/collections/transferOperations.d.ts +3 -2
- package/dist/collections/transferOperations.js +93 -12
- package/dist/config/yamlConfig.d.ts +221 -88
- package/dist/examples/yamlTerminologyExample.d.ts +1 -1
- package/dist/examples/yamlTerminologyExample.js +6 -3
- package/dist/functions/fnConfigDiscovery.d.ts +3 -0
- package/dist/functions/fnConfigDiscovery.js +108 -0
- package/dist/interactiveCLI.js +18 -15
- package/dist/main.js +211 -73
- package/dist/migrations/appwriteToX.d.ts +88 -23
- package/dist/migrations/comprehensiveTransfer.d.ts +2 -0
- package/dist/migrations/comprehensiveTransfer.js +83 -6
- package/dist/migrations/dataLoader.d.ts +227 -69
- package/dist/migrations/dataLoader.js +3 -3
- package/dist/migrations/importController.js +3 -3
- package/dist/migrations/relationships.d.ts +8 -2
- package/dist/migrations/services/ImportOrchestrator.js +3 -3
- package/dist/migrations/transfer.js +159 -37
- package/dist/shared/attributeMapper.d.ts +20 -0
- package/dist/shared/attributeMapper.js +203 -0
- package/dist/shared/selectionDialogs.js +8 -4
- package/dist/storage/schemas.d.ts +354 -92
- package/dist/utils/configDiscovery.js +4 -3
- package/dist/utils/versionDetection.d.ts +0 -4
- package/dist/utils/versionDetection.js +41 -173
- package/dist/utils/yamlConverter.js +89 -16
- package/dist/utils/yamlLoader.d.ts +1 -1
- package/dist/utils/yamlLoader.js +6 -2
- package/dist/utilsController.js +56 -19
- package/package.json +4 -4
- package/src/adapters/AdapterFactory.ts +119 -143
- package/src/adapters/DatabaseAdapter.ts +18 -3
- package/src/adapters/LegacyAdapter.ts +236 -105
- package/src/adapters/TablesDBAdapter.ts +773 -643
- package/src/cli/commands/databaseCommands.ts +13 -12
- package/src/cli/commands/functionCommands.ts +23 -14
- package/src/collections/attributes.ts +2054 -1611
- package/src/collections/methods.ts +208 -293
- package/src/collections/tableOperations.ts +506 -0
- package/src/collections/transferOperations.ts +218 -144
- package/src/examples/yamlTerminologyExample.ts +10 -5
- package/src/functions/fnConfigDiscovery.ts +103 -0
- package/src/interactiveCLI.ts +25 -20
- package/src/main.ts +549 -194
- package/src/migrations/comprehensiveTransfer.ts +126 -50
- package/src/migrations/dataLoader.ts +3 -3
- package/src/migrations/importController.ts +3 -3
- package/src/migrations/services/ImportOrchestrator.ts +3 -3
- package/src/migrations/transfer.ts +148 -131
- package/src/shared/attributeMapper.ts +229 -0
- package/src/shared/selectionDialogs.ts +29 -25
- package/src/utils/configDiscovery.ts +9 -3
- package/src/utils/versionDetection.ts +74 -228
- package/src/utils/yamlConverter.ts +94 -17
- package/src/utils/yamlLoader.ts +11 -4
- 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:
|
|
42
|
+
private databases: Databases;
|
|
43
43
|
|
|
44
|
-
constructor(client:
|
|
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
|
-
//
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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
|
+
}
|