appwrite-utils-cli 1.5.2 → 1.6.0

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 (233) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +251 -29
  3. package/dist/adapters/AdapterFactory.d.ts +10 -3
  4. package/dist/adapters/AdapterFactory.js +213 -17
  5. package/dist/adapters/TablesDBAdapter.js +60 -17
  6. package/dist/backups/operations/bucketBackup.d.ts +19 -0
  7. package/dist/backups/operations/bucketBackup.js +197 -0
  8. package/dist/backups/operations/collectionBackup.d.ts +30 -0
  9. package/dist/backups/operations/collectionBackup.js +201 -0
  10. package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
  11. package/dist/backups/operations/comprehensiveBackup.js +238 -0
  12. package/dist/backups/schemas/bucketManifest.d.ts +93 -0
  13. package/dist/backups/schemas/bucketManifest.js +33 -0
  14. package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
  15. package/dist/backups/schemas/comprehensiveManifest.js +32 -0
  16. package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
  17. package/dist/backups/tracking/centralizedTracking.js +274 -0
  18. package/dist/cli/commands/configCommands.d.ts +8 -0
  19. package/dist/cli/commands/configCommands.js +160 -0
  20. package/dist/cli/commands/databaseCommands.d.ts +13 -0
  21. package/dist/cli/commands/databaseCommands.js +478 -0
  22. package/dist/cli/commands/functionCommands.d.ts +7 -0
  23. package/dist/cli/commands/functionCommands.js +289 -0
  24. package/dist/cli/commands/schemaCommands.d.ts +7 -0
  25. package/dist/cli/commands/schemaCommands.js +134 -0
  26. package/dist/cli/commands/transferCommands.d.ts +5 -0
  27. package/dist/cli/commands/transferCommands.js +384 -0
  28. package/dist/collections/attributes.d.ts +5 -4
  29. package/dist/collections/attributes.js +539 -246
  30. package/dist/collections/indexes.js +39 -37
  31. package/dist/collections/methods.d.ts +2 -16
  32. package/dist/collections/methods.js +90 -538
  33. package/dist/collections/transferOperations.d.ts +7 -0
  34. package/dist/collections/transferOperations.js +331 -0
  35. package/dist/collections/wipeOperations.d.ts +16 -0
  36. package/dist/collections/wipeOperations.js +328 -0
  37. package/dist/config/configMigration.d.ts +87 -0
  38. package/dist/config/configMigration.js +390 -0
  39. package/dist/config/configValidation.d.ts +66 -0
  40. package/dist/config/configValidation.js +358 -0
  41. package/dist/config/yamlConfig.d.ts +455 -1
  42. package/dist/config/yamlConfig.js +145 -52
  43. package/dist/databases/methods.js +3 -2
  44. package/dist/databases/setup.d.ts +1 -2
  45. package/dist/databases/setup.js +9 -87
  46. package/dist/examples/yamlTerminologyExample.d.ts +42 -0
  47. package/dist/examples/yamlTerminologyExample.js +269 -0
  48. package/dist/functions/deployments.js +11 -10
  49. package/dist/functions/methods.d.ts +1 -1
  50. package/dist/functions/methods.js +5 -4
  51. package/dist/init.js +9 -9
  52. package/dist/interactiveCLI.d.ts +8 -17
  53. package/dist/interactiveCLI.js +181 -1172
  54. package/dist/main.js +364 -21
  55. package/dist/migrations/afterImportActions.js +22 -30
  56. package/dist/migrations/appwriteToX.js +71 -25
  57. package/dist/migrations/dataLoader.js +35 -26
  58. package/dist/migrations/importController.js +29 -30
  59. package/dist/migrations/relationships.js +13 -12
  60. package/dist/migrations/services/ImportOrchestrator.js +16 -19
  61. package/dist/migrations/transfer.js +46 -46
  62. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +3 -1
  63. package/dist/migrations/yaml/YamlImportConfigLoader.js +6 -3
  64. package/dist/migrations/yaml/YamlImportIntegration.d.ts +9 -3
  65. package/dist/migrations/yaml/YamlImportIntegration.js +22 -11
  66. package/dist/migrations/yaml/generateImportSchemas.d.ts +14 -1
  67. package/dist/migrations/yaml/generateImportSchemas.js +736 -7
  68. package/dist/schemas/authUser.d.ts +1 -1
  69. package/dist/setupController.js +3 -2
  70. package/dist/shared/backupMetadataSchema.d.ts +94 -0
  71. package/dist/shared/backupMetadataSchema.js +38 -0
  72. package/dist/shared/backupTracking.d.ts +18 -0
  73. package/dist/shared/backupTracking.js +176 -0
  74. package/dist/shared/confirmationDialogs.js +15 -15
  75. package/dist/shared/errorUtils.d.ts +54 -0
  76. package/dist/shared/errorUtils.js +95 -0
  77. package/dist/shared/functionManager.js +20 -19
  78. package/dist/shared/indexManager.js +12 -11
  79. package/dist/shared/jsonSchemaGenerator.js +10 -26
  80. package/dist/shared/logging.d.ts +51 -0
  81. package/dist/shared/logging.js +70 -0
  82. package/dist/shared/messageFormatter.d.ts +2 -0
  83. package/dist/shared/messageFormatter.js +10 -0
  84. package/dist/shared/migrationHelpers.d.ts +6 -16
  85. package/dist/shared/migrationHelpers.js +24 -21
  86. package/dist/shared/operationLogger.d.ts +8 -1
  87. package/dist/shared/operationLogger.js +11 -24
  88. package/dist/shared/operationQueue.d.ts +28 -1
  89. package/dist/shared/operationQueue.js +268 -66
  90. package/dist/shared/operationsTable.d.ts +26 -0
  91. package/dist/shared/operationsTable.js +286 -0
  92. package/dist/shared/operationsTableSchema.d.ts +48 -0
  93. package/dist/shared/operationsTableSchema.js +35 -0
  94. package/dist/shared/relationshipExtractor.d.ts +56 -0
  95. package/dist/shared/relationshipExtractor.js +138 -0
  96. package/dist/shared/schemaGenerator.d.ts +19 -1
  97. package/dist/shared/schemaGenerator.js +56 -75
  98. package/dist/storage/backupCompression.d.ts +20 -0
  99. package/dist/storage/backupCompression.js +67 -0
  100. package/dist/storage/methods.d.ts +16 -2
  101. package/dist/storage/methods.js +98 -14
  102. package/dist/users/methods.js +9 -8
  103. package/dist/utils/configDiscovery.d.ts +78 -0
  104. package/dist/utils/configDiscovery.js +430 -0
  105. package/dist/utils/directoryUtils.d.ts +22 -0
  106. package/dist/utils/directoryUtils.js +59 -0
  107. package/dist/utils/getClientFromConfig.d.ts +17 -8
  108. package/dist/utils/getClientFromConfig.js +162 -17
  109. package/dist/utils/helperFunctions.d.ts +16 -2
  110. package/dist/utils/helperFunctions.js +19 -5
  111. package/dist/utils/loadConfigs.d.ts +34 -9
  112. package/dist/utils/loadConfigs.js +236 -316
  113. package/dist/utils/pathResolvers.d.ts +53 -0
  114. package/dist/utils/pathResolvers.js +72 -0
  115. package/dist/utils/projectConfig.d.ts +119 -0
  116. package/dist/utils/projectConfig.js +171 -0
  117. package/dist/utils/retryFailedPromises.js +4 -2
  118. package/dist/utils/sessionAuth.d.ts +48 -0
  119. package/dist/utils/sessionAuth.js +164 -0
  120. package/dist/utils/sessionPreservationExample.d.ts +1666 -0
  121. package/dist/utils/sessionPreservationExample.js +101 -0
  122. package/dist/utils/setupFiles.js +301 -41
  123. package/dist/utils/typeGuards.d.ts +35 -0
  124. package/dist/utils/typeGuards.js +57 -0
  125. package/dist/utils/versionDetection.js +145 -9
  126. package/dist/utils/yamlConverter.d.ts +53 -3
  127. package/dist/utils/yamlConverter.js +232 -13
  128. package/dist/utils/yamlLoader.d.ts +70 -0
  129. package/dist/utils/yamlLoader.js +263 -0
  130. package/dist/utilsController.d.ts +36 -3
  131. package/dist/utilsController.js +186 -56
  132. package/package.json +12 -2
  133. package/src/adapters/AdapterFactory.ts +263 -35
  134. package/src/adapters/TablesDBAdapter.ts +225 -36
  135. package/src/backups/operations/bucketBackup.ts +277 -0
  136. package/src/backups/operations/collectionBackup.ts +310 -0
  137. package/src/backups/operations/comprehensiveBackup.ts +342 -0
  138. package/src/backups/schemas/bucketManifest.ts +78 -0
  139. package/src/backups/schemas/comprehensiveManifest.ts +76 -0
  140. package/src/backups/tracking/centralizedTracking.ts +352 -0
  141. package/src/cli/commands/configCommands.ts +194 -0
  142. package/src/cli/commands/databaseCommands.ts +635 -0
  143. package/src/cli/commands/functionCommands.ts +379 -0
  144. package/src/cli/commands/schemaCommands.ts +163 -0
  145. package/src/cli/commands/transferCommands.ts +457 -0
  146. package/src/collections/attributes.ts +900 -621
  147. package/src/collections/attributes.ts.backup +1555 -0
  148. package/src/collections/indexes.ts +116 -114
  149. package/src/collections/methods.ts +295 -968
  150. package/src/collections/transferOperations.ts +516 -0
  151. package/src/collections/wipeOperations.ts +501 -0
  152. package/src/config/README.md +274 -0
  153. package/src/config/configMigration.ts +575 -0
  154. package/src/config/configValidation.ts +445 -0
  155. package/src/config/yamlConfig.ts +168 -55
  156. package/src/databases/methods.ts +3 -2
  157. package/src/databases/setup.ts +11 -138
  158. package/src/examples/yamlTerminologyExample.ts +341 -0
  159. package/src/functions/deployments.ts +14 -12
  160. package/src/functions/methods.ts +11 -11
  161. package/src/functions/templates/hono-typescript/README.md +286 -0
  162. package/src/functions/templates/hono-typescript/package.json +26 -0
  163. package/src/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  164. package/src/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  165. package/src/functions/templates/hono-typescript/src/app.ts +180 -0
  166. package/src/functions/templates/hono-typescript/src/context.ts +103 -0
  167. package/src/functions/templates/hono-typescript/src/index.ts +54 -0
  168. package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  169. package/src/functions/templates/hono-typescript/tsconfig.json +20 -0
  170. package/src/functions/templates/typescript-node/package.json +2 -1
  171. package/src/functions/templates/typescript-node/src/context.ts +103 -0
  172. package/src/functions/templates/typescript-node/src/index.ts +18 -12
  173. package/src/functions/templates/uv/pyproject.toml +1 -0
  174. package/src/functions/templates/uv/src/context.py +125 -0
  175. package/src/functions/templates/uv/src/index.py +35 -5
  176. package/src/init.ts +9 -11
  177. package/src/interactiveCLI.ts +278 -1596
  178. package/src/main.ts +418 -24
  179. package/src/migrations/afterImportActions.ts +71 -44
  180. package/src/migrations/appwriteToX.ts +100 -34
  181. package/src/migrations/dataLoader.ts +48 -34
  182. package/src/migrations/importController.ts +44 -39
  183. package/src/migrations/relationships.ts +28 -18
  184. package/src/migrations/services/ImportOrchestrator.ts +24 -27
  185. package/src/migrations/transfer.ts +159 -121
  186. package/src/migrations/yaml/YamlImportConfigLoader.ts +11 -4
  187. package/src/migrations/yaml/YamlImportIntegration.ts +47 -20
  188. package/src/migrations/yaml/generateImportSchemas.ts +751 -12
  189. package/src/setupController.ts +3 -2
  190. package/src/shared/backupMetadataSchema.ts +93 -0
  191. package/src/shared/backupTracking.ts +211 -0
  192. package/src/shared/confirmationDialogs.ts +19 -19
  193. package/src/shared/errorUtils.ts +110 -0
  194. package/src/shared/functionManager.ts +21 -20
  195. package/src/shared/indexManager.ts +12 -11
  196. package/src/shared/jsonSchemaGenerator.ts +38 -52
  197. package/src/shared/logging.ts +75 -0
  198. package/src/shared/messageFormatter.ts +14 -1
  199. package/src/shared/migrationHelpers.ts +45 -38
  200. package/src/shared/operationLogger.ts +11 -36
  201. package/src/shared/operationQueue.ts +322 -93
  202. package/src/shared/operationsTable.ts +338 -0
  203. package/src/shared/operationsTableSchema.ts +60 -0
  204. package/src/shared/relationshipExtractor.ts +214 -0
  205. package/src/shared/schemaGenerator.ts +179 -219
  206. package/src/storage/backupCompression.ts +88 -0
  207. package/src/storage/methods.ts +131 -34
  208. package/src/users/methods.ts +11 -9
  209. package/src/utils/configDiscovery.ts +502 -0
  210. package/src/utils/directoryUtils.ts +61 -0
  211. package/src/utils/getClientFromConfig.ts +205 -22
  212. package/src/utils/helperFunctions.ts +23 -5
  213. package/src/utils/loadConfigs.ts +313 -345
  214. package/src/utils/pathResolvers.ts +81 -0
  215. package/src/utils/projectConfig.ts +299 -0
  216. package/src/utils/retryFailedPromises.ts +4 -2
  217. package/src/utils/sessionAuth.ts +230 -0
  218. package/src/utils/setupFiles.ts +322 -54
  219. package/src/utils/typeGuards.ts +65 -0
  220. package/src/utils/versionDetection.ts +218 -64
  221. package/src/utils/yamlConverter.ts +296 -13
  222. package/src/utils/yamlLoader.ts +364 -0
  223. package/src/utilsController.ts +314 -110
  224. package/tests/README.md +497 -0
  225. package/tests/adapters/AdapterFactory.test.ts +277 -0
  226. package/tests/integration/syncOperations.test.ts +463 -0
  227. package/tests/jest.config.js +25 -0
  228. package/tests/migration/configMigration.test.ts +546 -0
  229. package/tests/setup.ts +62 -0
  230. package/tests/testUtils.ts +340 -0
  231. package/tests/utils/loadConfigs.test.ts +350 -0
  232. package/tests/validation/configValidation.test.ts +412 -0
  233. package/src/utils/schemaStrings.ts +0 -517
