appwrite-utils-cli 1.7.8 → 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 (111) 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 +10 -10
  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/services/ConfigLoaderService.d.ts +7 -0
  18. package/dist/config/services/ConfigLoaderService.js +47 -1
  19. package/dist/config/yamlConfig.d.ts +221 -88
  20. package/dist/examples/yamlTerminologyExample.d.ts +1 -1
  21. package/dist/examples/yamlTerminologyExample.js +6 -3
  22. package/dist/functions/deployments.js +5 -23
  23. package/dist/functions/fnConfigDiscovery.d.ts +3 -0
  24. package/dist/functions/fnConfigDiscovery.js +108 -0
  25. package/dist/functions/methods.js +4 -2
  26. package/dist/functions/pathResolution.d.ts +37 -0
  27. package/dist/functions/pathResolution.js +185 -0
  28. package/dist/functions/templates/count-docs-in-collection/README.md +54 -0
  29. package/dist/functions/templates/count-docs-in-collection/package.json +25 -0
  30. package/dist/functions/templates/count-docs-in-collection/src/main.ts +159 -0
  31. package/dist/functions/templates/count-docs-in-collection/src/request.ts +9 -0
  32. package/dist/functions/templates/count-docs-in-collection/tsconfig.json +28 -0
  33. package/dist/functions/templates/hono-typescript/README.md +286 -0
  34. package/dist/functions/templates/hono-typescript/package.json +26 -0
  35. package/dist/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  36. package/dist/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  37. package/dist/functions/templates/hono-typescript/src/app.ts +180 -0
  38. package/dist/functions/templates/hono-typescript/src/context.ts +103 -0
  39. package/dist/functions/templates/hono-typescript/src/index.ts +54 -0
  40. package/dist/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  41. package/dist/functions/templates/hono-typescript/tsconfig.json +20 -0
  42. package/dist/functions/templates/typescript-node/README.md +32 -0
  43. package/dist/functions/templates/typescript-node/package.json +25 -0
  44. package/dist/functions/templates/typescript-node/src/context.ts +103 -0
  45. package/dist/functions/templates/typescript-node/src/index.ts +29 -0
  46. package/dist/functions/templates/typescript-node/tsconfig.json +28 -0
  47. package/dist/functions/templates/uv/README.md +31 -0
  48. package/dist/functions/templates/uv/pyproject.toml +30 -0
  49. package/dist/functions/templates/uv/src/__init__.py +0 -0
  50. package/dist/functions/templates/uv/src/context.py +125 -0
  51. package/dist/functions/templates/uv/src/index.py +46 -0
  52. package/dist/interactiveCLI.js +18 -15
  53. package/dist/main.js +219 -81
  54. package/dist/migrations/appwriteToX.d.ts +88 -23
  55. package/dist/migrations/comprehensiveTransfer.d.ts +2 -0
  56. package/dist/migrations/comprehensiveTransfer.js +83 -6
  57. package/dist/migrations/dataLoader.d.ts +227 -69
  58. package/dist/migrations/dataLoader.js +3 -3
  59. package/dist/migrations/importController.js +3 -3
  60. package/dist/migrations/relationships.d.ts +8 -2
  61. package/dist/migrations/services/ImportOrchestrator.js +3 -3
  62. package/dist/migrations/transfer.js +159 -37
  63. package/dist/shared/attributeMapper.d.ts +20 -0
  64. package/dist/shared/attributeMapper.js +203 -0
  65. package/dist/shared/selectionDialogs.d.ts +1 -1
  66. package/dist/shared/selectionDialogs.js +39 -11
  67. package/dist/storage/schemas.d.ts +354 -92
  68. package/dist/utils/configDiscovery.js +4 -3
  69. package/dist/utils/versionDetection.d.ts +0 -4
  70. package/dist/utils/versionDetection.js +41 -173
  71. package/dist/utils/yamlConverter.js +89 -16
  72. package/dist/utils/yamlLoader.d.ts +1 -1
  73. package/dist/utils/yamlLoader.js +6 -2
  74. package/dist/utilsController.d.ts +2 -1
  75. package/dist/utilsController.js +151 -22
  76. package/package.json +7 -5
  77. package/scripts/copy-templates.ts +23 -0
  78. package/src/adapters/AdapterFactory.ts +119 -143
  79. package/src/adapters/DatabaseAdapter.ts +18 -3
  80. package/src/adapters/LegacyAdapter.ts +236 -105
  81. package/src/adapters/TablesDBAdapter.ts +773 -643
  82. package/src/cli/commands/databaseCommands.ts +19 -19
  83. package/src/cli/commands/functionCommands.ts +23 -14
  84. package/src/collections/attributes.ts +2054 -1611
  85. package/src/collections/methods.ts +208 -293
  86. package/src/collections/tableOperations.ts +506 -0
  87. package/src/collections/transferOperations.ts +218 -144
  88. package/src/config/services/ConfigLoaderService.ts +62 -1
  89. package/src/examples/yamlTerminologyExample.ts +10 -5
  90. package/src/functions/deployments.ts +10 -35
  91. package/src/functions/fnConfigDiscovery.ts +103 -0
  92. package/src/functions/methods.ts +4 -2
  93. package/src/functions/pathResolution.ts +227 -0
  94. package/src/interactiveCLI.ts +25 -20
  95. package/src/main.ts +557 -202
  96. package/src/migrations/comprehensiveTransfer.ts +126 -50
  97. package/src/migrations/dataLoader.ts +3 -3
  98. package/src/migrations/importController.ts +3 -3
  99. package/src/migrations/services/ImportOrchestrator.ts +3 -3
  100. package/src/migrations/transfer.ts +148 -131
  101. package/src/shared/attributeMapper.ts +229 -0
  102. package/src/shared/selectionDialogs.ts +65 -32
  103. package/src/utils/configDiscovery.ts +9 -3
  104. package/src/utils/versionDetection.ts +74 -228
  105. package/src/utils/yamlConverter.ts +94 -17
  106. package/src/utils/yamlLoader.ts +11 -4
  107. package/src/utilsController.ts +202 -36
  108. package/dist/utils/schemaStrings.d.ts +0 -14
  109. package/dist/utils/schemaStrings.js +0 -428
  110. package/dist/utils/sessionPreservationExample.d.ts +0 -1666
  111. package/dist/utils/sessionPreservationExample.js +0 -101
