@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.
- package/CHANGELOG.md +16 -0
- package/CONFIG_TODO.md +1189 -0
- package/SELECTION_DIALOGS.md +146 -0
- package/SERVICE_IMPLEMENTATION_REPORT.md +462 -0
- package/dist/adapters/index.d.ts +7 -8
- package/dist/adapters/index.js +7 -9
- package/dist/backups/operations/bucketBackup.js +2 -2
- package/dist/backups/operations/collectionBackup.d.ts +1 -1
- package/dist/backups/operations/collectionBackup.js +3 -3
- package/dist/backups/operations/comprehensiveBackup.d.ts +1 -1
- package/dist/backups/operations/comprehensiveBackup.js +2 -2
- package/dist/backups/tracking/centralizedTracking.d.ts +1 -1
- package/dist/backups/tracking/centralizedTracking.js +2 -2
- package/dist/cli/commands/configCommands.js +51 -7
- package/dist/cli/commands/databaseCommands.d.ts +1 -0
- package/dist/cli/commands/databaseCommands.js +119 -9
- package/dist/cli/commands/functionCommands.js +3 -3
- package/dist/cli/commands/importFileCommands.d.ts +7 -0
- package/dist/cli/commands/importFileCommands.js +674 -0
- package/dist/cli/commands/schemaCommands.js +3 -3
- package/dist/cli/commands/storageCommands.js +2 -3
- package/dist/cli/commands/transferCommands.js +3 -5
- package/dist/collections/attributes.d.ts +1 -1
- package/dist/collections/attributes.js +2 -35
- package/dist/collections/indexes.js +1 -3
- package/dist/collections/methods.d.ts +1 -1
- package/dist/collections/methods.js +111 -192
- package/dist/collections/tableOperations.d.ts +1 -0
- package/dist/collections/tableOperations.js +55 -23
- package/dist/collections/transferOperations.d.ts +1 -1
- package/dist/collections/transferOperations.js +3 -4
- package/dist/collections/wipeOperations.d.ts +4 -3
- package/dist/collections/wipeOperations.js +112 -39
- package/dist/databases/methods.js +2 -2
- package/dist/databases/setup.js +2 -2
- package/dist/examples/yamlTerminologyExample.js +2 -2
- package/dist/functions/deployments.d.ts +1 -1
- package/dist/functions/deployments.js +5 -5
- package/dist/functions/fnConfigDiscovery.js +2 -2
- package/dist/functions/methods.js +16 -4
- package/dist/init.js +1 -1
- package/dist/interactiveCLI.d.ts +6 -1
- package/dist/interactiveCLI.js +63 -9
- package/dist/main.js +130 -177
- package/dist/migrations/afterImportActions.js +2 -3
- package/dist/migrations/appwriteToX.d.ts +1 -1
- package/dist/migrations/appwriteToX.js +9 -7
- package/dist/migrations/comprehensiveTransfer.js +3 -5
- package/dist/migrations/dataLoader.js +2 -5
- package/dist/migrations/importController.js +3 -4
- package/dist/migrations/importDataActions.js +3 -3
- package/dist/migrations/relationships.js +1 -2
- package/dist/migrations/services/DataTransformationService.js +2 -2
- package/dist/migrations/services/FileHandlerService.js +1 -1
- package/dist/migrations/services/ImportOrchestrator.js +4 -4
- package/dist/migrations/services/RateLimitManager.js +1 -1
- package/dist/migrations/services/RelationshipResolver.js +1 -1
- package/dist/migrations/services/UserMappingService.js +1 -1
- package/dist/migrations/services/ValidationService.js +1 -1
- package/dist/migrations/transfer.d.ts +8 -4
- package/dist/migrations/transfer.js +106 -55
- package/dist/migrations/yaml/YamlImportConfigLoader.js +1 -1
- package/dist/migrations/yaml/YamlImportIntegration.js +2 -2
- package/dist/migrations/yaml/generateImportSchemas.js +1 -1
- package/dist/setupCommands.d.ts +1 -1
- package/dist/setupCommands.js +5 -6
- package/dist/setupController.js +1 -1
- package/dist/shared/backupTracking.d.ts +1 -1
- package/dist/shared/backupTracking.js +2 -2
- package/dist/shared/confirmationDialogs.js +1 -1
- package/dist/shared/migrationHelpers.d.ts +1 -1
- package/dist/shared/migrationHelpers.js +3 -3
- package/dist/shared/operationQueue.d.ts +1 -1
- package/dist/shared/operationQueue.js +2 -3
- package/dist/shared/operationsTable.d.ts +1 -1
- package/dist/shared/operationsTable.js +2 -2
- package/dist/shared/progressManager.js +1 -1
- package/dist/shared/selectionDialogs.js +9 -8
- package/dist/storage/methods.js +4 -4
- package/dist/storage/schemas.d.ts +2 -2
- package/dist/tables/indexManager.d.ts +65 -0
- package/dist/tables/indexManager.js +294 -0
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/dist/users/methods.js +2 -3
- package/dist/utils/configMigration.js +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/loadConfigs.d.ts +2 -2
- package/dist/utils/loadConfigs.js +6 -7
- package/dist/utils/setupFiles.js +5 -7
- package/dist/utilsController.d.ts +15 -8
- package/dist/utilsController.js +57 -28
- package/package.json +7 -3
- package/src/adapters/index.ts +8 -34
- package/src/backups/operations/bucketBackup.ts +2 -2
- package/src/backups/operations/collectionBackup.ts +4 -4
- package/src/backups/operations/comprehensiveBackup.ts +3 -3
- package/src/backups/tracking/centralizedTracking.ts +3 -3
- package/src/cli/commands/configCommands.ts +72 -8
- package/src/cli/commands/databaseCommands.ts +161 -9
- package/src/cli/commands/functionCommands.ts +4 -3
- package/src/cli/commands/importFileCommands.ts +815 -0
- package/src/cli/commands/schemaCommands.ts +3 -3
- package/src/cli/commands/storageCommands.ts +2 -3
- package/src/cli/commands/transferCommands.ts +3 -6
- package/src/collections/attributes.ts +3 -39
- package/src/collections/indexes.ts +2 -4
- package/src/collections/methods.ts +115 -150
- package/src/collections/tableOperations.ts +57 -21
- package/src/collections/transferOperations.ts +4 -5
- package/src/collections/wipeOperations.ts +154 -51
- package/src/databases/methods.ts +2 -2
- package/src/databases/setup.ts +2 -2
- package/src/examples/yamlTerminologyExample.ts +2 -2
- package/src/functions/deployments.ts +6 -5
- package/src/functions/fnConfigDiscovery.ts +2 -2
- package/src/functions/methods.ts +17 -4
- package/src/init.ts +1 -1
- package/src/interactiveCLI.ts +75 -10
- package/src/main.ts +143 -287
- package/src/migrations/afterImportActions.ts +2 -3
- package/src/migrations/appwriteToX.ts +12 -8
- package/src/migrations/comprehensiveTransfer.ts +6 -6
- package/src/migrations/dataLoader.ts +2 -5
- package/src/migrations/importController.ts +3 -4
- package/src/migrations/importDataActions.ts +3 -3
- package/src/migrations/relationships.ts +1 -2
- package/src/migrations/services/DataTransformationService.ts +2 -2
- package/src/migrations/services/FileHandlerService.ts +1 -1
- package/src/migrations/services/ImportOrchestrator.ts +4 -4
- package/src/migrations/services/RateLimitManager.ts +1 -1
- package/src/migrations/services/RelationshipResolver.ts +1 -1
- package/src/migrations/services/UserMappingService.ts +1 -1
- package/src/migrations/services/ValidationService.ts +1 -1
- package/src/migrations/transfer.ts +126 -83
- package/src/migrations/yaml/YamlImportConfigLoader.ts +1 -1
- package/src/migrations/yaml/YamlImportIntegration.ts +2 -2
- package/src/migrations/yaml/generateImportSchemas.ts +1 -1
- package/src/setupCommands.ts +5 -6
- package/src/setupController.ts +1 -1
- package/src/shared/backupTracking.ts +3 -3
- package/src/shared/confirmationDialogs.ts +1 -1
- package/src/shared/migrationHelpers.ts +4 -4
- package/src/shared/operationQueue.ts +3 -4
- package/src/shared/operationsTable.ts +3 -3
- package/src/shared/progressManager.ts +1 -1
- package/src/shared/selectionDialogs.ts +9 -8
- package/src/storage/methods.ts +4 -4
- package/src/tables/indexManager.ts +409 -0
- package/src/types.ts +2 -2
- package/src/users/methods.ts +2 -3
- package/src/utils/configMigration.ts +1 -1
- package/src/utils/index.ts +1 -1
- package/src/utils/loadConfigs.ts +15 -7
- package/src/utils/setupFiles.ts +5 -7
- package/src/utilsController.ts +86 -32
- package/dist/adapters/AdapterFactory.d.ts +0 -94
- package/dist/adapters/AdapterFactory.js +0 -405
- package/dist/adapters/DatabaseAdapter.d.ts +0 -233
- package/dist/adapters/DatabaseAdapter.js +0 -50
- package/dist/adapters/LegacyAdapter.d.ts +0 -50
- package/dist/adapters/LegacyAdapter.js +0 -612
- package/dist/adapters/TablesDBAdapter.d.ts +0 -45
- package/dist/adapters/TablesDBAdapter.js +0 -571
- package/dist/config/ConfigManager.d.ts +0 -445
- package/dist/config/ConfigManager.js +0 -625
- package/dist/config/configMigration.d.ts +0 -87
- package/dist/config/configMigration.js +0 -390
- package/dist/config/configValidation.d.ts +0 -66
- package/dist/config/configValidation.js +0 -358
- package/dist/config/index.d.ts +0 -8
- package/dist/config/index.js +0 -7
- package/dist/config/services/ConfigDiscoveryService.d.ts +0 -126
- package/dist/config/services/ConfigDiscoveryService.js +0 -374
- package/dist/config/services/ConfigLoaderService.d.ts +0 -129
- package/dist/config/services/ConfigLoaderService.js +0 -540
- package/dist/config/services/ConfigMergeService.d.ts +0 -208
- package/dist/config/services/ConfigMergeService.js +0 -308
- package/dist/config/services/ConfigValidationService.d.ts +0 -214
- package/dist/config/services/ConfigValidationService.js +0 -310
- package/dist/config/services/SessionAuthService.d.ts +0 -225
- package/dist/config/services/SessionAuthService.js +0 -456
- package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +0 -1
- package/dist/config/services/__tests__/ConfigMergeService.test.js +0 -271
- package/dist/config/services/index.d.ts +0 -13
- package/dist/config/services/index.js +0 -10
- package/dist/config/yamlConfig.d.ts +0 -722
- package/dist/config/yamlConfig.js +0 -702
- package/dist/functions/pathResolution.d.ts +0 -37
- package/dist/functions/pathResolution.js +0 -185
- package/dist/shared/attributeMapper.d.ts +0 -20
- package/dist/shared/attributeMapper.js +0 -203
- package/dist/shared/errorUtils.d.ts +0 -54
- package/dist/shared/errorUtils.js +0 -95
- package/dist/shared/functionManager.d.ts +0 -48
- package/dist/shared/functionManager.js +0 -336
- package/dist/shared/indexManager.d.ts +0 -24
- package/dist/shared/indexManager.js +0 -151
- package/dist/shared/jsonSchemaGenerator.d.ts +0 -50
- package/dist/shared/jsonSchemaGenerator.js +0 -290
- package/dist/shared/logging.d.ts +0 -61
- package/dist/shared/logging.js +0 -116
- package/dist/shared/messageFormatter.d.ts +0 -39
- package/dist/shared/messageFormatter.js +0 -162
- package/dist/shared/pydanticModelGenerator.d.ts +0 -17
- package/dist/shared/pydanticModelGenerator.js +0 -615
- package/dist/shared/schemaGenerator.d.ts +0 -40
- package/dist/shared/schemaGenerator.js +0 -556
- package/dist/utils/ClientFactory.d.ts +0 -87
- package/dist/utils/ClientFactory.js +0 -212
- package/dist/utils/configDiscovery.d.ts +0 -78
- package/dist/utils/configDiscovery.js +0 -472
- package/dist/utils/constantsGenerator.d.ts +0 -31
- package/dist/utils/constantsGenerator.js +0 -321
- package/dist/utils/dataConverters.d.ts +0 -46
- package/dist/utils/dataConverters.js +0 -139
- package/dist/utils/directoryUtils.d.ts +0 -22
- package/dist/utils/directoryUtils.js +0 -59
- package/dist/utils/getClientFromConfig.d.ts +0 -39
- package/dist/utils/getClientFromConfig.js +0 -199
- package/dist/utils/helperFunctions.d.ts +0 -63
- package/dist/utils/helperFunctions.js +0 -156
- package/dist/utils/pathResolvers.d.ts +0 -53
- package/dist/utils/pathResolvers.js +0 -72
- package/dist/utils/projectConfig.d.ts +0 -119
- package/dist/utils/projectConfig.js +0 -171
- package/dist/utils/retryFailedPromises.d.ts +0 -2
- package/dist/utils/retryFailedPromises.js +0 -23
- package/dist/utils/sessionAuth.d.ts +0 -48
- package/dist/utils/sessionAuth.js +0 -164
- package/dist/utils/typeGuards.d.ts +0 -35
- package/dist/utils/typeGuards.js +0 -57
- package/dist/utils/validationRules.d.ts +0 -43
- package/dist/utils/validationRules.js +0 -42
- package/dist/utils/versionDetection.d.ts +0 -58
- package/dist/utils/versionDetection.js +0 -251
- package/dist/utils/yamlConverter.d.ts +0 -100
- package/dist/utils/yamlConverter.js +0 -428
- package/dist/utils/yamlLoader.d.ts +0 -70
- package/dist/utils/yamlLoader.js +0 -267
- package/src/adapters/AdapterFactory.ts +0 -510
- package/src/adapters/DatabaseAdapter.ts +0 -306
- package/src/adapters/LegacyAdapter.ts +0 -841
- package/src/adapters/TablesDBAdapter.ts +0 -773
- package/src/config/ConfigManager.ts +0 -808
- package/src/config/README.md +0 -274
- package/src/config/configMigration.ts +0 -575
- package/src/config/configValidation.ts +0 -445
- package/src/config/index.ts +0 -10
- package/src/config/services/ConfigDiscoveryService.ts +0 -463
- package/src/config/services/ConfigLoaderService.ts +0 -740
- package/src/config/services/ConfigMergeService.ts +0 -388
- package/src/config/services/ConfigValidationService.ts +0 -394
- package/src/config/services/SessionAuthService.ts +0 -565
- package/src/config/services/__tests__/ConfigMergeService.test.ts +0 -351
- package/src/config/services/index.ts +0 -29
- package/src/config/yamlConfig.ts +0 -761
- package/src/functions/pathResolution.ts +0 -227
- package/src/shared/attributeMapper.ts +0 -229
- package/src/shared/errorUtils.ts +0 -110
- package/src/shared/functionManager.ts +0 -525
- package/src/shared/indexManager.ts +0 -254
- package/src/shared/jsonSchemaGenerator.ts +0 -383
- package/src/shared/logging.ts +0 -149
- package/src/shared/messageFormatter.ts +0 -208
- package/src/shared/pydanticModelGenerator.ts +0 -618
- package/src/shared/schemaGenerator.ts +0 -644
- package/src/utils/ClientFactory.ts +0 -240
- package/src/utils/configDiscovery.ts +0 -557
- package/src/utils/constantsGenerator.ts +0 -369
- package/src/utils/dataConverters.ts +0 -159
- package/src/utils/directoryUtils.ts +0 -61
- package/src/utils/getClientFromConfig.ts +0 -257
- package/src/utils/helperFunctions.ts +0 -228
- package/src/utils/pathResolvers.ts +0 -81
- package/src/utils/projectConfig.ts +0 -299
- package/src/utils/retryFailedPromises.ts +0 -29
- package/src/utils/sessionAuth.ts +0 -230
- package/src/utils/typeGuards.ts +0 -65
- package/src/utils/validationRules.ts +0 -88
- package/src/utils/versionDetection.ts +0 -292
- package/src/utils/yamlConverter.ts +0 -542
- package/src/utils/yamlLoader.ts +0 -371
package/dist/utilsController.js
CHANGED
|
@@ -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 '
|
|
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 "
|
|
18
|
-
import { getAdapterFromConfig } from "
|
|
19
|
-
import { hasSessionAuth, findSessionByEndpointAndProject, isValidSessionCookie } from "
|
|
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 "
|
|
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 {
|
|
31
|
-
import {
|
|
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
|
-
//
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
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
|
-
|
|
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 =
|
|
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.
|
|
5
|
-
"main": "
|
|
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.
|
|
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"
|
package/src/adapters/index.ts
CHANGED
|
@@ -1,37 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Adapters Module -
|
|
3
|
-
*
|
|
4
|
-
* This module exports all adapter classes and utilities
|
|
5
|
-
*
|
|
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
|
|
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
|
|
7
|
-
import { logger } from
|
|
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
|
|
6
|
-
import { logger } from
|
|
7
|
-
import type { DatabaseAdapter } from
|
|
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 "
|
|
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
|
|
6
|
-
import { logger } from
|
|
7
|
-
import type { DatabaseAdapter } from
|
|
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
|
|
2
|
-
import { logger } from
|
|
3
|
-
import { tryAwaitWithRetry } from "
|
|
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
|
|
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
|
-
|
|
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
|
|
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("
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
};
|