@njdamstra/appwrite-utils-cli 1.8.9 → 1.10.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 (284) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/CONFIG_TODO.md +1189 -0
  3. package/SELECTION_DIALOGS.md +146 -0
  4. package/SERVICE_IMPLEMENTATION_REPORT.md +462 -0
  5. package/dist/adapters/index.d.ts +7 -8
  6. package/dist/adapters/index.js +7 -9
  7. package/dist/backups/operations/bucketBackup.js +2 -2
  8. package/dist/backups/operations/collectionBackup.d.ts +1 -1
  9. package/dist/backups/operations/collectionBackup.js +3 -3
  10. package/dist/backups/operations/comprehensiveBackup.d.ts +1 -1
  11. package/dist/backups/operations/comprehensiveBackup.js +2 -2
  12. package/dist/backups/tracking/centralizedTracking.d.ts +1 -1
  13. package/dist/backups/tracking/centralizedTracking.js +2 -2
  14. package/dist/cli/commands/configCommands.js +51 -7
  15. package/dist/cli/commands/databaseCommands.d.ts +1 -0
  16. package/dist/cli/commands/databaseCommands.js +119 -9
  17. package/dist/cli/commands/functionCommands.js +3 -3
  18. package/dist/cli/commands/importFileCommands.d.ts +7 -0
  19. package/dist/cli/commands/importFileCommands.js +674 -0
  20. package/dist/cli/commands/schemaCommands.js +3 -3
  21. package/dist/cli/commands/storageCommands.js +2 -3
  22. package/dist/cli/commands/transferCommands.js +3 -5
  23. package/dist/collections/attributes.d.ts +1 -1
  24. package/dist/collections/attributes.js +2 -35
  25. package/dist/collections/indexes.js +1 -3
  26. package/dist/collections/methods.d.ts +1 -1
  27. package/dist/collections/methods.js +111 -192
  28. package/dist/collections/tableOperations.d.ts +1 -0
  29. package/dist/collections/tableOperations.js +55 -23
  30. package/dist/collections/transferOperations.d.ts +1 -1
  31. package/dist/collections/transferOperations.js +3 -4
  32. package/dist/collections/wipeOperations.d.ts +4 -3
  33. package/dist/collections/wipeOperations.js +112 -39
  34. package/dist/databases/methods.js +2 -2
  35. package/dist/databases/setup.js +2 -2
  36. package/dist/examples/yamlTerminologyExample.js +2 -2
  37. package/dist/functions/deployments.d.ts +1 -1
  38. package/dist/functions/deployments.js +5 -5
  39. package/dist/functions/fnConfigDiscovery.js +2 -2
  40. package/dist/functions/methods.js +16 -4
  41. package/dist/init.js +1 -1
  42. package/dist/interactiveCLI.d.ts +6 -1
  43. package/dist/interactiveCLI.js +63 -9
  44. package/dist/main.js +130 -177
  45. package/dist/migrations/afterImportActions.js +2 -3
  46. package/dist/migrations/appwriteToX.d.ts +1 -1
  47. package/dist/migrations/appwriteToX.js +9 -7
  48. package/dist/migrations/comprehensiveTransfer.js +3 -5
  49. package/dist/migrations/dataLoader.js +2 -5
  50. package/dist/migrations/importController.js +3 -4
  51. package/dist/migrations/importDataActions.js +3 -3
  52. package/dist/migrations/relationships.js +1 -2
  53. package/dist/migrations/services/DataTransformationService.js +2 -2
  54. package/dist/migrations/services/FileHandlerService.js +1 -1
  55. package/dist/migrations/services/ImportOrchestrator.js +4 -4
  56. package/dist/migrations/services/RateLimitManager.js +1 -1
  57. package/dist/migrations/services/RelationshipResolver.js +1 -1
  58. package/dist/migrations/services/UserMappingService.js +1 -1
  59. package/dist/migrations/services/ValidationService.js +1 -1
  60. package/dist/migrations/transfer.d.ts +8 -4
  61. package/dist/migrations/transfer.js +106 -55
  62. package/dist/migrations/yaml/YamlImportConfigLoader.js +1 -1
  63. package/dist/migrations/yaml/YamlImportIntegration.js +2 -2
  64. package/dist/migrations/yaml/generateImportSchemas.js +1 -1
  65. package/dist/setupCommands.d.ts +1 -1
  66. package/dist/setupCommands.js +5 -6
  67. package/dist/setupController.js +1 -1
  68. package/dist/shared/backupTracking.d.ts +1 -1
  69. package/dist/shared/backupTracking.js +2 -2
  70. package/dist/shared/confirmationDialogs.js +1 -1
  71. package/dist/shared/migrationHelpers.d.ts +1 -1
  72. package/dist/shared/migrationHelpers.js +3 -3
  73. package/dist/shared/operationQueue.d.ts +1 -1
  74. package/dist/shared/operationQueue.js +2 -3
  75. package/dist/shared/operationsTable.d.ts +1 -1
  76. package/dist/shared/operationsTable.js +2 -2
  77. package/dist/shared/progressManager.js +1 -1
  78. package/dist/shared/selectionDialogs.js +9 -8
  79. package/dist/storage/methods.js +4 -4
  80. package/dist/storage/schemas.d.ts +2 -2
  81. package/dist/tables/indexManager.d.ts +65 -0
  82. package/dist/tables/indexManager.js +294 -0
  83. package/dist/types.d.ts +2 -2
  84. package/dist/types.js +1 -1
  85. package/dist/users/methods.js +2 -3
  86. package/dist/utils/configMigration.js +1 -1
  87. package/dist/utils/index.d.ts +1 -1
  88. package/dist/utils/index.js +1 -1
  89. package/dist/utils/loadConfigs.d.ts +2 -2
  90. package/dist/utils/loadConfigs.js +6 -7
  91. package/dist/utils/setupFiles.js +5 -7
  92. package/dist/utilsController.d.ts +15 -8
  93. package/dist/utilsController.js +57 -28
  94. package/package.json +7 -3
  95. package/src/adapters/index.ts +8 -34
  96. package/src/backups/operations/bucketBackup.ts +2 -2
  97. package/src/backups/operations/collectionBackup.ts +4 -4
  98. package/src/backups/operations/comprehensiveBackup.ts +3 -3
  99. package/src/backups/tracking/centralizedTracking.ts +3 -3
  100. package/src/cli/commands/configCommands.ts +72 -8
  101. package/src/cli/commands/databaseCommands.ts +161 -9
  102. package/src/cli/commands/functionCommands.ts +4 -3
  103. package/src/cli/commands/importFileCommands.ts +815 -0
  104. package/src/cli/commands/schemaCommands.ts +3 -3
  105. package/src/cli/commands/storageCommands.ts +2 -3
  106. package/src/cli/commands/transferCommands.ts +3 -6
  107. package/src/collections/attributes.ts +3 -39
  108. package/src/collections/indexes.ts +2 -4
  109. package/src/collections/methods.ts +115 -150
  110. package/src/collections/tableOperations.ts +57 -21
  111. package/src/collections/transferOperations.ts +4 -5
  112. package/src/collections/wipeOperations.ts +154 -51
  113. package/src/databases/methods.ts +2 -2
  114. package/src/databases/setup.ts +2 -2
  115. package/src/examples/yamlTerminologyExample.ts +2 -2
  116. package/src/functions/deployments.ts +6 -5
  117. package/src/functions/fnConfigDiscovery.ts +2 -2
  118. package/src/functions/methods.ts +17 -4
  119. package/src/init.ts +1 -1
  120. package/src/interactiveCLI.ts +75 -10
  121. package/src/main.ts +143 -287
  122. package/src/migrations/afterImportActions.ts +2 -3
  123. package/src/migrations/appwriteToX.ts +12 -8
  124. package/src/migrations/comprehensiveTransfer.ts +6 -6
  125. package/src/migrations/dataLoader.ts +2 -5
  126. package/src/migrations/importController.ts +3 -4
  127. package/src/migrations/importDataActions.ts +3 -3
  128. package/src/migrations/relationships.ts +1 -2
  129. package/src/migrations/services/DataTransformationService.ts +2 -2
  130. package/src/migrations/services/FileHandlerService.ts +1 -1
  131. package/src/migrations/services/ImportOrchestrator.ts +4 -4
  132. package/src/migrations/services/RateLimitManager.ts +1 -1
  133. package/src/migrations/services/RelationshipResolver.ts +1 -1
  134. package/src/migrations/services/UserMappingService.ts +1 -1
  135. package/src/migrations/services/ValidationService.ts +1 -1
  136. package/src/migrations/transfer.ts +126 -83
  137. package/src/migrations/yaml/YamlImportConfigLoader.ts +1 -1
  138. package/src/migrations/yaml/YamlImportIntegration.ts +2 -2
  139. package/src/migrations/yaml/generateImportSchemas.ts +1 -1
  140. package/src/setupCommands.ts +5 -6
  141. package/src/setupController.ts +1 -1
  142. package/src/shared/backupTracking.ts +3 -3
  143. package/src/shared/confirmationDialogs.ts +1 -1
  144. package/src/shared/migrationHelpers.ts +4 -4
  145. package/src/shared/operationQueue.ts +3 -4
  146. package/src/shared/operationsTable.ts +3 -3
  147. package/src/shared/progressManager.ts +1 -1
  148. package/src/shared/selectionDialogs.ts +9 -8
  149. package/src/storage/methods.ts +4 -4
  150. package/src/tables/indexManager.ts +409 -0
  151. package/src/types.ts +2 -2
  152. package/src/users/methods.ts +2 -3
  153. package/src/utils/configMigration.ts +1 -1
  154. package/src/utils/index.ts +1 -1
  155. package/src/utils/loadConfigs.ts +15 -7
  156. package/src/utils/setupFiles.ts +5 -7
  157. package/src/utilsController.ts +86 -32
  158. package/dist/adapters/AdapterFactory.d.ts +0 -94
  159. package/dist/adapters/AdapterFactory.js +0 -405
  160. package/dist/adapters/DatabaseAdapter.d.ts +0 -233
  161. package/dist/adapters/DatabaseAdapter.js +0 -50
  162. package/dist/adapters/LegacyAdapter.d.ts +0 -50
  163. package/dist/adapters/LegacyAdapter.js +0 -612
  164. package/dist/adapters/TablesDBAdapter.d.ts +0 -45
  165. package/dist/adapters/TablesDBAdapter.js +0 -571
  166. package/dist/config/ConfigManager.d.ts +0 -445
  167. package/dist/config/ConfigManager.js +0 -625
  168. package/dist/config/configMigration.d.ts +0 -87
  169. package/dist/config/configMigration.js +0 -390
  170. package/dist/config/configValidation.d.ts +0 -66
  171. package/dist/config/configValidation.js +0 -358
  172. package/dist/config/index.d.ts +0 -8
  173. package/dist/config/index.js +0 -7
  174. package/dist/config/services/ConfigDiscoveryService.d.ts +0 -126
  175. package/dist/config/services/ConfigDiscoveryService.js +0 -374
  176. package/dist/config/services/ConfigLoaderService.d.ts +0 -129
  177. package/dist/config/services/ConfigLoaderService.js +0 -540
  178. package/dist/config/services/ConfigMergeService.d.ts +0 -208
  179. package/dist/config/services/ConfigMergeService.js +0 -308
  180. package/dist/config/services/ConfigValidationService.d.ts +0 -214
  181. package/dist/config/services/ConfigValidationService.js +0 -310
  182. package/dist/config/services/SessionAuthService.d.ts +0 -225
  183. package/dist/config/services/SessionAuthService.js +0 -456
  184. package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +0 -1
  185. package/dist/config/services/__tests__/ConfigMergeService.test.js +0 -271
  186. package/dist/config/services/index.d.ts +0 -13
  187. package/dist/config/services/index.js +0 -10
  188. package/dist/config/yamlConfig.d.ts +0 -722
  189. package/dist/config/yamlConfig.js +0 -702
  190. package/dist/functions/pathResolution.d.ts +0 -37
  191. package/dist/functions/pathResolution.js +0 -185
  192. package/dist/shared/attributeMapper.d.ts +0 -20
  193. package/dist/shared/attributeMapper.js +0 -203
  194. package/dist/shared/errorUtils.d.ts +0 -54
  195. package/dist/shared/errorUtils.js +0 -95
  196. package/dist/shared/functionManager.d.ts +0 -48
  197. package/dist/shared/functionManager.js +0 -336
  198. package/dist/shared/indexManager.d.ts +0 -24
  199. package/dist/shared/indexManager.js +0 -151
  200. package/dist/shared/jsonSchemaGenerator.d.ts +0 -50
  201. package/dist/shared/jsonSchemaGenerator.js +0 -290
  202. package/dist/shared/logging.d.ts +0 -61
  203. package/dist/shared/logging.js +0 -116
  204. package/dist/shared/messageFormatter.d.ts +0 -39
  205. package/dist/shared/messageFormatter.js +0 -162
  206. package/dist/shared/pydanticModelGenerator.d.ts +0 -17
  207. package/dist/shared/pydanticModelGenerator.js +0 -615
  208. package/dist/shared/schemaGenerator.d.ts +0 -40
  209. package/dist/shared/schemaGenerator.js +0 -556
  210. package/dist/utils/ClientFactory.d.ts +0 -87
  211. package/dist/utils/ClientFactory.js +0 -212
  212. package/dist/utils/configDiscovery.d.ts +0 -78
  213. package/dist/utils/configDiscovery.js +0 -472
  214. package/dist/utils/constantsGenerator.d.ts +0 -31
  215. package/dist/utils/constantsGenerator.js +0 -321
  216. package/dist/utils/dataConverters.d.ts +0 -46
  217. package/dist/utils/dataConverters.js +0 -139
  218. package/dist/utils/directoryUtils.d.ts +0 -22
  219. package/dist/utils/directoryUtils.js +0 -59
  220. package/dist/utils/getClientFromConfig.d.ts +0 -39
  221. package/dist/utils/getClientFromConfig.js +0 -199
  222. package/dist/utils/helperFunctions.d.ts +0 -63
  223. package/dist/utils/helperFunctions.js +0 -156
  224. package/dist/utils/pathResolvers.d.ts +0 -53
  225. package/dist/utils/pathResolvers.js +0 -72
  226. package/dist/utils/projectConfig.d.ts +0 -119
  227. package/dist/utils/projectConfig.js +0 -171
  228. package/dist/utils/retryFailedPromises.d.ts +0 -2
  229. package/dist/utils/retryFailedPromises.js +0 -23
  230. package/dist/utils/sessionAuth.d.ts +0 -48
  231. package/dist/utils/sessionAuth.js +0 -164
  232. package/dist/utils/typeGuards.d.ts +0 -35
  233. package/dist/utils/typeGuards.js +0 -57
  234. package/dist/utils/validationRules.d.ts +0 -43
  235. package/dist/utils/validationRules.js +0 -42
  236. package/dist/utils/versionDetection.d.ts +0 -58
  237. package/dist/utils/versionDetection.js +0 -251
  238. package/dist/utils/yamlConverter.d.ts +0 -100
  239. package/dist/utils/yamlConverter.js +0 -428
  240. package/dist/utils/yamlLoader.d.ts +0 -70
  241. package/dist/utils/yamlLoader.js +0 -267
  242. package/src/adapters/AdapterFactory.ts +0 -510
  243. package/src/adapters/DatabaseAdapter.ts +0 -306
  244. package/src/adapters/LegacyAdapter.ts +0 -841
  245. package/src/adapters/TablesDBAdapter.ts +0 -773
  246. package/src/config/ConfigManager.ts +0 -808
  247. package/src/config/README.md +0 -274
  248. package/src/config/configMigration.ts +0 -575
  249. package/src/config/configValidation.ts +0 -445
  250. package/src/config/index.ts +0 -10
  251. package/src/config/services/ConfigDiscoveryService.ts +0 -463
  252. package/src/config/services/ConfigLoaderService.ts +0 -740
  253. package/src/config/services/ConfigMergeService.ts +0 -388
  254. package/src/config/services/ConfigValidationService.ts +0 -394
  255. package/src/config/services/SessionAuthService.ts +0 -565
  256. package/src/config/services/__tests__/ConfigMergeService.test.ts +0 -351
  257. package/src/config/services/index.ts +0 -29
  258. package/src/config/yamlConfig.ts +0 -761
  259. package/src/functions/pathResolution.ts +0 -227
  260. package/src/shared/attributeMapper.ts +0 -229
  261. package/src/shared/errorUtils.ts +0 -110
  262. package/src/shared/functionManager.ts +0 -525
  263. package/src/shared/indexManager.ts +0 -254
  264. package/src/shared/jsonSchemaGenerator.ts +0 -383
  265. package/src/shared/logging.ts +0 -149
  266. package/src/shared/messageFormatter.ts +0 -208
  267. package/src/shared/pydanticModelGenerator.ts +0 -618
  268. package/src/shared/schemaGenerator.ts +0 -644
  269. package/src/utils/ClientFactory.ts +0 -240
  270. package/src/utils/configDiscovery.ts +0 -557
  271. package/src/utils/constantsGenerator.ts +0 -369
  272. package/src/utils/dataConverters.ts +0 -159
  273. package/src/utils/directoryUtils.ts +0 -61
  274. package/src/utils/getClientFromConfig.ts +0 -257
  275. package/src/utils/helperFunctions.ts +0 -228
  276. package/src/utils/pathResolvers.ts +0 -81
  277. package/src/utils/projectConfig.ts +0 -299
  278. package/src/utils/retryFailedPromises.ts +0 -29
  279. package/src/utils/sessionAuth.ts +0 -230
  280. package/src/utils/typeGuards.ts +0 -65
  281. package/src/utils/validationRules.ts +0 -88
  282. package/src/utils/versionDetection.ts +0 -292
  283. package/src/utils/yamlConverter.ts +0 -542
  284. package/src/utils/yamlLoader.ts +0 -371
