@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/interactiveCLI.js
CHANGED
|
@@ -12,9 +12,8 @@ import { join } from "node:path";
|
|
|
12
12
|
import path from "path";
|
|
13
13
|
import fs from "node:fs";
|
|
14
14
|
import os from "node:os";
|
|
15
|
-
import { MessageFormatter } from "
|
|
15
|
+
import { MessageFormatter, findYamlConfig } from "@njdamstra/appwrite-utils-helpers";
|
|
16
16
|
import { findAppwriteConfig } from "./utils/loadConfigs.js";
|
|
17
|
-
import { findYamlConfig } from "./config/yamlConfig.js";
|
|
18
17
|
// Import command modules
|
|
19
18
|
import { configCommands } from "./cli/commands/configCommands.js";
|
|
20
19
|
import { databaseCommands } from "./cli/commands/databaseCommands.js";
|
|
@@ -22,6 +21,7 @@ import { functionCommands } from "./cli/commands/functionCommands.js";
|
|
|
22
21
|
import { storageCommands } from "./cli/commands/storageCommands.js";
|
|
23
22
|
import { transferCommands } from "./cli/commands/transferCommands.js";
|
|
24
23
|
import { schemaCommands } from "./cli/commands/schemaCommands.js";
|
|
24
|
+
import { importFileCommands } from "./cli/commands/importFileCommands.js";
|
|
25
25
|
var CHOICES;
|
|
26
26
|
(function (CHOICES) {
|
|
27
27
|
CHOICES["MIGRATE_CONFIG"] = "\uD83D\uDD04 Migrate TypeScript config to YAML (.appwrite structure)";
|
|
@@ -43,6 +43,7 @@ var CHOICES;
|
|
|
43
43
|
CHOICES["GENERATE_SCHEMAS"] = "\uD83C\uDFD7\uFE0F Generate schemas";
|
|
44
44
|
CHOICES["GENERATE_CONSTANTS"] = "\uD83D\uDCCB Generate cross-language constants (TypeScript, Python, PHP, Dart, etc.)";
|
|
45
45
|
CHOICES["IMPORT_DATA"] = "\uD83D\uDCE5 Import data";
|
|
46
|
+
CHOICES["IMPORT_FILE"] = "\uD83D\uDCC4 Import file (CSV/JSON) directly into a table";
|
|
46
47
|
CHOICES["RELOAD_CONFIG"] = "\uD83D\uDD04 Reload configuration files";
|
|
47
48
|
CHOICES["UPDATE_FUNCTION_SPEC"] = "\u2699\uFE0F Update function specifications";
|
|
48
49
|
CHOICES["MANAGE_BUCKETS"] = "\uD83E\uDEA3 Manage storage buckets";
|
|
@@ -53,12 +54,14 @@ export class InteractiveCLI {
|
|
|
53
54
|
controller;
|
|
54
55
|
isUsingTypeScriptConfig = false;
|
|
55
56
|
lastSelectedCollectionIds = [];
|
|
56
|
-
|
|
57
|
+
options;
|
|
58
|
+
constructor(currentDir, options = {}) {
|
|
57
59
|
this.currentDir = currentDir;
|
|
60
|
+
this.options = options;
|
|
58
61
|
}
|
|
59
62
|
async run() {
|
|
60
63
|
MessageFormatter.banner("Appwrite Utils CLI", "Welcome to Appwrite Utils CLI Tool by Zach Handley");
|
|
61
|
-
MessageFormatter.info("For more information, visit https://github.com/
|
|
64
|
+
MessageFormatter.info("For more information, visit https://github.com/njdamstra/AppwriteUtils");
|
|
62
65
|
// Detect configuration type
|
|
63
66
|
try {
|
|
64
67
|
await this.detectConfigurationType();
|
|
@@ -148,6 +151,10 @@ export class InteractiveCLI {
|
|
|
148
151
|
await this.initControllerIfNeeded();
|
|
149
152
|
await schemaCommands.importData(this);
|
|
150
153
|
break;
|
|
154
|
+
case CHOICES.IMPORT_FILE:
|
|
155
|
+
await this.initControllerIfNeeded();
|
|
156
|
+
await importFileCommands.importFile(this);
|
|
157
|
+
break;
|
|
151
158
|
case CHOICES.RELOAD_CONFIG:
|
|
152
159
|
await configCommands.reloadConfigWithSessionPreservation(this);
|
|
153
160
|
break;
|
|
@@ -167,7 +174,10 @@ export class InteractiveCLI {
|
|
|
167
174
|
async initControllerIfNeeded(directConfig) {
|
|
168
175
|
if (!this.controller) {
|
|
169
176
|
this.controller = UtilsController.getInstance(this.currentDir, directConfig);
|
|
170
|
-
await this.controller.init(
|
|
177
|
+
await this.controller.init({
|
|
178
|
+
useSession: this.options.useSession,
|
|
179
|
+
sessionCookie: this.options.sessionCookie
|
|
180
|
+
});
|
|
171
181
|
}
|
|
172
182
|
else {
|
|
173
183
|
// Extract session info from existing controller before reinitializing
|
|
@@ -182,13 +192,19 @@ export class InteractiveCLI {
|
|
|
182
192
|
// Reinitialize with session preservation
|
|
183
193
|
UtilsController.clearInstance();
|
|
184
194
|
this.controller = UtilsController.getInstance(this.currentDir, enhancedDirectConfig);
|
|
185
|
-
await this.controller.init(
|
|
195
|
+
await this.controller.init({
|
|
196
|
+
useSession: this.options.useSession,
|
|
197
|
+
sessionCookie: this.options.sessionCookie
|
|
198
|
+
});
|
|
186
199
|
}
|
|
187
200
|
else if (directConfig) {
|
|
188
201
|
// Standard reinitialize without session
|
|
189
202
|
UtilsController.clearInstance();
|
|
190
203
|
this.controller = UtilsController.getInstance(this.currentDir, directConfig);
|
|
191
|
-
await this.controller.init(
|
|
204
|
+
await this.controller.init({
|
|
205
|
+
useSession: this.options.useSession,
|
|
206
|
+
sessionCookie: this.options.sessionCookie
|
|
207
|
+
});
|
|
192
208
|
}
|
|
193
209
|
// If no directConfig provided, keep existing controller
|
|
194
210
|
}
|
|
@@ -258,7 +274,8 @@ export class InteractiveCLI {
|
|
|
258
274
|
pageSize: 10,
|
|
259
275
|
},
|
|
260
276
|
]);
|
|
261
|
-
|
|
277
|
+
// "list" type returns a single value, "checkbox" returns an array — normalize to array
|
|
278
|
+
return Array.isArray(selectedDatabases) ? selectedDatabases : [selectedDatabases];
|
|
262
279
|
}
|
|
263
280
|
async selectCollections(database, databasesClient, message, multiSelect = true, preferLocal = false, shouldFilterByDatabase = false) {
|
|
264
281
|
await this.initControllerIfNeeded();
|
|
@@ -299,6 +316,9 @@ export class InteractiveCLI {
|
|
|
299
316
|
allCollections = allCollections.filter((collection) => !collection.$id.startsWith('_'));
|
|
300
317
|
const hasLocalAndRemote = allCollections.some((coll) => configCollections.some((c) => c.name === coll.name || c.$id === coll.$id)) &&
|
|
301
318
|
allCollections.some((coll) => !configCollections.some((c) => c.name === coll.name || c.$id === coll.$id));
|
|
319
|
+
const getCollectionId = (collection) => collection.$id || collection.name;
|
|
320
|
+
const localCollectionIds = new Set(configCollections.map((c) => c.$id || c.name));
|
|
321
|
+
const localCollections = allCollections.filter((collection) => localCollectionIds.has(getCollectionId(collection)));
|
|
302
322
|
// Enhanced choice display with type indicators
|
|
303
323
|
const choices = allCollections
|
|
304
324
|
.sort((a, b) => {
|
|
@@ -349,6 +369,18 @@ export class InteractiveCLI {
|
|
|
349
369
|
value: collection,
|
|
350
370
|
};
|
|
351
371
|
});
|
|
372
|
+
if (multiSelect && localCollections.length > 1) {
|
|
373
|
+
choices.unshift({
|
|
374
|
+
name: chalk.green.bold(`📋 Select All Local Items (${localCollections.length})`),
|
|
375
|
+
value: "__SELECT_ALL_LOCAL__"
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
if (multiSelect && allCollections.length > 1) {
|
|
379
|
+
choices.unshift({
|
|
380
|
+
name: chalk.green.bold(`📋 Select All Shown (${allCollections.length})`),
|
|
381
|
+
value: "__SELECT_ALL__"
|
|
382
|
+
});
|
|
383
|
+
}
|
|
352
384
|
const { selectedCollections } = await inquirer.prompt([
|
|
353
385
|
{
|
|
354
386
|
type: multiSelect ? "checkbox" : "list",
|
|
@@ -357,8 +389,27 @@ export class InteractiveCLI {
|
|
|
357
389
|
choices,
|
|
358
390
|
loop: true,
|
|
359
391
|
pageSize: 15, // Increased page size to accommodate additional info
|
|
392
|
+
validate: (input) => {
|
|
393
|
+
if (!multiSelect)
|
|
394
|
+
return true;
|
|
395
|
+
if (input.includes("__SELECT_ALL__") && input.length > 1) {
|
|
396
|
+
return "Cannot select 'Select All' with individual items.";
|
|
397
|
+
}
|
|
398
|
+
if (input.includes("__SELECT_ALL_LOCAL__") && input.length > 1) {
|
|
399
|
+
return "Cannot select 'Select All Local' with individual items.";
|
|
400
|
+
}
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
360
403
|
},
|
|
361
404
|
]);
|
|
405
|
+
if (multiSelect && Array.isArray(selectedCollections)) {
|
|
406
|
+
if (selectedCollections.includes("__SELECT_ALL__")) {
|
|
407
|
+
return allCollections;
|
|
408
|
+
}
|
|
409
|
+
if (selectedCollections.includes("__SELECT_ALL_LOCAL__")) {
|
|
410
|
+
return localCollections;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
362
413
|
return selectedCollections;
|
|
363
414
|
}
|
|
364
415
|
/**
|
|
@@ -800,7 +851,10 @@ export class InteractiveCLI {
|
|
|
800
851
|
}, bucketId.length > 0 ? bucketId : ulid());
|
|
801
852
|
}
|
|
802
853
|
getLocalCollections() {
|
|
803
|
-
const configCollections =
|
|
854
|
+
const configCollections = [
|
|
855
|
+
...(this.controller.config?.collections || []),
|
|
856
|
+
...(this.controller.config?.tables || [])
|
|
857
|
+
];
|
|
804
858
|
// @ts-expect-error - appwrite invalid types
|
|
805
859
|
return configCollections.map((c) => ({
|
|
806
860
|
$id: c.$id || ulid(),
|
package/dist/main.js
CHANGED
|
@@ -5,22 +5,18 @@ import { hideBin } from "yargs/helpers";
|
|
|
5
5
|
import { InteractiveCLI } from "./interactiveCLI.js";
|
|
6
6
|
import { UtilsController } from "./utilsController.js";
|
|
7
7
|
import { Databases, Storage } from "node-appwrite";
|
|
8
|
-
import { getClient } from "
|
|
8
|
+
import { getClient } from "@njdamstra/appwrite-utils-helpers";
|
|
9
9
|
import { fetchAllDatabases } from "./databases/methods.js";
|
|
10
10
|
import { setupDirsFiles } from "./utils/setupFiles.js";
|
|
11
11
|
import { fetchAllCollections } from "./collections/methods.js";
|
|
12
12
|
import chalk from "chalk";
|
|
13
13
|
import { listSpecifications } from "./functions/methods.js";
|
|
14
|
-
import { MessageFormatter } from "
|
|
14
|
+
import { MessageFormatter, logger, AuthenticationError } from "@njdamstra/appwrite-utils-helpers";
|
|
15
15
|
import { ConfirmationDialogs } from "./shared/confirmationDialogs.js";
|
|
16
16
|
import { SelectionDialogs } from "./shared/selectionDialogs.js";
|
|
17
|
-
import { logger } from "./shared/logging.js";
|
|
18
17
|
import path from "path";
|
|
19
18
|
import fs from "fs";
|
|
20
19
|
import { createRequire } from "node:module";
|
|
21
|
-
import { loadAppwriteProjectConfig, findAppwriteProjectConfig, projectConfigToAppwriteConfig, } from "./utils/projectConfig.js";
|
|
22
|
-
import { hasSessionAuth, getAvailableSessions, getAuthenticationStatus, } from "./utils/sessionAuth.js";
|
|
23
|
-
import { findYamlConfig, loadYamlConfigWithSession, } from "./config/yamlConfig.js";
|
|
24
20
|
const require = createRequire(import.meta.url);
|
|
25
21
|
if (!globalThis.require) {
|
|
26
22
|
globalThis.require = require;
|
|
@@ -217,6 +213,11 @@ const argv = yargs(hideBin(process.argv))
|
|
|
217
213
|
.option("config", {
|
|
218
214
|
type: "string",
|
|
219
215
|
description: "Path to Appwrite configuration file (appwriteConfig.ts)",
|
|
216
|
+
})
|
|
217
|
+
.option("appwriteConfig", {
|
|
218
|
+
alias: ["appwrite-config", "use-appwrite-config"],
|
|
219
|
+
type: "boolean",
|
|
220
|
+
description: "Prefer loading from appwrite.config.json instead of config.yaml",
|
|
220
221
|
})
|
|
221
222
|
.option("it", {
|
|
222
223
|
alias: ["interactive", "i"],
|
|
@@ -438,134 +439,85 @@ const argv = yargs(hideBin(process.argv))
|
|
|
438
439
|
.option("sessionCookie", {
|
|
439
440
|
type: "string",
|
|
440
441
|
description: "Explicit session cookie to use for authentication",
|
|
442
|
+
})
|
|
443
|
+
.option("importFile", {
|
|
444
|
+
alias: ["import-file"],
|
|
445
|
+
type: "string",
|
|
446
|
+
description: "Import a CSV or JSON file directly into a table (no config needed)",
|
|
447
|
+
})
|
|
448
|
+
.option("targetDb", {
|
|
449
|
+
alias: ["target-db"],
|
|
450
|
+
type: "string",
|
|
451
|
+
description: "Target database ID for --importFile (prompted if omitted)",
|
|
452
|
+
})
|
|
453
|
+
.option("targetTable", {
|
|
454
|
+
alias: ["target-table"],
|
|
455
|
+
type: "string",
|
|
456
|
+
description: "Target table ID for --importFile (prompted if omitted)",
|
|
441
457
|
})
|
|
442
458
|
.parse();
|
|
443
459
|
async function main() {
|
|
444
460
|
const startTime = Date.now();
|
|
445
461
|
const operationStats = {};
|
|
446
|
-
// Early session detection for better user guidance
|
|
447
|
-
const availableSessions = getAvailableSessions();
|
|
448
|
-
let hasAnyValidSessions = availableSessions.length > 0;
|
|
449
462
|
if (argv.it) {
|
|
450
|
-
const cli = new InteractiveCLI(process.cwd()
|
|
463
|
+
const cli = new InteractiveCLI(process.cwd(), {
|
|
464
|
+
useSession: argv.useSession,
|
|
465
|
+
sessionCookie: argv.sessionCookie
|
|
466
|
+
});
|
|
451
467
|
await cli.run();
|
|
452
468
|
}
|
|
453
469
|
else {
|
|
454
|
-
//
|
|
455
|
-
|
|
456
|
-
//
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
else {
|
|
471
|
-
MessageFormatter.info("No active Appwrite sessions found", {
|
|
472
|
-
prefix: "Auth",
|
|
473
|
-
});
|
|
474
|
-
MessageFormatter.info("\u2022 Run 'appwrite login' to authenticate with session", { prefix: "Auth" });
|
|
475
|
-
MessageFormatter.info("\u2022 Or provide --apiKey for API key authentication", { prefix: "Auth" });
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
// Priority 1: Check for appwrite.json project configuration
|
|
479
|
-
const projectConfigPath = findAppwriteProjectConfig(process.cwd());
|
|
480
|
-
if (projectConfigPath) {
|
|
481
|
-
const projectConfig = loadAppwriteProjectConfig(projectConfigPath);
|
|
482
|
-
if (projectConfig) {
|
|
483
|
-
directConfig = projectConfigToAppwriteConfig(projectConfig);
|
|
484
|
-
MessageFormatter.info(`Loaded project configuration from ${projectConfigPath}`, { prefix: "CLI" });
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
// Priority 2: CLI arguments override project config
|
|
488
|
-
if (argv.endpoint ||
|
|
489
|
-
argv.projectId ||
|
|
490
|
-
argv.apiKey ||
|
|
491
|
-
argv.useSession ||
|
|
492
|
-
argv.sessionCookie) {
|
|
493
|
-
directConfig = {
|
|
494
|
-
...directConfig,
|
|
495
|
-
appwriteEndpoint: argv.endpoint || directConfig?.appwriteEndpoint,
|
|
496
|
-
appwriteProject: argv.projectId || directConfig?.appwriteProject,
|
|
497
|
-
appwriteKey: argv.apiKey || directConfig?.appwriteKey,
|
|
470
|
+
// Non-interactive mode - pass auth flags through to controller
|
|
471
|
+
// ConfigManager will handle config discovery and auth decisions
|
|
472
|
+
// Users can provide credentials via CLI flags even without a config file
|
|
473
|
+
const controller = UtilsController.getInstance(process.cwd());
|
|
474
|
+
// Build init options from CLI flags
|
|
475
|
+
const initOptions = {
|
|
476
|
+
useSession: argv.useSession,
|
|
477
|
+
sessionCookie: argv.sessionCookie,
|
|
478
|
+
preferJson: argv.appwriteConfig,
|
|
479
|
+
};
|
|
480
|
+
// Add CLI overrides if provided - these can work even without a config file
|
|
481
|
+
if (argv.endpoint || argv.projectId || argv.apiKey) {
|
|
482
|
+
initOptions.overrides = {
|
|
483
|
+
appwriteEndpoint: argv.endpoint,
|
|
484
|
+
appwriteProject: argv.projectId,
|
|
485
|
+
appwriteKey: argv.apiKey,
|
|
498
486
|
};
|
|
499
487
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (directConfig?.appwriteEndpoint && directConfig?.appwriteProject) {
|
|
503
|
-
sessionAuthAvailable = hasSessionAuth(directConfig.appwriteEndpoint, directConfig.appwriteProject);
|
|
488
|
+
try {
|
|
489
|
+
await controller.init(initOptions);
|
|
504
490
|
}
|
|
505
|
-
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
else if (sessionAuthAvailable) {
|
|
511
|
-
MessageFormatter.info("Session authentication detected and will be used", { prefix: "Auth" });
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
514
|
-
MessageFormatter.warning("Session authentication requested but no valid session found", { prefix: "Auth" });
|
|
515
|
-
const availableSessions = getAvailableSessions();
|
|
516
|
-
if (availableSessions.length > 0) {
|
|
517
|
-
MessageFormatter.info(`Available sessions: ${availableSessions
|
|
518
|
-
.map((s) => `${s.projectId} (${s.email || "unknown"})`)
|
|
519
|
-
.join(", ")}`, { prefix: "Auth" });
|
|
520
|
-
MessageFormatter.info("Use --session flag to enable session authentication", { prefix: "Auth" });
|
|
521
|
-
}
|
|
522
|
-
else {
|
|
523
|
-
MessageFormatter.warning("No Appwrite CLI sessions found. Please run 'appwrite login' first.", { prefix: "Auth" });
|
|
524
|
-
}
|
|
525
|
-
MessageFormatter.error("Session authentication requested but not available", undefined, { prefix: "Auth" });
|
|
526
|
-
return; // Exit early if session auth was requested but not available
|
|
491
|
+
catch (error) {
|
|
492
|
+
if (error instanceof AuthenticationError) {
|
|
493
|
+
MessageFormatter.error(error.getFormattedMessage(), undefined, { prefix: "Auth" });
|
|
494
|
+
process.exit(1);
|
|
527
495
|
}
|
|
496
|
+
// Re-throw other errors
|
|
497
|
+
throw error;
|
|
528
498
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
MessageFormatter.
|
|
532
|
-
MessageFormatter.info("
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
// 1. If session auth is explicitly requested via flags, use it
|
|
536
|
-
// 2. If no API key is provided but sessions are available, offer to use session auth
|
|
537
|
-
// 3. Auto-detect session authentication when possible
|
|
538
|
-
let finalDirectConfig = directConfig;
|
|
539
|
-
if ((argv.useSession || argv.sessionCookie) &&
|
|
540
|
-
(!directConfig ||
|
|
541
|
-
!directConfig.appwriteEndpoint ||
|
|
542
|
-
!directConfig.appwriteProject)) {
|
|
543
|
-
// Don't pass incomplete directConfig - let UtilsController load YAML config normally
|
|
544
|
-
finalDirectConfig = null;
|
|
499
|
+
// After init, check if we have a valid config (from file OR CLI overrides)
|
|
500
|
+
if (!controller.config) {
|
|
501
|
+
MessageFormatter.error("No Appwrite configuration available", undefined, { prefix: "CLI" });
|
|
502
|
+
MessageFormatter.info("Provide credentials via CLI flags (--endpoint, --projectId, --apiKey or --session)", { prefix: "CLI" });
|
|
503
|
+
MessageFormatter.info("Or create a config file using --setup", { prefix: "CLI" });
|
|
504
|
+
return;
|
|
545
505
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
!
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
MessageFormatter.info("No API key provided, but session authentication is available", { prefix: "Auth" });
|
|
553
|
-
MessageFormatter.info("Automatically using session authentication (add --session to suppress this message)", { prefix: "Auth" });
|
|
554
|
-
// Implicitly enable session authentication
|
|
555
|
-
argv.useSession = true;
|
|
506
|
+
const parsedArgv = argv;
|
|
507
|
+
if (argv.importFile) {
|
|
508
|
+
const { importFileFromPath, importFilePromptMissing } = await import("./cli/commands/importFileCommands.js");
|
|
509
|
+
if (!controller.adapter) {
|
|
510
|
+
MessageFormatter.error("No adapter available — check your credentials", undefined, { prefix: "Import" });
|
|
511
|
+
return;
|
|
556
512
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
if (argv.useSession || argv.sessionCookie) {
|
|
563
|
-
initOptions.useSession = true;
|
|
564
|
-
if (argv.sessionCookie) {
|
|
565
|
-
initOptions.sessionCookie = argv.sessionCookie;
|
|
513
|
+
if (parsedArgv.targetDb && parsedArgv.targetTable) {
|
|
514
|
+
await importFileFromPath(controller.adapter, argv.importFile, parsedArgv.targetDb, parsedArgv.targetTable);
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
await importFilePromptMissing(controller.adapter, controller.database, argv.importFile, parsedArgv.targetDb, parsedArgv.targetTable);
|
|
566
518
|
}
|
|
519
|
+
return;
|
|
567
520
|
}
|
|
568
|
-
await controller.init(initOptions);
|
|
569
521
|
if (argv.setup) {
|
|
570
522
|
await setupDirsFiles(false, process.cwd());
|
|
571
523
|
return;
|
|
@@ -576,7 +528,7 @@ async function main() {
|
|
|
576
528
|
return;
|
|
577
529
|
}
|
|
578
530
|
if (argv.generateConstants) {
|
|
579
|
-
const { ConstantsGenerator } = await import("
|
|
531
|
+
const { ConstantsGenerator } = await import("@njdamstra/appwrite-utils-helpers");
|
|
580
532
|
if (!controller.config) {
|
|
581
533
|
MessageFormatter.error("No Appwrite configuration found", undefined, {
|
|
582
534
|
prefix: "Constants",
|
|
@@ -642,7 +594,7 @@ async function main() {
|
|
|
642
594
|
MessageFormatter.info(" • tables/ folder must not exist or be empty", { prefix: "Migration" });
|
|
643
595
|
return;
|
|
644
596
|
}
|
|
645
|
-
const { migrateCollectionsToTables } = await import("
|
|
597
|
+
const { migrateCollectionsToTables } = await import("@njdamstra/appwrite-utils-helpers");
|
|
646
598
|
MessageFormatter.info("Starting collections to tables migration...", {
|
|
647
599
|
prefix: "Migration",
|
|
648
600
|
});
|
|
@@ -666,41 +618,9 @@ async function main() {
|
|
|
666
618
|
}
|
|
667
619
|
return;
|
|
668
620
|
}
|
|
669
|
-
if (!controller.config) {
|
|
670
|
-
// Provide better guidance based on available authentication methods
|
|
671
|
-
const availableSessions = getAvailableSessions();
|
|
672
|
-
if (availableSessions.length > 0) {
|
|
673
|
-
MessageFormatter.error("No Appwrite configuration found", undefined, {
|
|
674
|
-
prefix: "CLI",
|
|
675
|
-
});
|
|
676
|
-
MessageFormatter.info("Available authentication options:", {
|
|
677
|
-
prefix: "Auth",
|
|
678
|
-
});
|
|
679
|
-
MessageFormatter.info("• Session authentication: Add --session flag", {
|
|
680
|
-
prefix: "Auth",
|
|
681
|
-
});
|
|
682
|
-
MessageFormatter.info("• API key authentication: Add --apiKey YOUR_API_KEY", { prefix: "Auth" });
|
|
683
|
-
MessageFormatter.info(`• Available sessions: ${availableSessions
|
|
684
|
-
.map((s) => `${s.projectId} (${s.email || "unknown"})`)
|
|
685
|
-
.join(", ")}`, { prefix: "Auth" });
|
|
686
|
-
}
|
|
687
|
-
else {
|
|
688
|
-
MessageFormatter.error("No Appwrite configuration found", undefined, {
|
|
689
|
-
prefix: "CLI",
|
|
690
|
-
});
|
|
691
|
-
MessageFormatter.info("Authentication options:", { prefix: "Auth" });
|
|
692
|
-
MessageFormatter.info("• Login with Appwrite CLI: Run 'appwrite login' then use --session flag", { prefix: "Auth" });
|
|
693
|
-
MessageFormatter.info("• Use API key: Add --apiKey YOUR_API_KEY", {
|
|
694
|
-
prefix: "Auth",
|
|
695
|
-
});
|
|
696
|
-
MessageFormatter.info("• Create config file: Run with --setup to initialize project configuration", { prefix: "Auth" });
|
|
697
|
-
}
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
const parsedArgv = argv;
|
|
701
621
|
// List backups if requested
|
|
702
622
|
if (parsedArgv.listBackups) {
|
|
703
|
-
const { AdapterFactory } = await import("
|
|
623
|
+
const { AdapterFactory } = await import("@njdamstra/appwrite-utils-helpers");
|
|
704
624
|
const { listBackups } = await import("./shared/backupTracking.js");
|
|
705
625
|
if (!controller.config) {
|
|
706
626
|
MessageFormatter.error("No Appwrite configuration found", undefined, {
|
|
@@ -789,7 +709,7 @@ async function main() {
|
|
|
789
709
|
// Comprehensive backup (all databases + all buckets)
|
|
790
710
|
if (parsedArgv.comprehensiveBackup) {
|
|
791
711
|
const { comprehensiveBackup } = await import("./backups/operations/comprehensiveBackup.js");
|
|
792
|
-
const { AdapterFactory } = await import("
|
|
712
|
+
const { AdapterFactory } = await import("@njdamstra/appwrite-utils-helpers");
|
|
793
713
|
// Get tracking database ID (interactive prompt if not specified)
|
|
794
714
|
let trackingDatabaseId = parsedArgv.trackingDatabaseId;
|
|
795
715
|
if (!trackingDatabaseId) {
|
|
@@ -963,7 +883,10 @@ async function main() {
|
|
|
963
883
|
}
|
|
964
884
|
// Build DatabaseSelection[] with tableIds per DB
|
|
965
885
|
const databaseSelections = [];
|
|
966
|
-
const allConfigItems =
|
|
886
|
+
const allConfigItems = [
|
|
887
|
+
...(controller.config.collections || []),
|
|
888
|
+
...(controller.config.tables || [])
|
|
889
|
+
];
|
|
967
890
|
let lastSelectedTableIds = null;
|
|
968
891
|
for (const dbId of selectedDbIds) {
|
|
969
892
|
const db = availableDatabases.find(d => d.$id === dbId);
|
|
@@ -979,8 +902,16 @@ async function main() {
|
|
|
979
902
|
return one === dbId;
|
|
980
903
|
return true; // eligible everywhere if unspecified
|
|
981
904
|
});
|
|
982
|
-
// Fetch available tables from remote for
|
|
905
|
+
// Fetch available tables from remote for status/context
|
|
983
906
|
const availableTables = await fetchAllCollections(dbId, controller.database);
|
|
907
|
+
const remoteTableIds = new Set(availableTables.map(table => table.$id));
|
|
908
|
+
const localItems = eligibleConfigItems;
|
|
909
|
+
const localItemIds = localItems.map(item => item.$id || item.id || item.tableId || item.name);
|
|
910
|
+
const localNewItems = localItems.filter(item => {
|
|
911
|
+
const itemId = item.$id || item.id || item.tableId || item.name;
|
|
912
|
+
return !remoteTableIds.has(itemId);
|
|
913
|
+
});
|
|
914
|
+
const localNewIds = localNewItems.map(item => item.$id || item.id || item.tableId || item.name);
|
|
984
915
|
// Determine selected table IDs
|
|
985
916
|
let selectedTableIds = [];
|
|
986
917
|
if (parsedArgv.collectionIds) {
|
|
@@ -988,35 +919,57 @@ async function main() {
|
|
|
988
919
|
selectedTableIds = parsedArgv.collectionIds.split(/[\,\s]+/).filter(Boolean);
|
|
989
920
|
}
|
|
990
921
|
else {
|
|
991
|
-
|
|
922
|
+
const inquirer = (await import("inquirer")).default;
|
|
923
|
+
const choices = [];
|
|
992
924
|
if (lastSelectedTableIds && lastSelectedTableIds.length > 0) {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
925
|
+
choices.push({
|
|
926
|
+
name: `Use same selection as previous (${lastSelectedTableIds.length} items)`,
|
|
927
|
+
value: "same"
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
if (localItemIds.length > 0) {
|
|
931
|
+
choices.push({
|
|
932
|
+
name: `Select all local items for ${db.name} (${localItemIds.length} items)`,
|
|
933
|
+
value: "all_local"
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
if (localNewIds.length > 0) {
|
|
937
|
+
choices.push({
|
|
938
|
+
name: `Select only new local items (not on remote) (${localNewIds.length} items)`,
|
|
939
|
+
value: "new_only"
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
choices.push({
|
|
943
|
+
name: "Manual selection",
|
|
944
|
+
value: "manual"
|
|
945
|
+
});
|
|
946
|
+
const { selectionMode } = await inquirer.prompt([
|
|
947
|
+
{
|
|
948
|
+
type: "list",
|
|
949
|
+
name: "selectionMode",
|
|
950
|
+
message: `How do you want to select tables for ${db.name}?`,
|
|
951
|
+
choices,
|
|
952
|
+
default: choices[0]?.value || "manual"
|
|
1009
953
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
954
|
+
]);
|
|
955
|
+
if (selectionMode === "same") {
|
|
956
|
+
selectedTableIds = [...(lastSelectedTableIds || [])];
|
|
957
|
+
}
|
|
958
|
+
else if (selectionMode === "all_local") {
|
|
959
|
+
selectedTableIds = [...localItemIds];
|
|
960
|
+
}
|
|
961
|
+
else if (selectionMode === "new_only") {
|
|
962
|
+
selectedTableIds = [...localNewIds];
|
|
963
|
+
}
|
|
964
|
+
else {
|
|
965
|
+
if (localItems.length === 0) {
|
|
966
|
+
MessageFormatter.warning(`No local tables/collections available for ${db.name}`, { prefix: "Push" });
|
|
967
|
+
selectedTableIds = [];
|
|
1012
968
|
}
|
|
1013
969
|
else {
|
|
1014
|
-
selectedTableIds = await SelectionDialogs.selectTablesForDatabase(dbId, db.name,
|
|
970
|
+
selectedTableIds = await SelectionDialogs.selectTablesForDatabase(dbId, db.name, localItems, availableTables, { showSelectAll: localItems.length > 1, allowNewOnly: false, defaultSelected: lastSelectedTableIds || [] });
|
|
1015
971
|
}
|
|
1016
972
|
}
|
|
1017
|
-
else {
|
|
1018
|
-
selectedTableIds = await SelectionDialogs.selectTablesForDatabase(dbId, db.name, availableTables, eligibleConfigItems, { showSelectAll: false, allowNewOnly: true, defaultSelected: [] });
|
|
1019
|
-
}
|
|
1020
973
|
}
|
|
1021
974
|
databaseSelections.push({
|
|
1022
975
|
databaseId: db.$id,
|
|
@@ -3,10 +3,9 @@ import { InputFile } from "node-appwrite/file";
|
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import os from "os";
|
|
6
|
-
import { logger } from "
|
|
6
|
+
import { logger, MessageFormatter } from "@njdamstra/appwrite-utils-helpers";
|
|
7
7
|
import { tryAwaitWithRetry, } from "@njdamstra/appwrite-utils";
|
|
8
|
-
import { getClientFromConfig } from "
|
|
9
|
-
import { MessageFormatter } from "../shared/messageFormatter.js";
|
|
8
|
+
import { getClientFromConfig } from "@njdamstra/appwrite-utils-helpers";
|
|
10
9
|
export const getDatabaseFromConfig = (config) => {
|
|
11
10
|
getClientFromConfig(config); // Sets config.appwriteClient if missing
|
|
12
11
|
return new Databases(config.appwriteClient);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Storage, type Models } from "node-appwrite";
|
|
2
2
|
import { type AppwriteConfig } from "@njdamstra/appwrite-utils";
|
|
3
|
-
import type { DatabaseAdapter } from "
|
|
3
|
+
import type { DatabaseAdapter } from "@njdamstra/appwrite-utils-helpers";
|
|
4
4
|
import type { DatabaseSelection, BucketSelection } from "../shared/selectionDialogs.js";
|
|
5
5
|
export declare class AppwriteToX {
|
|
6
6
|
config: AppwriteConfig;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { SchemaGenerator } from "
|
|
2
|
-
import { findYamlConfig } from "../config/yamlConfig.js";
|
|
1
|
+
import { SchemaGenerator, findYamlConfig } from "@njdamstra/appwrite-utils-helpers";
|
|
3
2
|
import { Client, Compression, Databases, Query, Storage, } from "node-appwrite";
|
|
4
3
|
import { fetchAllCollections } from "../collections/methods.js";
|
|
5
4
|
import { fetchAllDatabases } from "../databases/methods.js";
|
|
6
5
|
import { CollectionSchema, attributeSchema, AppwriteConfigSchema, permissionsSchema, attributesSchema, indexesSchema, parseAttribute, } from "@njdamstra/appwrite-utils";
|
|
7
6
|
import { getDatabaseFromConfig } from "./afterImportActions.js";
|
|
8
|
-
import { getAdapterFromConfig } from "
|
|
7
|
+
import { getAdapterFromConfig } from "@njdamstra/appwrite-utils-helpers";
|
|
9
8
|
import { listBuckets } from "../storage/methods.js";
|
|
10
9
|
import { listFunctions, listFunctionDeployments, getFunction } from "../functions/methods.js";
|
|
11
|
-
import { MessageFormatter } from "
|
|
12
|
-
import { isLegacyDatabases } from "
|
|
10
|
+
import { MessageFormatter } from "@njdamstra/appwrite-utils-helpers";
|
|
11
|
+
import { isLegacyDatabases } from "@njdamstra/appwrite-utils-helpers";
|
|
13
12
|
/**
|
|
14
13
|
* Convert between collection and table terminology based on data structure
|
|
15
14
|
*/
|
|
@@ -80,8 +79,11 @@ export class AppwriteToX {
|
|
|
80
79
|
const client = new Client();
|
|
81
80
|
client
|
|
82
81
|
.setEndpoint(this.config.appwriteEndpoint)
|
|
83
|
-
.setProject(this.config.appwriteProject)
|
|
84
|
-
|
|
82
|
+
.setProject(this.config.appwriteProject);
|
|
83
|
+
// Only set API key if provided (session auth is alternative)
|
|
84
|
+
if (this.config.appwriteKey) {
|
|
85
|
+
client.setKey(this.config.appwriteKey);
|
|
86
|
+
}
|
|
85
87
|
this.config.appwriteClient = client;
|
|
86
88
|
}
|
|
87
89
|
}
|