@@ -1,8 +1,9 @@
1
- import { indexSchema, type Index } from "appwrite-utils";
2
- import { Databases, IndexType, Query, type Models } from "node-appwrite";
3
- import type { DatabaseAdapter } from "../adapters/DatabaseAdapter.js";
4
- import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
5
- import chalk from "chalk";
1
+ import { indexSchema, type Index } from "appwrite-utils";
2
+ import { Databases, IndexType, Query, type Models } from "node-appwrite";
3
+ import type { DatabaseAdapter } from "../adapters/DatabaseAdapter.js";
4
+ import { delay, tryAwaitWithRetry, calculateExponentialBackoff } from "../utils/helperFunctions.js";
5
+ import { isLegacyDatabases } from "../utils/typeGuards.js";
6
+ import { MessageFormatter } from "../shared/messageFormatter.js";
6
7
 
7
8
  // Interface for index with status
8
9
  interface IndexWithStatus {
@@ -19,90 +20,90 @@ interface IndexWithStatus {
19
20
  /**
20
21
  * Wait for index to become available, with retry logic for stuck indexes and exponential backoff
21
22
  */
22
- const waitForIndexAvailable = async (
23
- db: Databases | DatabaseAdapter,
24
- dbId: string,
25
- collectionId: string,
26
- indexKey: string,
27
- maxWaitTime: number = 60000, // 1 minute
28
- retryCount: number = 0,
29
- maxRetries: number = 5
30
- ): Promise<boolean> => {
23
+ const waitForIndexAvailable = async (
24
+ db: Databases | DatabaseAdapter,
25
+ dbId: string,
26
+ collectionId: string,
27
+ indexKey: string,
28
+ maxWaitTime: number = 60000, // 1 minute
29
+ retryCount: number = 0,
30
+ maxRetries: number = 5
31
+ ): Promise<boolean> => {
31
32
  const startTime = Date.now();
32
33
  let checkInterval = 2000; // Start with 2 seconds
33
34
 
34
35
  // Calculate exponential backoff: 2s, 4s, 8s, 16s, 30s (capped at 30s)
35
36
  if (retryCount > 0) {
36
- const exponentialDelay = Math.min(2000 * Math.pow(2, retryCount), 30000);
37
- console.log(chalk.blue(`Waiting for index '${indexKey}' to become available (retry ${retryCount}, backoff: ${exponentialDelay}ms)...`));
37
+ const exponentialDelay = calculateExponentialBackoff(retryCount);
38
+ MessageFormatter.info(`Waiting for index '${indexKey}' to become available (retry ${retryCount}, backoff: ${exponentialDelay}ms)...`);
38
39
  await delay(exponentialDelay);
39
40
  } else {
40
- console.log(chalk.blue(`Waiting for index '${indexKey}' to become available...`));
41
+ MessageFormatter.info(`Waiting for index '${indexKey}' to become available...`);
41
42
  }
42
43
 
43
44
  while (Date.now() - startTime < maxWaitTime) {
44
45
  try {
45
- const indexList = await (db instanceof Databases
46
- ? db.listIndexes(dbId, collectionId)
47
- : (db as DatabaseAdapter).listIndexes({ databaseId: dbId, tableId: collectionId }));
48
- const indexes: any[] = (db instanceof Databases)
49
- ? (indexList as any).indexes
50
- : ((indexList as any).data || (indexList as any).indexes || []);
51
- const index = indexes.find((idx: any) => idx.key === indexKey) as IndexWithStatus | undefined;
52
-
46
+ const indexList = await (isLegacyDatabases(db)
47
+ ? db.listIndexes(dbId, collectionId)
48
+ : (db as DatabaseAdapter).listIndexes({ databaseId: dbId, tableId: collectionId }));
49
+ const indexes: any[] = isLegacyDatabases(db)
50
+ ? (indexList as any).indexes
51
+ : ((indexList as any).data || (indexList as any).indexes || []);
52
+ const index = indexes.find((idx: any) => idx.key === indexKey) as IndexWithStatus | undefined;
53
+
53
54
  if (!index) {
54
- console.log(chalk.red(`Index '${indexKey}' not found`));
55
+ MessageFormatter.error(`Index '${indexKey}' not found in database '${dbId}' collection '${collectionId}'`);
55
56
  return false;
56
57
  }
57
-
58
- if (db instanceof Databases) {
59
- console.log(chalk.gray(`Index '${indexKey}' status: ${(index as any).status}`));
60
- } else {
61
- console.log(chalk.gray(`Index '${indexKey}' detected (TablesDB)`));
62
- }
58
+
59
+ if (isLegacyDatabases(db)) {
60
+ MessageFormatter.debug(`Index '${indexKey}' status: ${(index as any).status}`);
61
+ } else {
62
+ MessageFormatter.debug(`Index '${indexKey}' detected (TablesDB)`);
63
+ }
63
64
 
64
65
  switch (index.status) {
65
- case 'available':
66
- console.log(chalk.green(`✅ Index '${indexKey}' is now available`));
67
- return true;
68
-
66
+ case 'available':
67
+ MessageFormatter.success(`Index '${indexKey}' is now available (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
68
+ return true;
69
+
69
70
  case 'failed':
70
- console.log(chalk.red(`❌ Index '${indexKey}' failed: ${index.error}`));
71
+ MessageFormatter.error(`Index '${indexKey}' failed: ${index.error} (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
71
72
  return false;
72
-
73
+
73
74
  case 'stuck':
74
- console.log(chalk.yellow(`⚠️ Index '${indexKey}' is stuck, will retry...`));
75
+ MessageFormatter.warning(`Index '${indexKey}' is stuck, will retry... (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
75
76
  return false;
76
-
77
- case 'processing':
78
- // Continue waiting
79
- break;
80
-
77
+
78
+ case 'processing':
79
+ // Continue waiting
80
+ break;
81
+
81
82
  case 'deleting':
82
- console.log(chalk.yellow(`Index '${indexKey}' is being deleted`));
83
+ MessageFormatter.warning(`Index '${indexKey}' is being deleted`);
83
84
  break;
84
-
85
+
85
86
  default:
86
- console.log(chalk.yellow(`Unknown status '${index.status}' for index '${indexKey}'`));
87
+ MessageFormatter.warning(`Unknown status '${index.status}' for index '${indexKey}'`);
87
88
  break;
88
89
  }
89
90
 
90
- await delay(checkInterval);
91
- } catch (error) {
92
- console.log(chalk.red(`Error checking index status: ${error}`));
93
- return false;
94
- }
95
- }
96
-
91
+ await delay(checkInterval);
92
+ } catch (error) {
93
+ MessageFormatter.error(`Error checking index '${indexKey}' status in database '${dbId}' collection '${collectionId}': ${error}`);
94
+ return false;
95
+ }
96
+ }
97
+
97
98
  // Timeout reached
98
- console.log(chalk.yellow(`⏰ Timeout waiting for index '${indexKey}' (${maxWaitTime}ms)`));
99
-
99
+ MessageFormatter.warning(`Timeout waiting for index '${indexKey}' (${maxWaitTime}ms)`);
100
+
100
101
  // If we have retries left and this isn't the last retry, try recreating
101
102
  if (retryCount < maxRetries) {
102
- console.log(chalk.yellow(`🔄 Retrying index creation (attempt ${retryCount + 1}/${maxRetries})`));
103
+ MessageFormatter.info(`Retrying index '${indexKey}' creation (attempt ${retryCount + 1}/${maxRetries})`);
103
104
  return false; // Signal that we need to retry
104
105
  }
105
-
106
+
106
107
  return false;
107
108
  };
108
109
 
@@ -119,7 +120,7 @@ export const createOrUpdateIndexWithStatusCheck = async (
119
120
  retryCount: number = 0,
120
121
  maxRetries: number = 3,
121
122
  ): Promise<boolean> => {
122
- console.log(chalk.blue(`Creating/updating index '${index.key}' (attempt ${retryCount + 1}/${maxRetries + 1})`));
123
+ MessageFormatter.info(`Creating/updating index '${index.key}' (attempt ${retryCount + 1}/${maxRetries + 1}) - type: ${index.type}, attributes: [${index.attributes.join(', ')}]`);
123
124
 
124
125
  try {
125
126
  // First, validate that all required attributes exist
@@ -127,10 +128,10 @@ export const createOrUpdateIndexWithStatusCheck = async (
127
128
  const existingAttributeKeys = freshCollection.attributes.map((attr: any) => attr.key);
128
129
 
129
130
  const missingAttributes = index.attributes.filter(attr => !existingAttributeKeys.includes(attr));
130
-
131
+
131
132
  if (missingAttributes.length > 0) {
132
- console.log(chalk.red(`❌ Index '${index.key}' cannot be created: missing attributes [${missingAttributes.join(', ')}]`));
133
- console.log(chalk.red(`Available attributes: [${existingAttributeKeys.join(', ')}]`));
133
+ MessageFormatter.error(`Index '${index.key}' cannot be created: missing attributes [${missingAttributes.join(', ')}] (type: ${index.type})`);
134
+ MessageFormatter.error(`Available attributes: [${existingAttributeKeys.join(', ')}]`);
134
135
  return false; // Don't retry if attributes are missing
135
136
  }
136
137
 
@@ -154,56 +155,56 @@ export const createOrUpdateIndexWithStatusCheck = async (
154
155
 
155
156
  // If not successful and we have retries left, just retry the index creation
156
157
  if (retryCount < maxRetries) {
157
- console.log(chalk.yellow(`Index '${index.key}' failed/stuck, retrying (${retryCount + 1}/${maxRetries})...`));
158
-
158
+ MessageFormatter.warning(`Index '${index.key}' failed/stuck, retrying (${retryCount + 1}/${maxRetries}) - type: ${index.type}, attributes: [${index.attributes.join(', ')}]`);
159
+
159
160
  // Wait a bit before retry
160
161
  await new Promise(resolve => setTimeout(resolve, 2000 * (retryCount + 1)));
161
-
162
+
162
163
  // Retry the index creation
163
164
  return await createOrUpdateIndexWithStatusCheck(
164
- dbId,
165
- db,
166
- collectionId,
167
- collection,
168
- index,
169
- retryCount + 1,
165
+ dbId,
166
+ db,
167
+ collectionId,
168
+ collection,
169
+ index,
170
+ retryCount + 1,
170
171
  maxRetries
171
172
  );
172
173
  }
173
-
174
- console.log(chalk.red(`❌ Failed to create index '${index.key}' after ${maxRetries + 1} attempts`));
174
+
175
+ MessageFormatter.error(`Failed to create index '${index.key}' after ${maxRetries + 1} attempts (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
175
176
  return false;
176
177
 
177
178
  } catch (error) {
178
179
  const errorMessage = error instanceof Error ? error.message : String(error);
179
- console.log(chalk.red(`Error creating index '${index.key}': ${errorMessage}`));
180
-
180
+ MessageFormatter.error(`Error creating index '${index.key}': ${errorMessage} (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
181
+
181
182
  // Check if this is a permanent error that shouldn't be retried
182
- if (errorMessage.toLowerCase().includes('not found') ||
183
- errorMessage.toLowerCase().includes('missing') ||
183
+ if (errorMessage.toLowerCase().includes('not found') ||
184
+ errorMessage.toLowerCase().includes('missing') ||
184
185
  errorMessage.toLowerCase().includes('does not exist') ||
185
186
  errorMessage.toLowerCase().includes('attribute') && errorMessage.toLowerCase().includes('not found')) {
186
- console.log(chalk.red(`❌ Index '${index.key}' has permanent error - not retrying`));
187
+ MessageFormatter.error(`Index '${index.key}' has permanent error - not retrying (type: ${index.type})`);
187
188
  return false;
188
189
  }
189
-
190
+
190
191
  if (retryCount < maxRetries) {
191
- console.log(chalk.yellow(`Retrying index '${index.key}' due to error...`));
192
-
192
+ MessageFormatter.warning(`Retrying index '${index.key}' due to error... (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
193
+
193
194
  // Wait a bit before retry
194
195
  await delay(2000);
195
-
196
+
196
197
  return await createOrUpdateIndexWithStatusCheck(
197
- dbId,
198
- db,
199
- collectionId,
200
- collection,
201
- index,
202
- retryCount + 1,
198
+ dbId,
199
+ db,
200
+ collectionId,
201
+ collection,
202
+ index,
203
+ retryCount + 1,
203
204
  maxRetries
204
205
  );
205
206
  }
206
-
207
+
207
208
  return false;
208
209
  }
209
210
  };
@@ -218,61 +219,62 @@ export const createOrUpdateIndexesWithStatusCheck = async (
218
219
  collection: Models.Collection,
219
220
  indexes: Index[]
220
221
  ): Promise<boolean> => {
221
- console.log(chalk.blue(`Creating/updating ${indexes.length} indexes with status monitoring...`));
222
-
222
+ MessageFormatter.info(`Creating/updating ${indexes.length} indexes with status monitoring for collection '${collectionId}'`);
223
+
223
224
  let indexesToProcess = [...indexes];
224
225
  let overallRetryCount = 0;
225
226
  const maxOverallRetries = 3;
226
-
227
+
227
228
  while (indexesToProcess.length > 0 && overallRetryCount < maxOverallRetries) {
228
229
  const remainingIndexes = [...indexesToProcess];
229
230
  indexesToProcess = []; // Reset for next iteration
230
-
231
- console.log(chalk.blue(`\n=== Attempt ${overallRetryCount + 1}/${maxOverallRetries} - Processing ${remainingIndexes.length} indexes ===`));
231
+
232
+ MessageFormatter.info(`\n=== Attempt ${overallRetryCount + 1}/${maxOverallRetries} - Processing ${remainingIndexes.length} indexes ===`);
232
233
 
233
234
  for (const index of remainingIndexes) {
234
- console.log(chalk.blue(`\n--- Processing index: ${index.key} ---`));
235
-
235
+ MessageFormatter.info(`\n--- Processing index: ${index.key} (type: ${index.type}, attributes: [${index.attributes.join(', ')}]) ---`);
236
+
236
237
  const success = await createOrUpdateIndexWithStatusCheck(
237
- dbId,
238
- db,
239
- collectionId,
240
- collection,
238
+ dbId,
239
+ db,
240
+ collectionId,
241
+ collection,
241
242
  index
242
243
  );
243
-
244
+
244
245
  if (success) {
245
- console.log(chalk.green(`✅ Successfully created index: ${index.key}`));
246
-
246
+ MessageFormatter.success(`Successfully created index: ${index.key} (type: ${index.type})`);
247
+
247
248
  // Add delay between successful indexes
248
249
  await delay(1000);
249
250
  } else {
250
- console.log(chalk.red(`❌ Failed to create index: ${index.key}, will retry in next round`));
251
+ MessageFormatter.error(`Failed to create index: ${index.key} (type: ${index.type}), will retry in next round`);
251
252
  indexesToProcess.push(index); // Add back to retry list
252
253
  }
253
254
  }
254
-
255
+
255
256
  if (indexesToProcess.length === 0) {
256
- console.log(chalk.green(`\n✅ Successfully created all ${indexes.length} indexes`));
257
+ MessageFormatter.success(`\nSuccessfully created all ${indexes.length} indexes for collection '${collectionId}'`);
257
258
  return true;
258
259
  }
259
-
260
+
260
261
  overallRetryCount++;
261
-
262
+
262
263
  if (overallRetryCount < maxOverallRetries) {
263
- console.log(chalk.yellow(`\n⏳ Waiting 5 seconds before retrying ${indexesToProcess.length} failed indexes...`));
264
+ MessageFormatter.warning(`\nWaiting 5 seconds before retrying ${indexesToProcess.length} failed indexes...`);
264
265
  await delay(5000);
265
266
  }
266
267
  }
267
-
268
+
268
269
  // If we get here, some indexes still failed after all retries
269
270
  if (indexesToProcess.length > 0) {
270
- console.log(chalk.red(`\n❌ Failed to create ${indexesToProcess.length} indexes after ${maxOverallRetries} attempts: ${indexesToProcess.map(i => i.key).join(', ')}`));
271
- console.log(chalk.red(`This may indicate a fundamental issue with the index definitions or Appwrite instance`));
271
+ const failedIndexKeys = indexesToProcess.map(i => `${i.key} (${i.type})`).join(', ');
272
+ MessageFormatter.error(`\nFailed to create ${indexesToProcess.length} indexes after ${maxOverallRetries} attempts: ${failedIndexKeys}`);
273
+ MessageFormatter.error(`This may indicate a fundamental issue with the index definitions or Appwrite instance`);
272
274
  return false;
273
275
  }
274
-
275
- console.log(chalk.green(`\n✅ Successfully created all ${indexes.length} indexes`));
276
+
277
+ MessageFormatter.success(`\nSuccessfully created all ${indexes.length} indexes for collection '${collectionId}'`);
276
278
  return true;
277
279
  };
278
280