@@ -1,7 +1,7 @@
1
1
  import { Client, Databases, Query, Storage, Users, } from "node-appwrite";
2
2
  import {} from "@njdamstra/appwrite-utils";
3
3
  import { findAppwriteConfig, findFunctionsDir, } from "./utils/loadConfigs.js";
4
- import { normalizeFunctionName, validateFunctionDirectory } from './functions/pathResolution.js';
4
+ import { normalizeFunctionName, validateFunctionDirectory } from '@njdamstra/appwrite-utils-helpers';
5
5
  import { UsersController } from "./users/methods.js";
6
6
  import { AppwriteToX } from "./migrations/appwriteToX.js";
7
7
  import { ImportController } from "./migrations/importController.js";
@@ -14,22 +14,18 @@ import path from "path";
14
14
  import { converterFunctions, validationRules, } from "@njdamstra/appwrite-utils";
15
15
  import { afterImportActions } from "./migrations/afterImportActions.js";
16
16
  import { transferDatabaseLocalToLocal, transferDatabaseLocalToRemote, transferStorageLocalToLocal, transferStorageLocalToRemote, transferUsersLocalToRemote, } from "./migrations/transfer.js";
17
- import { getClient, getClientWithAuth } from "./utils/getClientFromConfig.js";
18
- import { getAdapterFromConfig } from "./utils/getClientFromConfig.js";
19
- import { hasSessionAuth, findSessionByEndpointAndProject, isValidSessionCookie } from "./utils/sessionAuth.js";
17
+ import { getClient, getClientWithAuth } from "@njdamstra/appwrite-utils-helpers";
18
+ import { getAdapterFromConfig } from "@njdamstra/appwrite-utils-helpers";
19
+ import { hasSessionAuth, findSessionByEndpointAndProject, isValidSessionCookie } from "@njdamstra/appwrite-utils-helpers";
20
20
  import { fetchAllDatabases } from "./databases/methods.js";