@@ -6,6 +6,7 @@
6
6
  * code uses TablesDB-style method signatures for consistency.
7
7
  */
8
8
 
9
+ import type { Client } from "node-appwrite";
9
10
  import type { ApiMode } from "../utils/versionDetection.js";
10
11
 
11
12
  // Base parameter types using TablesDB terminology
@@ -43,6 +44,7 @@ export interface CreateTableParams {
43
44
  name: string;
44
45
  permissions?: string[];
45
46
  documentSecurity?: boolean;
47
+ rowSecurity?: boolean;
46
48
  enabled?: boolean;
47
49
  }
48
50
 
@@ -52,6 +54,7 @@ export interface UpdateTableParams {
52
54
  name: string;
53
55
  permissions?: string[];
54
56
  documentSecurity?: boolean;
57
+ rowSecurity?: boolean;
55
58
  enabled?: boolean;
56
59
  }
57
60
 
@@ -131,8 +134,20 @@ export interface UpdateAttributeParams {
131
134
  databaseId: string;
132
135
  tableId: string;
133
136
  key: string;
137
+ type?: string;
134
138
  required?: boolean;
135
139
  default?: any;
140
+ size?: number;
141
+ min?: number;
142
+ max?: number;
143
+ array?: boolean;
144
+ encrypt?: boolean;
145
+ elements?: string[];
146
+ relatedCollection?: string;
147
+ relationType?: string;
148
+ twoWay?: boolean;
149
+ twoWayKey?: string;
150
+ onDelete?: string;
136
151
  }
137
152
 
138
153
  export interface DeleteAttributeParams {
@@ -217,10 +232,10 @@ export interface DatabaseAdapter {
217
232
  * Base adapter class with common functionality
218
233
  */
219
234
  export abstract class BaseAdapter implements DatabaseAdapter {
220
- protected client: any;
235
+ protected client: Client;
221
236
  protected apiMode: ApiMode;
222
237
 
223
- constructor(client: any, apiMode: ApiMode) {
238
+ constructor(client: Client, apiMode: ApiMode) {
224
239
  this.client = client;
225
240
  this.apiMode = apiMode;
226
241
  }
@@ -288,4 +303,4 @@ export class UnsupportedOperationError extends AdapterError {
288
303
  );
289
304
  this.name = 'UnsupportedOperationError';
290
305
  }
291
- }
306
+ }
@@ -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
+ }