appwrite-utils-cli 1.7.9 → 1.8.2

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
@@ -6,7 +6,7 @@
6
6
  * code can use modern TablesDB patterns while maintaining compatibility with
7
7
  * older Appwrite instances.
8
8
  */
9
- import { Query } from "node-appwrite";
9
+ import { Client, Databases, IndexType, Query, RelationshipType, RelationMutate } from "node-appwrite";
10
10
  import { chunk } from "es-toolkit";
11
11
  import { BaseAdapter, AdapterError, UnsupportedOperationError } from './DatabaseAdapter.js';
12
12
  /**
@@ -17,7 +17,7 @@ export class LegacyAdapter extends BaseAdapter {
17
17
  constructor(client) {
18
18
  super(client, 'legacy');
19
19
  // Assuming Databases service is available on the client
20
- this.databases = client;
20
+ this.databases = new Databases(client);
21
21
  }
22
22
  // Row (Document) Operations - Translate object notation to positional parameters
23
23
  async listRows(params) {
@@ -211,35 +211,113 @@ export class LegacyAdapter extends BaseAdapter {
211
211
  let result;
212
212
  switch (params.type.toLowerCase()) {
213
213
  case 'string':
214
- result = await this.databases.createStringAttribute(params.databaseId, params.tableId, params.key, params.size || 255, params.required ?? false, params.default, params.array ?? false, params.encrypt ?? false);
214
+ result = await this.databases.createStringAttribute({
215
+ databaseId: params.databaseId,
216
+ collectionId: params.tableId,
217
+ key: params.key,
218
+ size: params.size || 255,
219
+ required: params.required ?? false,
220
+ xdefault: params.default,
221
+ array: params.array ?? false,
222
+ encrypt: params.encrypt ?? false
223
+ });
215
224
  break;
216
225
  case 'integer':
217
- result = await this.databases.createIntegerAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.min, params.max, params.default, params.array ?? false);
226
+ result = await this.databases.createIntegerAttribute({
227
+ databaseId: params.databaseId,
228
+ collectionId: params.tableId,
229
+ key: params.key,
230
+ required: params.required ?? false,
231
+ min: params.min,
232
+ max: params.max,
233
+ xdefault: params.default,
234
+ array: params.array ?? false
235
+ });
218
236
  break;
219
237
  case 'float':
220
238
  case 'double':
221
- result = await this.databases.createFloatAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.min, params.max, params.default, params.array ?? false);
239
+ result = await this.databases.createFloatAttribute({
240
+ databaseId: params.databaseId,
241
+ collectionId: params.tableId,
242
+ key: params.key,
243
+ required: params.required ?? false,
244
+ min: params.min,
245
+ max: params.max,
246
+ xdefault: params.default,
247
+ array: params.array ?? false
248
+ });
222
249
  break;
223
250
  case 'boolean':
224
- result = await this.databases.createBooleanAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.default, params.array ?? false);
251
+ result = await this.databases.createBooleanAttribute({
252
+ databaseId: params.databaseId,
253
+ collectionId: params.tableId,
254
+ key: params.key,
255
+ required: params.required ?? false,
256
+ xdefault: params.default,
257
+ array: params.array ?? false
258
+ });
225
259
  break;
226
260
  case 'datetime':
227
- result = await this.databases.createDatetimeAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.default, params.array ?? false);
261
+ result = await this.databases.createDatetimeAttribute({
262
+ databaseId: params.databaseId,
263
+ collectionId: params.tableId,
264
+ key: params.key,
265
+ required: params.required ?? false,
266
+ xdefault: params.default,
267
+ array: params.array ?? false
268
+ });
228
269
  break;
229
270
  case 'email':
230
- result = await this.databases.createEmailAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.default, params.array ?? false);
271
+ result = await this.databases.createEmailAttribute({
272
+ databaseId: params.databaseId,
273
+ collectionId: params.tableId,
274
+ key: params.key,
275
+ required: params.required ?? false,
276
+ xdefault: params.default,
277
+ array: params.array ?? false
278
+ });
231
279
  break;
232
280
  case 'enum':
233
- result = await this.databases.createEnumAttribute(params.databaseId, params.tableId, params.key, params.elements || [], params.required ?? false, params.default, params.array ?? false);
281
+ result = await this.databases.createEnumAttribute({
282
+ databaseId: params.databaseId,
283
+ collectionId: params.tableId,
284
+ key: params.key,
285
+ elements: params.elements || [],
286
+ required: params.required ?? false,
287
+ xdefault: params.default,
288
+ array: params.array ?? false
289
+ });
234
290
  break;
235
291
  case 'ip':
236
- result = await this.databases.createIpAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.default, params.array ?? false);
292
+ result = await this.databases.createIpAttribute({
293
+ databaseId: params.databaseId,
294
+ collectionId: params.tableId,
295
+ key: params.key,
296
+ required: params.required ?? false,
297
+ xdefault: params.default,
298
+ array: params.array ?? false
299
+ });
237
300
  break;
238
301
  case 'url':
239
- result = await this.databases.createUrlAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.default, params.array ?? false);
302
+ result = await this.databases.createUrlAttribute({
303
+ databaseId: params.databaseId,
304
+ collectionId: params.tableId,
305
+ key: params.key,
306
+ required: params.required ?? false,
307
+ xdefault: params.default,
308
+ array: params.array ?? false
309
+ });
240
310
  break;
241
311
  case 'relationship':
242
- result = await this.databases.createRelationshipAttribute(params.databaseId, params.tableId, params.key, params.relatedCollection || '', params.type || 'oneToOne', params.twoWay ?? false, params.onDelete || 'restrict');
312
+ result = await this.databases.createRelationshipAttribute({
313
+ databaseId: params.databaseId,
314
+ collectionId: params.tableId,
315
+ key: params.key,
316
+ relatedCollectionId: params.relatedCollection || '',
317
+ type: (params.type || 'oneToOne'),
318
+ twoWay: params.twoWay ?? false,
319
+ onDelete: params.onDelete || 'restrict'
320
+ });
243
321
  break;
244
322
  default:
245
323
  throw new AdapterError(`Unsupported attribute type: ${params.type}`, 'UNSUPPORTED_ATTRIBUTE_TYPE');
@@ -252,10 +330,128 @@ export class LegacyAdapter extends BaseAdapter {
252
330
  }
253
331
  async updateAttribute(params) {
254
332
  try {
255
- // TablesDB: updateAttribute({ databaseId, tableId, key, required, default })
256
- // Legacy: updateStringAttribute, updateIntegerAttribute, etc.
257
- // Note: Legacy API has type-specific update methods
258
- const result = await this.databases.updateStringAttribute(params.databaseId, params.tableId, params.key, params.required ?? false, params.default);
333
+ // Get the current collection to determine the attribute type
334
+ const collection = await this.databases.getCollection(params.databaseId, params.tableId);
335
+ const existingAttr = collection.attributes.find((attr) => attr.key === params.key);
336
+ if (!existingAttr) {
337
+ throw new AdapterError(`Attribute '${params.key}' not found in collection '${params.tableId}'`, 'ATTRIBUTE_NOT_FOUND');
338
+ }
339
+ let result;
340
+ const attributeType = existingAttr.type.toLowerCase();
341
+ // Use type-specific update methods based on attribute type with object notation
342
+ switch (attributeType) {
343
+ case 'string':
344
+ const stringAttr = existingAttr;
345
+ result = await this.databases.updateStringAttribute({
346
+ databaseId: params.databaseId,
347
+ collectionId: params.tableId,
348
+ key: params.key,
349
+ required: params.required ?? stringAttr.required,
350
+ xdefault: params.default !== undefined ? params.default : stringAttr.default,
351
+ size: stringAttr.size
352
+ });
353
+ break;
354
+ case 'integer':
355
+ const integerAttr = existingAttr;
356
+ result = await this.databases.updateIntegerAttribute({
357
+ databaseId: params.databaseId,
358
+ collectionId: params.tableId,
359
+ key: params.key,
360
+ required: params.required ?? integerAttr.required,
361
+ xdefault: params.default !== undefined ? params.default : integerAttr.default,
362
+ // Only include when explicitly provided to avoid resubmitting extreme values
363
+ ...(params.min !== undefined ? { min: params.min } : {}),
364
+ ...(params.max !== undefined ? { max: params.max } : {}),
365
+ });
366
+ break;
367
+ case 'float':
368
+ case 'double':
369
+ const floatAttr = existingAttr;
370
+ result = await this.databases.updateFloatAttribute({
371
+ databaseId: params.databaseId,
372
+ collectionId: params.tableId,
373
+ key: params.key,
374
+ required: params.required ?? floatAttr.required,
375
+ xdefault: params.default !== undefined ? params.default : floatAttr.default,
376
+ ...(params.min !== undefined ? { min: params.min } : {}),
377
+ ...(params.max !== undefined ? { max: params.max } : {}),
378
+ });
379
+ break;
380
+ case 'boolean':
381
+ const booleanAttr = existingAttr;
382
+ result = await this.databases.updateBooleanAttribute({
383
+ databaseId: params.databaseId,
384
+ collectionId: params.tableId,
385
+ key: params.key,
386
+ required: params.required ?? booleanAttr.required,
387
+ xdefault: params.default !== undefined ? params.default : booleanAttr.default
388
+ });
389
+ break;
390
+ case 'datetime':
391
+ const datetimeAttr = existingAttr;
392
+ result = await this.databases.updateDatetimeAttribute({
393
+ databaseId: params.databaseId,
394
+ collectionId: params.tableId,
395
+ key: params.key,
396
+ required: params.required ?? datetimeAttr.required,
397
+ xdefault: params.default !== undefined ? params.default : datetimeAttr.default
398
+ });
399
+ break;
400
+ case 'email':
401
+ const emailAttr = existingAttr;
402
+ result = await this.databases.updateEmailAttribute({
403
+ databaseId: params.databaseId,
404
+ collectionId: params.tableId,
405
+ key: params.key,
406
+ required: params.required ?? emailAttr.required,
407
+ xdefault: params.default !== undefined ? params.default : emailAttr.default
408
+ });
409
+ break;
410
+ case 'enum':
411
+ const enumAttr = existingAttr;
412
+ console.log('Updating enum attribute with params:', params);
413
+ result = await this.databases.updateEnumAttribute({
414
+ databaseId: params.databaseId,
415
+ collectionId: params.tableId,
416
+ key: params.key,
417
+ elements: enumAttr.elements || [],
418
+ required: params.required ?? enumAttr.required,
419
+ xdefault: params.default !== undefined ? params.default : enumAttr.default
420
+ });
421
+ break;
422
+ case 'ip':
423
+ const ipAttr = existingAttr;
424
+ result = await this.databases.updateIpAttribute({
425
+ databaseId: params.databaseId,
426
+ collectionId: params.tableId,
427
+ key: params.key,
428
+ required: params.required ?? ipAttr.required,
429
+ xdefault: params.default !== undefined ? params.default : ipAttr.default
430
+ });
431
+ break;
432
+ case 'url':
433
+ const urlAttr = existingAttr;
434
+ result = await this.databases.updateUrlAttribute({
435
+ databaseId: params.databaseId,
436
+ collectionId: params.tableId,
437
+ key: params.key,
438
+ required: params.required ?? urlAttr.required,
439
+ xdefault: params.default !== undefined ? params.default : urlAttr.default
440
+ });
441
+ break;
442
+ case 'relationship':
443
+ // Relationship attributes have different update method signature
444
+ const relationshipAttr = existingAttr;
445
+ result = await this.databases.updateRelationshipAttribute({
446
+ databaseId: params.databaseId,
447
+ collectionId: params.tableId,
448
+ key: params.key,
449
+ onDelete: relationshipAttr.onDelete
450
+ });
451
+ break;
452
+ default:
453
+ throw new AdapterError(`Unsupported attribute type for update: ${attributeType}`, 'UNSUPPORTED_ATTRIBUTE_TYPE');
454
+ }
259
455
  return { data: result };
260
456
  }
261
457
  catch (error) {
@@ -6,12 +6,13 @@
6
6
  * and returns Models.Row instead of Models.Document.
7
7
  */