21
21
  import { listFunctions, updateFunctionSpecifications, } from "./functions/methods.js";
22
22
  import chalk from "chalk";
23
23
  import { deployLocalFunction } from "./functions/deployments.js";
24
24
  import fs from "node:fs";
25
- import { configureLogging, updateLogger, logger } from "./shared/logging.js";
26
- import { MessageFormatter, Messages } from "./shared/messageFormatter.js";
27
- import { SchemaGenerator } from "./shared/schemaGenerator.js";
28
- import { findYamlConfig } from "./config/yamlConfig.js";
25
+ import { configureLogging, updateLogger, logger, MessageFormatter, Messages, SchemaGenerator, findYamlConfig, validateCollectionsTablesConfig, reportValidationResults, validateWithStrictMode, ConfigManager } from "@njdamstra/appwrite-utils-helpers";
29
26
  import { createImportSchemas } from "./migrations/yaml/generateImportSchemas.js";
30
- import { validateCollectionsTablesConfig, reportValidationResults, validateWithStrictMode } from "./config/configValidation.js";
31
- import { ConfigManager } from "./config/ConfigManager.js";
32
- import { ClientFactory } from "./utils/ClientFactory.js";
27
+ import { ClientFactory } from "@njdamstra/appwrite-utils-helpers";
28
+ import { clearProcessingState, processQueue } from "./shared/operationQueue.js";
33
29
  export class UtilsController {
34
30
  // ──────────────────────────────────────────────────
35
31
  // SINGLETON PATTERN
@@ -151,7 +147,7 @@ export class UtilsController {
151
147
  }
152
148
  }
153
149
  async init(options = {}) {
154
- const { validate = false, strictMode = false } = options;
150
+ const { validate = false, strictMode = false, preferJson = false, useSession, sessionCookie, overrides } = options;
155
151
  const configManager = ConfigManager.getInstance();
156
152
  // Load config if not already loaded
157
153
  if (!configManager.hasConfig()) {
@@ -159,6 +155,10 @@ export class UtilsController {
159
155
  configDir: this.currentUserDir,
160
156
  validate,
161
157
  strictMode,
158
+ preferJson,
159
+ useSession,
160
+ explicitSessionCookie: sessionCookie,
161
+ overrides,
162
162
  });
163
163
  }
164
164
  const config = configManager.getConfig();
@@ -351,7 +351,7 @@ export class UtilsController {
351
351
  MessageFormatter.error(`Function ${functionName} not found in config`, undefined, { prefix: "Controller" });
352
352
  return;
353
353
  }
354
- await deployLocalFunction(this.appwriteServer, functionName, functionConfig, functionPath);
354
+ await deployLocalFunction(this.appwriteServer, functionName, functionConfig, functionPath, this.appwriteFolderPath);
355
355
  }
356
356
  async syncFunctions() {
357
357
  await this.init();
@@ -457,7 +457,6 @@ export class UtilsController {
457
457
  // Ensure we don't carry state between databases in a multi-db push
458
458
  // This resets processed sets and name->id mapping per database
459
459
  try {
460
- const { clearProcessingState } = await import('./shared/operationQueue.js');
461
460
  clearProcessingState();
462
461
  }
463
462
  catch { }
@@ -474,6 +473,15 @@ export class UtilsController {
474
473
  logger.debug("Adapter unavailable, falling back to legacy Databases path", { prefix: "UtilsController" });
475
474
  await createOrUpdateCollections(this.database, database.$id, this.config, deletedCollections, collections);
476
475
  }
476
+ // Safety net: Process any remaining queued operations to complete relationship sync
477
+ try {
478
+ MessageFormatter.info(`🔄 Processing final operation queue for database ${database.$id}`, { prefix: "UtilsController" });
479
+ await processQueue(this.adapter || this.database, database.$id);
480
+ MessageFormatter.info(`✅ Operation queue processing completed`, { prefix: "UtilsController" });
481
+ }
482
+ catch (error) {
483
+ MessageFormatter.error(`Failed to process operation queue`, error instanceof Error ? error : new Error(String(error)), { prefix: 'UtilsController' });
484
+ }
477
485
  }
478
486
  async generateSchemas() {
479
487
  // Schema generation doesn't need Appwrite connection, just config
@@ -638,20 +646,38 @@ export class UtilsController {
638
646
  MessageFormatter.progress("Starting selective push (local config → Appwrite)...", { prefix: "Controller" });
639
647
  // Convert database selections to Models.Database format
640
648
  const selectedDatabases = [];
649
+ const serverDatabases = await fetchAllDatabases(this.database);
650
+ const configuredDatabases = this.config?.databases || [];
641
651
  for (const dbSelection of databaseSelections) {
642
- // Get the full database object from the controller
643
- const databases = await fetchAllDatabases(this.database);
644
- const database = databases.find(db => db.$id === dbSelection.databaseId);
645
- if (database) {
646
- selectedDatabases.push(database);
647
- MessageFormatter.info(`Selected database: ${database.name} (${database.$id})`, { prefix: "Controller" });
648
- // Log selected tables for this database
649
- if (dbSelection.tableIds && dbSelection.tableIds.length > 0) {
650
- MessageFormatter.info(` Tables: ${dbSelection.tableIds.join(', ')}`, { prefix: "Controller" });
651
- }
652
+ // First try to find on server
653
+ const serverDb = serverDatabases.find(db => db.$id === dbSelection.databaseId);
654
+ if (serverDb) {
655
+ selectedDatabases.push(serverDb);
656
+ MessageFormatter.info(`Selected database: ${serverDb.name} (${serverDb.$id})`, { prefix: "Controller" });
652
657
  }
653
658
  else {
654
- MessageFormatter.warning(`Database with ID ${dbSelection.databaseId} not found`, { prefix: "Controller" });
659
+ // Database doesn't exist on server - check if it's in local config
660
+ const configDb = configuredDatabases.find((db) => db.$id === dbSelection.databaseId);
661
+ if (configDb) {
662
+ // Create a pseudo-database object that ensureDatabasesExist will create
663
+ const dbId = configDb.$id;
664
+ selectedDatabases.push({
665
+ $id: dbId,
666
+ name: configDb.name || dbId,
667
+ $createdAt: new Date().toISOString(),
668
+ $updatedAt: new Date().toISOString(),
669
+ enabled: true,
670
+ });
671
+ MessageFormatter.info(`Selected database: ${configDb.name || dbId} (${dbId}) [will be created]`, { prefix: "Controller" });
672
+ }
673
+ else {
674
+ MessageFormatter.warning(`Database with ID ${dbSelection.databaseId} not found in server or local config`, { prefix: "Controller" });
675
+ continue;
676
+ }
677
+ }
678
+ // Log selected tables for this database
679
+ if (dbSelection.tableIds && dbSelection.tableIds.length > 0) {
680
+ MessageFormatter.info(` Tables: ${dbSelection.tableIds.join(', ')}`, { prefix: "Controller" });
655
681
  }
656
682
  }
657
683
  if (selectedDatabases.length === 0) {
@@ -670,7 +696,10 @@ export class UtilsController {
670
696
  // Build database-specific collection mappings from databaseSelections
671
697
  const databaseCollectionsMap = new Map();
672
698
  // Get all collections/tables from config (they're at the root level, not nested in databases)
673
- const allCollections = this.config?.collections || this.config?.tables || [];
699
+ const allCollections = [
700
+ ...(this.config?.collections || []),
701
+ ...(this.config?.tables || [])
702
+ ];
674
703
  // Create database-specific collection mapping to preserve relationships
675
704
  for (const dbSelection of databaseSelections) {
676
705
  const collectionsForDatabase = [];
@@ -760,10 +789,10 @@ export class UtilsController {
760
789
  return;
761
790
  }
762
791
  if (options.isRemote && targetClient) {
763
- await transferDatabaseLocalToRemote(sourceClient, options.transferEndpoint, options.transferProject, options.transferKey, fromDb.$id, targetDb.$id);
792
+ await transferDatabaseLocalToRemote(sourceClient, options.transferEndpoint, options.transferProject, options.transferKey, fromDb.$id, targetDb.$id, options.collections);
764
793
  }
765
794
  else {
766
- await transferDatabaseLocalToLocal(sourceClient, fromDb.$id, targetDb.$id);
795
+ await transferDatabaseLocalToLocal(sourceClient, fromDb.$id, targetDb.$id, options.collections, this.adapter);
767
796
  }
768
797
  }
769
798
  if (options.transferUsers) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@njdamstra/appwrite-utils-cli",
3
3
  "description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
4
- "version": "1.8.9",
5
- "main": "src/main.ts",
4
+ "version": "1.10.0",
5
+ "main": "dist/main.js",
6
6
  "type": "module",
7
7
  "repository": {
8
8
  "type": "git",
@@ -39,12 +39,14 @@
39
39
  "@types/inquirer": "^9.0.8",
40
40
  "@types/json-schema": "^7.0.15",
41
41
  "@types/yargs": "^17.0.33",
42
- "@njdamstra/appwrite-utils": "^1.6.5",
42
+ "@njdamstra/appwrite-utils": "^1.7.0",
43
+ "@njdamstra/appwrite-utils-helpers": "^0.1.1",
43
44
  "chalk": "^5.4.1",
44
45
  "cli-progress": "^3.12.0",
45
46
  "commander": "^12.1.0",
46
47
  "decimal.js": "^10.6.0",
47
48
  "es-toolkit": "^1.39.4",
49
+ "find-up": "^8.0.0",
48
50
  "ignore": "^6.0.2",
49
51
  "inquirer": "^9.3.7",
50
52
  "js-yaml": "^4.1.0",
@@ -53,6 +55,7 @@
53
55
  "nanostores": "^0.10.3",
54
56
  "node-appwrite": "^20.2.1",
55
57
  "p-limit": "^6.2.0",
58
+ "papaparse": "^5.5.3",
56
59
  "tar": "^7.4.3",
57
60
  "tsx": "^4.20.3",
58
61
  "ulidx": "^2.4.1",
@@ -68,6 +71,7 @@
68
71
  "@types/jszip": "^3.4.1",
69
72
  "@types/lodash": "^4.17.18",
70
73
  "@types/luxon": "^3.6.2",
74
+ "@types/papaparse": "^5.5.2",
71
75
  "jest": "^29.7.0",
72
76
  "ts-jest": "^29.1.2",
73
77
  "typescript": "^5.8.3"
@@ -1,37 +1,11 @@
1
1
  /**
2
- * Adapters Module - Unified Database API for Appwrite
3
- *
4
- * This module exports all adapter classes and utilities for working with
5
- * both legacy Appwrite (collections/documents) and TablesDB (tables/rows) APIs.
2
+ * Adapters Module - Re-exported from appwrite-utils-helpers
3
+ *
4
+ * This module re-exports all adapter classes and utilities from the
5
+ * appwrite-utils-helpers package for backward compatibility.
6
+ *
7
+ * The adapters have been moved to the helpers package to make them
8
+ * available to other packages and reduce code duplication.
6
9
  */
7
10
 
8
- export { AdapterFactory, type AdapterFactoryConfig, type AdapterFactoryResult } from './AdapterFactory.js';
9
- export {
10
- type DatabaseAdapter,
11
- type CreateRowParams,
12
- type UpdateRowParams,
13
- type ListRowsParams,
14
- type DeleteRowParams,
15
- type CreateTableParams,
16
- type UpdateTableParams,
17
- type ListTablesParams,
18
- type DeleteTableParams,
19
- type GetTableParams,
20
- type BulkCreateRowsParams,
21
- type BulkUpsertRowsParams,
22
- type BulkDeleteRowsParams,
23
- type CreateIndexParams,
24
- type ListIndexesParams,
25
- type DeleteIndexParams,
26
- type CreateAttributeParams,
27
- type UpdateAttributeParams,
28
- type DeleteAttributeParams,
29
- type ApiResponse,
30
- type AdapterMetadata,
31
- BaseAdapter
32
- } from './DatabaseAdapter.js';
33
- export { TablesDBAdapter } from './TablesDBAdapter.js';
34
- export { LegacyAdapter } from './LegacyAdapter.js';
35
-
36
- // Convenience exports
37
- export { createDatabaseAdapter, getApiCapabilities } from './AdapterFactory.js';
11
+ export * from '@njdamstra/appwrite-utils-helpers';
@@ -3,8 +3,8 @@ import JSZip from "jszip";
3
3
  import { ID, Query } from "node-appwrite";
4
4
  import { InputFile } from "node-appwrite/file";
5
5
  import pLimit from "p-limit";
6
- import { MessageFormatter } from "../../shared/messageFormatter.js";
7
- import { logger } from "../../shared/logging.js";
6
+ import { MessageFormatter } from '@njdamstra/appwrite-utils-helpers';
7
+ import { logger } from '@njdamstra/appwrite-utils-helpers';
8
8
  import type { BucketManifest, BucketFileMetadata } from "../schemas/bucketManifest.js";
9
9
  import { ulid } from "ulidx";
10
10
 
@@ -2,12 +2,12 @@ import type { Storage, Databases, Models } from "node-appwrite";
2
2
  import { ID, Query } from "node-appwrite";
3
3
  import { InputFile } from "node-appwrite/file";
4
4
  import { ulid } from "ulidx";
5
- import { MessageFormatter } from "../../shared/messageFormatter.js";
6
- import { logger } from "../../shared/logging.js";
7
- import type { DatabaseAdapter } from "../../adapters/DatabaseAdapter.js";
5
+ import { MessageFormatter } from '@njdamstra/appwrite-utils-helpers';
6
+ import { logger } from '@njdamstra/appwrite-utils-helpers';
7
+ import type { DatabaseAdapter } from '@njdamstra/appwrite-utils-helpers';
8
8
  import { tryAwaitWithRetry } from "@njdamstra/appwrite-utils";
9
9
  import { splitIntoBatches } from "../../shared/migrationHelpers.js";
10
- import { retryFailedPromises } from "../../utils/retryFailedPromises.js";
10
+ import { retryFailedPromises } from "@njdamstra/appwrite-utils-helpers";
11
11
  import { ProgressManager } from "../../shared/progressManager.js";
12
12
  import { createBackupZip } from "../../storage/backupCompression.js";
13
13
  import {
@@ -2,9 +2,9 @@ import type { Storage, Databases, Models } from "node-appwrite";
2
2
  import { ID } from "node-appwrite";
3
3
  import { InputFile } from "node-appwrite/file";
4
4
  import { ulid } from "ulidx";
5
- import { MessageFormatter } from "../../shared/messageFormatter.js";
6
- import { logger } from "../../shared/logging.js";
7
- import type { DatabaseAdapter } from "../../adapters/DatabaseAdapter.js";
5
+ import { MessageFormatter } from '@njdamstra/appwrite-utils-helpers';
6
+ import { logger } from '@njdamstra/appwrite-utils-helpers';
7
+ import type { DatabaseAdapter } from '@njdamstra/appwrite-utils-helpers';
8
8
  import { backupDatabase } from "../../storage/methods.js";
9
9
  import { backupBucket } from "./bucketBackup.js";
10
10
  import {
@@ -1,6 +1,6 @@
1
- import type { DatabaseAdapter } from "../../adapters/DatabaseAdapter.js";
2
- import { logger } from "../../shared/logging.js";
3
- import { tryAwaitWithRetry } from "../../utils/helperFunctions.js";
1
+ import type { DatabaseAdapter } from '@njdamstra/appwrite-utils-helpers';
2
+ import { logger } from '@njdamstra/appwrite-utils-helpers';
3
+ import { tryAwaitWithRetry } from "@njdamstra/appwrite-utils-helpers";
4
4
  import { Query, ID } from "node-appwrite";
5
5
  import {
6
6
  BACKUP_TABLE_ID,
@@ -1,20 +1,27 @@
1
1
  import inquirer from "inquirer";
2
- import { MessageFormatter } from "../../shared/messageFormatter.js";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { MessageFormatter } from '@njdamstra/appwrite-utils-helpers';
3
5
  import { migrateConfig } from "../../utils/configMigration.js";
4
6
  import {
5
7
  validateCollectionsTablesConfig,
6
8
  reportValidationResults,
7
- } from "../../config/configValidation.js";
9
+ ConfigManager,
10
+ findAppwriteConfig,
11
+ findYamlConfig,
12
+ YamlLoader,
13
+ resolveCollectionsDir,
14
+ resolveTablesDir
15
+ } from "@njdamstra/appwrite-utils-helpers";
8
16
  import {
9
17
  createMigrationPlan,
10
18
  executeMigrationPlan,
11
19
  saveMigrationResult,
12
20
  type MigrationStrategy,
13
- } from "../../config/configMigration.js";
21
+ } from '@njdamstra/appwrite-utils-helpers';
14
22
  import { createEmptyCollection } from "../../utils/setupFiles.js";
15
23
  import chalk from "chalk";
16
24
  import type { InteractiveCLI } from "../../interactiveCLI.js";
17
- import { ConfigManager } from "../../config/ConfigManager.js";
18
25
  import { UtilsController } from "../../utilsController.js";
19
26
 
20
27
  export const configCommands = {
@@ -56,7 +63,7 @@ export const configCommands = {
56
63
  return;
57
64
  }
58
65
 
59
- const { validateCollectionsTablesConfig, reportValidationResults } = await import("../../config/configValidation.js");
66
+ const { validateCollectionsTablesConfig, reportValidationResults } = await import("@njdamstra/appwrite-utils-helpers");
60
67
  const validation = validateCollectionsTablesConfig(config);
61
68
 
62
69
  reportValidationResults(validation, { verbose: true });
@@ -78,6 +85,9 @@ export const configCommands = {
78
85
 
79
86
  await (cli as any).initControllerIfNeeded();
80
87
 
88
+ const currentDir = (cli as any).currentDir;
89
+ const yamlConfigPath = findYamlConfig(currentDir);
90
+
81
91
  // Ensure config is properly loaded with YAML collections
82
92
  if (!(cli as any).controller?.config) {
83
93
  MessageFormatter.error("No configuration found", undefined, { prefix: "Migration" });
@@ -90,8 +100,6 @@ export const configCommands = {
90
100
  return;
91
101
  }
92
102
 
93
- const { createMigrationPlan, executeMigrationPlan, saveMigrationResult } = await import("../../config/configMigration.js");
94
-
95
103
  // Get user's migration strategy preference
96
104
  const { strategy } = await inquirer.prompt([
97
105
  {
@@ -106,6 +114,60 @@ export const configCommands = {
106
114
  }
107
115
  ]);
108
116
 
117
+ if (yamlConfigPath) {
118
+ const appwriteDir = path.dirname(yamlConfigPath);
119
+ const collectionsDir = resolveCollectionsDir(appwriteDir);
120
+ const tablesDir = resolveTablesDir(appwriteDir);
121
+
122
+ if (!fs.existsSync(collectionsDir)) {
123
+ MessageFormatter.error(`Collections directory not found: ${collectionsDir}`, undefined, { prefix: "Migration" });
124
+ return;
125
+ }
126
+
127
+ const collectionFiles = fs
128
+ .readdirSync(collectionsDir)
129
+ .filter(file => file.endsWith(".yaml") || file.endsWith(".yml"));
130
+
131
+ if (collectionFiles.length === 0) {
132
+ MessageFormatter.error("No YAML collection files found to migrate.", undefined, { prefix: "Migration" });
133
+ return;
134
+ }
135
+
136
+ const { confirmed } = await inquirer.prompt([
137
+ {
138
+ type: "confirm",
139
+ name: "confirmed",
140
+ message: `Proceed with migration? This will process ${collectionFiles.length} file(s).`,
141
+ default: false
142
+ }
143
+ ]);
144
+
145
+ if (!confirmed) {
146
+ MessageFormatter.info("Migration cancelled by user", { prefix: "Migration" });
147
+ return;
148
+ }
149
+
150
+ const yamlLoader = new YamlLoader(appwriteDir);
151
+ const result = await yamlLoader.migrateTerminology(
152
+ path.relative(appwriteDir, collectionsDir),
153
+ path.relative(appwriteDir, tablesDir),
154
+ true
155
+ );
156
+
157
+ if (result.errors.length > 0) {
158
+ MessageFormatter.warning(`Migration completed with ${result.errors.length} error(s).`, { prefix: "Migration" });
159
+ }
160
+
161
+ if (strategy === "move") {
162
+ const backupDir = `${collectionsDir}.backup.${Date.now()}`;
163
+ fs.renameSync(collectionsDir, backupDir);
164
+ MessageFormatter.info(`Collections moved to ${path.basename(backupDir)}`, { prefix: "Migration" });
165
+ }
166
+
167
+ MessageFormatter.success(`Collections migrated to tables (${result.migrated} converted, ${result.skipped} skipped).`, { prefix: "Migration" });
168
+ return;
169
+ }
170
+
109
171
  // Map user-friendly strategy names to internal MigrationStrategy types
110
172
  const migrationStrategy = strategy === "move" ? "full_migration" :
111
173
  strategy === "copy" || strategy === "dual" ? "dual_format" : "full_migration";
@@ -122,7 +184,9 @@ export const configCommands = {
122
184
 
123
185
  if (confirmed) {
124
186
  const result = executeMigrationPlan((cli as any).controller.config, plan);
125
- await saveMigrationResult(result, (cli as any).currentDir);
187
+ const configDir = findAppwriteConfig(currentDir) || currentDir;
188
+ const outputPath = path.join(configDir, "appwriteConfig.ts");
189
+ await saveMigrationResult(result, outputPath, { originalConfigPath: outputPath });
126
190
 
127
191
  MessageFormatter.success("Collections to tables migration completed!", { prefix: "Migration" });
128
192
  } else {
@@ -1,14 +1,16 @@
1
1
  import inquirer from "inquirer";
2
2
  import chalk from "chalk";
3
3
  import { join } from "node:path";
4
- import { MessageFormatter } from "../../shared/messageFormatter.js";
4
+ import { Query } from "node-appwrite";
5
+ import { MessageFormatter } from '@njdamstra/appwrite-utils-helpers';
5
6
  import { ConfirmationDialogs } from "../../shared/confirmationDialogs.js";
6
7
  import { SelectionDialogs } from "../../shared/selectionDialogs.js";
7
8
  import type { DatabaseSelection, BucketSelection } from "../../shared/selectionDialogs.js";
8
- import { logger } from "../../shared/logging.js";
9
+ import { logger } from '@njdamstra/appwrite-utils-helpers';
9
10
  import { fetchAllDatabases } from "../../databases/methods.js";
10
11
  import { listBuckets } from "../../storage/methods.js";
11
12
  import { getFunction, downloadLatestFunctionDeployment } from "../../functions/methods.js";
13
+ import { wipeTableRows } from "../../collections/wipeOperations.js";
12
14
  import type { InteractiveCLI } from "../../interactiveCLI.js";
13
15
 
14
16
  export const databaseCommands = {
@@ -19,18 +21,40 @@ export const databaseCommands = {
19
21
  // Initialize controller
20
22
  await (cli as any).controller!.init();
21
23
 
22
- // Get available and configured databases
23
- const availableDatabases = await fetchAllDatabases((cli as any).controller!.database!);
24
+ // Get available databases from server and configured databases from local config
25
+ const serverDatabases = await fetchAllDatabases((cli as any).controller!.database!);
24
26
  const configuredDatabases = (cli as any).controller!.config?.databases || [];
25
27
 
28
+ // For PUSH operations: Merge local configured databases with server databases
29
+ // This allows pushing databases that don't exist on the server yet
30
+ const serverDbIds = new Set(serverDatabases.map(db => db.$id));
31
+ const mergedDatabases = [...serverDatabases];
32
+
33
+ // Add locally configured databases that don't exist on server yet
34
+ for (const configDb of configuredDatabases) {
35
+ const dbId = configDb.$id;
36
+ if (dbId && !serverDbIds.has(dbId)) {
37
+ // Create a pseudo-database object for selection
38
+ mergedDatabases.push({
39
+ $id: dbId,
40
+ name: configDb.name || dbId,
41
+ $createdAt: new Date().toISOString(),
42
+ $updatedAt: new Date().toISOString(),
43
+ enabled: true,
44
+ _isLocalOnly: true, // Mark as not yet on server
45
+ } as any);
46
+ MessageFormatter.info(`Including local database "${configDb.name || dbId}" (not yet on server)`, { prefix: "Database" });
47
+ }
48
+ }
49
+
26
50
  // Get local collections for selection
27
51
  const localCollections = (cli as any).getLocalCollections();
28
52
 
29
53
  // Push operations always use local configuration as source of truth
30
54
 
31
- // Select databases
55
+ // Select databases (now includes locally configured databases that don't exist on server)
32
56
  const selectedDatabaseIds = await SelectionDialogs.selectDatabases(
33
- availableDatabases,
57
+ mergedDatabases,
34
58
  configuredDatabases,
35
59
  { showSelectAll: false, allowNewOnly: false, defaultSelected: [] }
36
60
  );
@@ -45,7 +69,7 @@ export const databaseCommands = {
45
69
  const availableTablesMap = new Map<string, any[]>();
46
70
 
47
71
  for (const databaseId of selectedDatabaseIds) {
48
- const database = availableDatabases.find(db => db.$id === databaseId)!;
72
+ const database = mergedDatabases.find(db => db.$id === databaseId)!;
49
73
 
50
74
  // Use the existing selectCollectionsAndTables method
51
75
  const selectedCollections = await (cli as any).selectCollectionsAndTables(
@@ -106,7 +130,7 @@ export const databaseCommands = {
106
130
  selectedBucketIds,
107
131
  availableBuckets,
108
132
  configuredBuckets,
109
- availableDatabases
133
+ mergedDatabases
110
134
  );
111
135
 
112
136
  MessageFormatter.info(`Selected ${bucketSelections.length} storage bucket(s)`, { prefix: "Database" });
@@ -121,7 +145,7 @@ export const databaseCommands = {
121
145
  // Create DatabaseSelection objects
122
146
  const databaseSelections = SelectionDialogs.createDatabaseSelection(
123
147
  selectedDatabaseIds,
124
- availableDatabases,
148
+ mergedDatabases,
125
149
  tableSelectionsMap,
126
150
  configuredDatabases,
127
151
  availableTablesMap
@@ -745,5 +769,133 @@ export const databaseCommands = {
745
769
  }
746
770
  }
747
771
  MessageFormatter.success("Wipe collections operation completed", { prefix: "Wipe" });
772
+ },
773
+
774
+ async wipeTablesData(cli: InteractiveCLI): Promise<void> {
775
+ const controller = (cli as any).controller;
776
+
777
+ if (!controller?.adapter) {
778
+ throw new Error(
779
+ "Database adapter is not initialized. TablesDB operations require adapter support."
780
+ );
781
+ }
782
+
783
+ try {
784
+ // Step 1: Select database (single selection for clearer UX)
785
+ const databases = await fetchAllDatabases(controller.database);
786
+
787
+ if (!databases || databases.length === 0) {
788
+ MessageFormatter.warning("No databases found", { prefix: "Wipe" });
789
+ return;
790
+ }
791
+
792
+ const { selectedDatabase } = await inquirer.prompt([
793
+ {
794
+ type: "list",
795
+ name: "selectedDatabase",
796
+ message: "Select database containing tables to wipe:",
797
+ choices: databases.map((db: any) => ({
798
+ name: `${db.name} (${db.$id})`,
799
+ value: db
800
+ }))
801
+ }
802
+ ]);
803
+
804
+ const database = selectedDatabase;
805
+
806
+ // Step 2: Get available tables
807
+ const adapter = controller.adapter;
808
+ const tablesResponse = await adapter.listTables({
809
+ databaseId: database.$id,
810
+ queries: [Query.limit(500)]
811
+ });
812
+ const availableTables = (tablesResponse as any).tables || [];
813
+
814
+ if (availableTables.length === 0) {
815
+ MessageFormatter.warning(`No tables found in database: ${database.name}`, { prefix: "Wipe" });
816
+ return;
817
+ }
818
+
819
+ // Step 3: Select tables using existing SelectionDialogs
820
+ const selectedTableIds = await SelectionDialogs.selectTablesForDatabase(
821
+ database.$id,
822
+ database.name,
823
+ availableTables,
824
+ [], // No configured tables context needed for wipe
825
+ {
826
+ showSelectAll: true,
827
+ allowNewOnly: false,
828
+ defaultSelected: []
829
+ }
830
+ );
831
+
832
+ if (selectedTableIds.length === 0) {
833
+ MessageFormatter.warning("No tables selected. Operation cancelled.", { prefix: "Wipe" });
834
+ return;
835
+ }
836
+
837
+ // Step 4: Show confirmation with table details
838
+ const selectedTables = availableTables.filter((t: any) =>
839
+ selectedTableIds.includes(t.$id)
840
+ );
841
+ const tableNames = selectedTables.map((t: any) => t.name);
842
+
843
+ console.log(chalk.yellow.bold("\n⚠️ WARNING: Table Row Wipe Operation"));
844
+ console.log(chalk.yellow("This will delete ALL ROWS from the selected tables."));
845
+ console.log(chalk.yellow("The table structures will remain intact.\n"));
846
+ console.log(chalk.cyan("Database:"), chalk.white(database.name));
847
+ console.log(chalk.cyan("Tables to wipe:"));
848
+ tableNames.forEach((name: string) => console.log(chalk.white(` • ${name}`)));
849
+ console.log();
850
+
851
+ const { confirmed } = await inquirer.prompt([
852
+ {
853
+ type: "confirm",
854
+ name: "confirmed",
855
+ message: chalk.red.bold("Are you ABSOLUTELY SURE you want to wipe these table rows?"),
856
+ default: false
857
+ }
858
+ ]);
859
+
860
+ if (!confirmed) {
861
+ MessageFormatter.info("Wipe operation cancelled by user", { prefix: "Wipe" });
862
+ return;
863
+ }
864
+
865
+ // Step 5: Execute wipe using existing wipeTableRows function
866
+ MessageFormatter.progress("Starting table row wipe operation...", { prefix: "Wipe" });
867
+
868
+ for (const table of selectedTables) {
869
+ try {
870
+ MessageFormatter.info(`Wiping rows from table: ${table.name}`, { prefix: "Wipe" });
871
+
872
+ // Use existing wipeTableRows from wipeOperations.ts
873
+ await wipeTableRows(adapter, database.$id, table.$id);
874
+
875
+ MessageFormatter.success(
876
+ `Successfully wiped rows from table: ${table.name}`,
877
+ { prefix: "Wipe" }
878
+ );
879
+ } catch (error) {
880
+ MessageFormatter.error(
881
+ `Failed to wipe table ${table.name}`,
882
+ error instanceof Error ? error : new Error(String(error)),
883
+ { prefix: "Wipe" }
884
+ );
885
+ }
886
+ }
887
+
888
+ MessageFormatter.success(
889
+ `Wipe operation completed for ${selectedTables.length} table(s)`,
890
+ { prefix: "Wipe" }
891
+ );
892
+ } catch (error) {
893
+ MessageFormatter.error(
894
+ "Table wipe operation failed",
895
+ error instanceof Error ? error : new Error(String(error)),
896
+ { prefix: "Wipe" }
897
+ );
898
+ throw error;
899
+ }
748
900
  }
749
901
  };