8
8
  import { BaseAdapter, type CreateRowParams, type UpdateRowParams, type ListRowsParams, type DeleteRowParams, type CreateTableParams, type UpdateTableParams, type ListTablesParams, type DeleteTableParams, type GetTableParams, type BulkCreateRowsParams, type BulkUpsertRowsParams, type BulkDeleteRowsParams, type CreateIndexParams, type ListIndexesParams, type DeleteIndexParams, type CreateAttributeParams, type UpdateAttributeParams, type DeleteAttributeParams, type ApiResponse, type AdapterMetadata } from './DatabaseAdapter.js';
9
+ import { Client } from "node-appwrite";
9
10
  /**
10
11
  * TablesDBAdapter implementation for native TablesDB API
11
12
  */
12
13
  export declare class TablesDBAdapter extends BaseAdapter {
13
14
  private tablesDB;
14
- constructor(client: any);
15
+ constructor(client: Client);
15
16
  listRows(params: ListRowsParams): Promise<ApiResponse>;
16
17
  createRow(params: CreateRowParams): Promise<ApiResponse>;
17
18
  updateRow(params: UpdateRowParams): Promise<ApiResponse>;
@@ -41,15 +42,4 @@ export declare class TablesDBAdapter extends BaseAdapter {
41
42
  * Execute a transaction (if supported by TablesDB)
42
43
  */
43
44
  executeTransaction(operations: Array<() => Promise<any>>): Promise<ApiResponse>;
44
- /**
45
- * Subscribe to real-time updates (if supported)
46
- */
47
- subscribeToTable(params: {
48
- databaseId: string;
49
- tableId: string;
50
- }, callback: (data: any) => void): () => void;
51
- /**
52
- * Get table statistics (if available in TablesDB)
53
- */
54
- getTableStats(params: GetTableParams): Promise<ApiResponse>;
55
45
  }