@njdamstra/appwrite-utils-cli 1.8.9
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 +19 -0
- package/README.md +1133 -0
- package/dist/adapters/AdapterFactory.d.ts +94 -0
- package/dist/adapters/AdapterFactory.js +405 -0
- package/dist/adapters/DatabaseAdapter.d.ts +233 -0
- package/dist/adapters/DatabaseAdapter.js +50 -0
- package/dist/adapters/LegacyAdapter.d.ts +50 -0
- package/dist/adapters/LegacyAdapter.js +612 -0
- package/dist/adapters/TablesDBAdapter.d.ts +45 -0
- package/dist/adapters/TablesDBAdapter.js +571 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.js +12 -0
- package/dist/backups/operations/bucketBackup.d.ts +19 -0
- package/dist/backups/operations/bucketBackup.js +197 -0
- package/dist/backups/operations/collectionBackup.d.ts +30 -0
- package/dist/backups/operations/collectionBackup.js +201 -0
- package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
- package/dist/backups/operations/comprehensiveBackup.js +238 -0
- package/dist/backups/schemas/bucketManifest.d.ts +93 -0
- package/dist/backups/schemas/bucketManifest.js +33 -0
- package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
- package/dist/backups/schemas/comprehensiveManifest.js +32 -0
- package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
- package/dist/backups/tracking/centralizedTracking.js +274 -0
- package/dist/cli/commands/configCommands.d.ts +8 -0
- package/dist/cli/commands/configCommands.js +166 -0
- package/dist/cli/commands/databaseCommands.d.ts +13 -0
- package/dist/cli/commands/databaseCommands.js +554 -0
- package/dist/cli/commands/functionCommands.d.ts +7 -0
- package/dist/cli/commands/functionCommands.js +330 -0
- package/dist/cli/commands/schemaCommands.d.ts +7 -0
- package/dist/cli/commands/schemaCommands.js +169 -0
- package/dist/cli/commands/storageCommands.d.ts +5 -0
- package/dist/cli/commands/storageCommands.js +143 -0
- package/dist/cli/commands/transferCommands.d.ts +5 -0
- package/dist/cli/commands/transferCommands.js +384 -0
- package/dist/collections/attributes.d.ts +13 -0
- package/dist/collections/attributes.js +1364 -0
- package/dist/collections/indexes.d.ts +12 -0
- package/dist/collections/indexes.js +217 -0
- package/dist/collections/methods.d.ts +19 -0
- package/dist/collections/methods.js +682 -0
- package/dist/collections/tableOperations.d.ts +86 -0
- package/dist/collections/tableOperations.js +434 -0
- package/dist/collections/transferOperations.d.ts +8 -0
- package/dist/collections/transferOperations.js +412 -0
- package/dist/collections/wipeOperations.d.ts +16 -0
- package/dist/collections/wipeOperations.js +233 -0
- package/dist/config/ConfigManager.d.ts +445 -0
- package/dist/config/ConfigManager.js +625 -0
- package/dist/config/configMigration.d.ts +87 -0
- package/dist/config/configMigration.js +390 -0
- package/dist/config/configValidation.d.ts +66 -0
- package/dist/config/configValidation.js +358 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.js +7 -0
- package/dist/config/services/ConfigDiscoveryService.d.ts +126 -0
- package/dist/config/services/ConfigDiscoveryService.js +374 -0
- package/dist/config/services/ConfigLoaderService.d.ts +129 -0
- package/dist/config/services/ConfigLoaderService.js +540 -0
- package/dist/config/services/ConfigMergeService.d.ts +208 -0
- package/dist/config/services/ConfigMergeService.js +308 -0
- package/dist/config/services/ConfigValidationService.d.ts +214 -0
- package/dist/config/services/ConfigValidationService.js +310 -0
- package/dist/config/services/SessionAuthService.d.ts +225 -0
- package/dist/config/services/SessionAuthService.js +456 -0
- package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +1 -0
- package/dist/config/services/__tests__/ConfigMergeService.test.js +271 -0
- package/dist/config/services/index.d.ts +13 -0
- package/dist/config/services/index.js +10 -0
- package/dist/config/yamlConfig.d.ts +722 -0
- package/dist/config/yamlConfig.js +702 -0
- package/dist/databases/methods.d.ts +6 -0
- package/dist/databases/methods.js +35 -0
- package/dist/databases/setup.d.ts +5 -0
- package/dist/databases/setup.js +45 -0
- package/dist/examples/yamlTerminologyExample.d.ts +42 -0
- package/dist/examples/yamlTerminologyExample.js +272 -0
- package/dist/functions/deployments.d.ts +4 -0
- package/dist/functions/deployments.js +146 -0
- package/dist/functions/fnConfigDiscovery.d.ts +3 -0
- package/dist/functions/fnConfigDiscovery.js +108 -0
- package/dist/functions/methods.d.ts +16 -0
- package/dist/functions/methods.js +162 -0
- package/dist/functions/pathResolution.d.ts +37 -0
- package/dist/functions/pathResolution.js +185 -0
- package/dist/functions/templates/count-docs-in-collection/README.md +54 -0
- package/dist/functions/templates/count-docs-in-collection/src/main.ts +159 -0
- package/dist/functions/templates/count-docs-in-collection/src/request.ts +9 -0
- package/dist/functions/templates/hono-typescript/README.md +286 -0
- package/dist/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
- package/dist/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
- package/dist/functions/templates/hono-typescript/src/app.ts +180 -0
- package/dist/functions/templates/hono-typescript/src/context.ts +103 -0
- package/dist/functions/templates/hono-typescript/src/index.ts +54 -0
- package/dist/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
- package/dist/functions/templates/typescript-node/README.md +32 -0
- package/dist/functions/templates/typescript-node/src/context.ts +103 -0
- package/dist/functions/templates/typescript-node/src/index.ts +29 -0
- package/dist/functions/templates/uv/README.md +31 -0
- package/dist/functions/templates/uv/pyproject.toml +30 -0
- package/dist/functions/templates/uv/src/__init__.py +0 -0
- package/dist/functions/templates/uv/src/context.py +125 -0
- package/dist/functions/templates/uv/src/index.py +46 -0
- package/dist/init.d.ts +2 -0
- package/dist/init.js +57 -0
- package/dist/interactiveCLI.d.ts +31 -0
- package/dist/interactiveCLI.js +898 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +1172 -0
- package/dist/migrations/afterImportActions.d.ts +17 -0
- package/dist/migrations/afterImportActions.js +306 -0
- package/dist/migrations/appwriteToX.d.ts +211 -0
- package/dist/migrations/appwriteToX.js +491 -0
- package/dist/migrations/comprehensiveTransfer.d.ts +147 -0
- package/dist/migrations/comprehensiveTransfer.js +1317 -0
- package/dist/migrations/dataLoader.d.ts +753 -0
- package/dist/migrations/dataLoader.js +1250 -0
- package/dist/migrations/importController.d.ts +23 -0
- package/dist/migrations/importController.js +268 -0
- package/dist/migrations/importDataActions.d.ts +50 -0
- package/dist/migrations/importDataActions.js +230 -0
- package/dist/migrations/relationships.d.ts +29 -0
- package/dist/migrations/relationships.js +204 -0
- package/dist/migrations/services/DataTransformationService.d.ts +55 -0
- package/dist/migrations/services/DataTransformationService.js +158 -0
- package/dist/migrations/services/FileHandlerService.d.ts +75 -0
- package/dist/migrations/services/FileHandlerService.js +236 -0
- package/dist/migrations/services/ImportOrchestrator.d.ts +97 -0
- package/dist/migrations/services/ImportOrchestrator.js +485 -0
- package/dist/migrations/services/RateLimitManager.d.ts +138 -0
- package/dist/migrations/services/RateLimitManager.js +279 -0
- package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
- package/dist/migrations/services/RelationshipResolver.js +332 -0
- package/dist/migrations/services/UserMappingService.d.ts +109 -0
- package/dist/migrations/services/UserMappingService.js +277 -0
- package/dist/migrations/services/ValidationService.d.ts +74 -0
- package/dist/migrations/services/ValidationService.js +260 -0
- package/dist/migrations/transfer.d.ts +26 -0
- package/dist/migrations/transfer.js +608 -0
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +131 -0
- package/dist/migrations/yaml/YamlImportConfigLoader.js +383 -0
- package/dist/migrations/yaml/YamlImportIntegration.d.ts +93 -0
- package/dist/migrations/yaml/YamlImportIntegration.js +341 -0
- package/dist/migrations/yaml/generateImportSchemas.d.ts +30 -0
- package/dist/migrations/yaml/generateImportSchemas.js +1327 -0
- package/dist/schemas/authUser.d.ts +24 -0
- package/dist/schemas/authUser.js +17 -0
- package/dist/setup.d.ts +2 -0
- package/dist/setup.js +5 -0
- package/dist/setupCommands.d.ts +58 -0
- package/dist/setupCommands.js +490 -0
- package/dist/setupController.d.ts +9 -0
- package/dist/setupController.js +34 -0
- package/dist/shared/attributeMapper.d.ts +20 -0
- package/dist/shared/attributeMapper.js +203 -0
- package/dist/shared/backupMetadataSchema.d.ts +94 -0
- package/dist/shared/backupMetadataSchema.js +38 -0
- package/dist/shared/backupTracking.d.ts +18 -0
- package/dist/shared/backupTracking.js +176 -0
- package/dist/shared/confirmationDialogs.d.ts +75 -0
- package/dist/shared/confirmationDialogs.js +236 -0
- package/dist/shared/errorUtils.d.ts +54 -0
- package/dist/shared/errorUtils.js +95 -0
- package/dist/shared/functionManager.d.ts +48 -0
- package/dist/shared/functionManager.js +336 -0
- package/dist/shared/indexManager.d.ts +24 -0
- package/dist/shared/indexManager.js +151 -0
- package/dist/shared/jsonSchemaGenerator.d.ts +50 -0
- package/dist/shared/jsonSchemaGenerator.js +290 -0
- package/dist/shared/logging.d.ts +61 -0
- package/dist/shared/logging.js +116 -0
- package/dist/shared/messageFormatter.d.ts +39 -0
- package/dist/shared/messageFormatter.js +162 -0
- package/dist/shared/migrationHelpers.d.ts +61 -0
- package/dist/shared/migrationHelpers.js +145 -0
- package/dist/shared/operationLogger.d.ts +10 -0
- package/dist/shared/operationLogger.js +12 -0
- package/dist/shared/operationQueue.d.ts +40 -0
- package/dist/shared/operationQueue.js +311 -0
- package/dist/shared/operationsTable.d.ts +26 -0
- package/dist/shared/operationsTable.js +286 -0
- package/dist/shared/operationsTableSchema.d.ts +48 -0
- package/dist/shared/operationsTableSchema.js +35 -0
- package/dist/shared/progressManager.d.ts +62 -0
- package/dist/shared/progressManager.js +215 -0
- package/dist/shared/pydanticModelGenerator.d.ts +17 -0
- package/dist/shared/pydanticModelGenerator.js +615 -0
- package/dist/shared/relationshipExtractor.d.ts +56 -0
- package/dist/shared/relationshipExtractor.js +138 -0
- package/dist/shared/schemaGenerator.d.ts +40 -0
- package/dist/shared/schemaGenerator.js +556 -0
- package/dist/shared/selectionDialogs.d.ts +214 -0
- package/dist/shared/selectionDialogs.js +544 -0
- package/dist/storage/backupCompression.d.ts +20 -0
- package/dist/storage/backupCompression.js +67 -0
- package/dist/storage/methods.d.ts +32 -0
- package/dist/storage/methods.js +472 -0
- package/dist/storage/schemas.d.ts +842 -0
- package/dist/storage/schemas.js +175 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +3 -0
- package/dist/users/methods.d.ts +16 -0
- package/dist/users/methods.js +277 -0
- package/dist/utils/ClientFactory.d.ts +87 -0
- package/dist/utils/ClientFactory.js +212 -0
- package/dist/utils/configDiscovery.d.ts +78 -0
- package/dist/utils/configDiscovery.js +472 -0
- package/dist/utils/configMigration.d.ts +1 -0
- package/dist/utils/configMigration.js +261 -0
- package/dist/utils/constantsGenerator.d.ts +31 -0
- package/dist/utils/constantsGenerator.js +321 -0
- package/dist/utils/dataConverters.d.ts +46 -0
- package/dist/utils/dataConverters.js +139 -0
- package/dist/utils/directoryUtils.d.ts +22 -0
- package/dist/utils/directoryUtils.js +59 -0
- package/dist/utils/getClientFromConfig.d.ts +39 -0
- package/dist/utils/getClientFromConfig.js +199 -0
- package/dist/utils/helperFunctions.d.ts +63 -0
- package/dist/utils/helperFunctions.js +156 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/loadConfigs.d.ts +50 -0
- package/dist/utils/loadConfigs.js +358 -0
- package/dist/utils/pathResolvers.d.ts +53 -0
- package/dist/utils/pathResolvers.js +72 -0
- package/dist/utils/projectConfig.d.ts +119 -0
- package/dist/utils/projectConfig.js +171 -0
- package/dist/utils/retryFailedPromises.d.ts +2 -0
- package/dist/utils/retryFailedPromises.js +23 -0
- package/dist/utils/sessionAuth.d.ts +48 -0
- package/dist/utils/sessionAuth.js +164 -0
- package/dist/utils/setupFiles.d.ts +4 -0
- package/dist/utils/setupFiles.js +1192 -0
- package/dist/utils/typeGuards.d.ts +35 -0
- package/dist/utils/typeGuards.js +57 -0
- package/dist/utils/validationRules.d.ts +43 -0
- package/dist/utils/validationRules.js +42 -0
- package/dist/utils/versionDetection.d.ts +58 -0
- package/dist/utils/versionDetection.js +251 -0
- package/dist/utils/yamlConverter.d.ts +100 -0
- package/dist/utils/yamlConverter.js +428 -0
- package/dist/utils/yamlLoader.d.ts +70 -0
- package/dist/utils/yamlLoader.js +267 -0
- package/dist/utilsController.d.ts +106 -0
- package/dist/utilsController.js +863 -0
- package/package.json +75 -0
- package/scripts/copy-templates.ts +23 -0
- package/src/adapters/AdapterFactory.ts +510 -0
- package/src/adapters/DatabaseAdapter.ts +306 -0
- package/src/adapters/LegacyAdapter.ts +841 -0
- package/src/adapters/TablesDBAdapter.ts +773 -0
- package/src/adapters/index.ts +37 -0
- package/src/backups/operations/bucketBackup.ts +277 -0
- package/src/backups/operations/collectionBackup.ts +310 -0
- package/src/backups/operations/comprehensiveBackup.ts +342 -0
- package/src/backups/schemas/bucketManifest.ts +78 -0
- package/src/backups/schemas/comprehensiveManifest.ts +76 -0
- package/src/backups/tracking/centralizedTracking.ts +352 -0
- package/src/cli/commands/configCommands.ts +201 -0
- package/src/cli/commands/databaseCommands.ts +749 -0
- package/src/cli/commands/functionCommands.ts +418 -0
- package/src/cli/commands/schemaCommands.ts +200 -0
- package/src/cli/commands/storageCommands.ts +152 -0
- package/src/cli/commands/transferCommands.ts +457 -0
- package/src/collections/attributes.ts +2054 -0
- package/src/collections/attributes.ts.backup +1555 -0
- package/src/collections/indexes.ts +352 -0
- package/src/collections/methods.ts +745 -0
- package/src/collections/tableOperations.ts +506 -0
- package/src/collections/transferOperations.ts +590 -0
- package/src/collections/wipeOperations.ts +346 -0
- package/src/config/ConfigManager.ts +808 -0
- package/src/config/README.md +274 -0
- package/src/config/configMigration.ts +575 -0
- package/src/config/configValidation.ts +445 -0
- package/src/config/index.ts +10 -0
- package/src/config/services/ConfigDiscoveryService.ts +463 -0
- package/src/config/services/ConfigLoaderService.ts +740 -0
- package/src/config/services/ConfigMergeService.ts +388 -0
- package/src/config/services/ConfigValidationService.ts +394 -0
- package/src/config/services/SessionAuthService.ts +565 -0
- package/src/config/services/__tests__/ConfigMergeService.test.ts +351 -0
- package/src/config/services/index.ts +29 -0
- package/src/config/yamlConfig.ts +761 -0
- package/src/databases/methods.ts +49 -0
- package/src/databases/setup.ts +77 -0
- package/src/examples/yamlTerminologyExample.ts +346 -0
- package/src/functions/deployments.ts +220 -0
- package/src/functions/fnConfigDiscovery.ts +103 -0
- package/src/functions/methods.ts +271 -0
- package/src/functions/pathResolution.ts +227 -0
- package/src/functions/templates/count-docs-in-collection/README.md +54 -0
- package/src/functions/templates/count-docs-in-collection/src/main.ts +159 -0
- package/src/functions/templates/count-docs-in-collection/src/request.ts +9 -0
- package/src/functions/templates/hono-typescript/README.md +286 -0
- package/src/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
- package/src/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
- package/src/functions/templates/hono-typescript/src/app.ts +180 -0
- package/src/functions/templates/hono-typescript/src/context.ts +103 -0
- package/src/functions/templates/hono-typescript/src/index.ts +54 -0
- package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
- package/src/functions/templates/typescript-node/README.md +32 -0
- package/src/functions/templates/typescript-node/src/context.ts +103 -0
- package/src/functions/templates/typescript-node/src/index.ts +29 -0
- package/src/functions/templates/uv/README.md +31 -0
- package/src/functions/templates/uv/pyproject.toml +30 -0
- package/src/functions/templates/uv/src/__init__.py +0 -0
- package/src/functions/templates/uv/src/context.py +125 -0
- package/src/functions/templates/uv/src/index.py +46 -0
- package/src/init.ts +62 -0
- package/src/interactiveCLI.ts +1136 -0
- package/src/main.ts +1661 -0
- package/src/migrations/afterImportActions.ts +580 -0
- package/src/migrations/appwriteToX.ts +664 -0
- package/src/migrations/comprehensiveTransfer.ts +2285 -0
- package/src/migrations/dataLoader.ts +1702 -0
- package/src/migrations/importController.ts +428 -0
- package/src/migrations/importDataActions.ts +315 -0
- package/src/migrations/relationships.ts +334 -0
- package/src/migrations/services/DataTransformationService.ts +196 -0
- package/src/migrations/services/FileHandlerService.ts +311 -0
- package/src/migrations/services/ImportOrchestrator.ts +666 -0
- package/src/migrations/services/RateLimitManager.ts +363 -0
- package/src/migrations/services/RelationshipResolver.ts +461 -0
- package/src/migrations/services/UserMappingService.ts +345 -0
- package/src/migrations/services/ValidationService.ts +349 -0
- package/src/migrations/transfer.ts +1068 -0
- package/src/migrations/yaml/YamlImportConfigLoader.ts +439 -0
- package/src/migrations/yaml/YamlImportIntegration.ts +446 -0
- package/src/migrations/yaml/generateImportSchemas.ts +1354 -0
- package/src/schemas/authUser.ts +23 -0
- package/src/setup.ts +8 -0
- package/src/setupCommands.ts +603 -0
- package/src/setupController.ts +43 -0
- package/src/shared/attributeMapper.ts +229 -0
- package/src/shared/backupMetadataSchema.ts +93 -0
- package/src/shared/backupTracking.ts +211 -0
- package/src/shared/confirmationDialogs.ts +327 -0
- package/src/shared/errorUtils.ts +110 -0
- package/src/shared/functionManager.ts +525 -0
- package/src/shared/indexManager.ts +254 -0
- package/src/shared/jsonSchemaGenerator.ts +383 -0
- package/src/shared/logging.ts +149 -0
- package/src/shared/messageFormatter.ts +208 -0
- package/src/shared/migrationHelpers.ts +232 -0
- package/src/shared/operationLogger.ts +20 -0
- package/src/shared/operationQueue.ts +377 -0
- package/src/shared/operationsTable.ts +338 -0
- package/src/shared/operationsTableSchema.ts +60 -0
- package/src/shared/progressManager.ts +278 -0
- package/src/shared/pydanticModelGenerator.ts +618 -0
- package/src/shared/relationshipExtractor.ts +214 -0
- package/src/shared/schemaGenerator.ts +644 -0
- package/src/shared/selectionDialogs.ts +749 -0
- package/src/storage/backupCompression.ts +88 -0
- package/src/storage/methods.ts +698 -0
- package/src/storage/schemas.ts +205 -0
- package/src/types/node-appwrite-tablesdb.d.ts +44 -0
- package/src/types.ts +9 -0
- package/src/users/methods.ts +359 -0
- package/src/utils/ClientFactory.ts +240 -0
- package/src/utils/configDiscovery.ts +557 -0
- package/src/utils/configMigration.ts +348 -0
- package/src/utils/constantsGenerator.ts +369 -0
- package/src/utils/dataConverters.ts +159 -0
- package/src/utils/directoryUtils.ts +61 -0
- package/src/utils/getClientFromConfig.ts +257 -0
- package/src/utils/helperFunctions.ts +228 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/loadConfigs.ts +449 -0
- package/src/utils/pathResolvers.ts +81 -0
- package/src/utils/projectConfig.ts +299 -0
- package/src/utils/retryFailedPromises.ts +29 -0
- package/src/utils/sessionAuth.ts +230 -0
- package/src/utils/setupFiles.ts +1238 -0
- package/src/utils/typeGuards.ts +65 -0
- package/src/utils/validationRules.ts +88 -0
- package/src/utils/versionDetection.ts +292 -0
- package/src/utils/yamlConverter.ts +542 -0
- package/src/utils/yamlLoader.ts +371 -0
- package/src/utilsController.ts +1203 -0
- package/tests/README.md +497 -0
- package/tests/adapters/AdapterFactory.test.ts +277 -0
- package/tests/integration/syncOperations.test.ts +463 -0
- package/tests/jest.config.js +25 -0
- package/tests/migration/configMigration.test.ts +546 -0
- package/tests/setup.ts +62 -0
- package/tests/testUtils.ts +340 -0
- package/tests/utils/loadConfigs.test.ts +350 -0
- package/tests/validation/configValidation.test.ts +412 -0
- package/tsconfig.json +44 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import { ulid } from "ulidx";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import { Query } from "node-appwrite";
|
|
8
|
+
import { MessageFormatter } from "../../shared/messageFormatter.js";
|
|
9
|
+
import {
|
|
10
|
+
createFunctionTemplate,
|
|
11
|
+
deleteFunction,
|
|
12
|
+
downloadLatestFunctionDeployment,
|
|
13
|
+
listFunctions,
|
|
14
|
+
listSpecifications,
|
|
15
|
+
} from "../../functions/methods.js";
|
|
16
|
+
import { deployLocalFunction } from "../../functions/deployments.js";
|
|
17
|
+
import { discoverFnConfigs, mergeDiscoveredFunctions } from "../../functions/fnConfigDiscovery.js";
|
|
18
|
+
import { addFunctionToYamlConfig, findYamlConfig } from "../../config/yamlConfig.js";
|
|
19
|
+
import { RuntimeSchema, type AppwriteFunction, type Runtime, type Specification } from "@njdamstra/appwrite-utils";
|
|
20
|
+
import type { InteractiveCLI } from "../../interactiveCLI.js";
|
|
21
|
+
|
|
22
|
+
export const functionCommands = {
|
|
23
|
+
async createFunction(cli: InteractiveCLI): Promise<void> {
|
|
24
|
+
const { name } = await inquirer.prompt([
|
|
25
|
+
{
|
|
26
|
+
type: "input",
|
|
27
|
+
name: "name",
|
|
28
|
+
message: "Function name:",
|
|
29
|
+
validate: (input) => input.length > 0,
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const { template } = await inquirer.prompt([
|
|
34
|
+
{
|
|
35
|
+
type: "list",
|
|
36
|
+
name: "template",
|
|
37
|
+
message: "Select a template:",
|
|
38
|
+
choices: [
|
|
39
|
+
{ name: "TypeScript Node.js", value: "typescript-node" },
|
|
40
|
+
{ name: "TypeScript with Hono Web Framework", value: "hono-typescript" },
|
|
41
|
+
{ name: "Python with UV", value: "uv" },
|
|
42
|
+
{ name: "Count Documents in Collection", value: "count-docs-in-collection" },
|
|
43
|
+
{ name: "None (Empty Function)", value: "none" },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
// Get template defaults
|
|
49
|
+
const templateDefaults = (cli as any).getTemplateDefaults(template);
|
|
50
|
+
|
|
51
|
+
const { runtime } = await inquirer.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: "list",
|
|
54
|
+
name: "runtime",
|
|
55
|
+
message: "Select runtime:",
|
|
56
|
+
choices: Object.values(RuntimeSchema.Values),
|
|
57
|
+
default: templateDefaults.runtime,
|
|
58
|
+
},
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
const specifications = await listSpecifications(
|
|
62
|
+
(cli as any).controller!.appwriteServer!
|
|
63
|
+
);
|
|
64
|
+
const { specification } = await inquirer.prompt([
|
|
65
|
+
{
|
|
66
|
+
type: "list",
|
|
67
|
+
name: "specification",
|
|
68
|
+
message: "Select specification:",
|
|
69
|
+
choices: [
|
|
70
|
+
{ name: "None", value: undefined },
|
|
71
|
+
...specifications.specifications.map((s: any) => ({
|
|
72
|
+
name: s.slug,
|
|
73
|
+
value: s.slug,
|
|
74
|
+
})),
|
|
75
|
+
],
|
|
76
|
+
default: templateDefaults.specification,
|
|
77
|
+
},
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
const functionConfig: AppwriteFunction = {
|
|
81
|
+
$id: ulid(),
|
|
82
|
+
name,
|
|
83
|
+
runtime,
|
|
84
|
+
events: [],
|
|
85
|
+
execute: ["any"],
|
|
86
|
+
enabled: true,
|
|
87
|
+
logging: true,
|
|
88
|
+
entrypoint: templateDefaults.entrypoint,
|
|
89
|
+
commands: templateDefaults.commands,
|
|
90
|
+
specification: specification || templateDefaults.specification,
|
|
91
|
+
scopes: [],
|
|
92
|
+
timeout: 15,
|
|
93
|
+
schedule: "",
|
|
94
|
+
installationId: "",
|
|
95
|
+
providerRepositoryId: "",
|
|
96
|
+
providerBranch: "",
|
|
97
|
+
providerSilentMode: false,
|
|
98
|
+
providerRootDirectory: "",
|
|
99
|
+
templateRepository: "",
|
|
100
|
+
templateOwner: "",
|
|
101
|
+
templateRootDirectory: "",
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
if (template !== "none") {
|
|
105
|
+
await createFunctionTemplate(
|
|
106
|
+
template as "typescript-node" | "uv" | "count-docs-in-collection" | "hono-typescript",
|
|
107
|
+
name,
|
|
108
|
+
"./functions"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Add to in-memory config
|
|
113
|
+
if (!(cli as any).controller!.config!.functions) {
|
|
114
|
+
(cli as any).controller!.config!.functions = [];
|
|
115
|
+
}
|
|
116
|
+
(cli as any).controller!.config!.functions.push(functionConfig);
|
|
117
|
+
|
|
118
|
+
// If using YAML config, also add to YAML file
|
|
119
|
+
const yamlConfigPath = findYamlConfig((cli as any).currentDir);
|
|
120
|
+
if (yamlConfigPath) {
|
|
121
|
+
try {
|
|
122
|
+
await addFunctionToYamlConfig(yamlConfigPath, functionConfig);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
MessageFormatter.warning(
|
|
125
|
+
`Function created but failed to update YAML config: ${error instanceof Error ? error.message : error}`,
|
|
126
|
+
{ prefix: "Functions" }
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
MessageFormatter.success("Function created successfully!", { prefix: "Functions" });
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
async deployFunction(cli: InteractiveCLI): Promise<void> {
|
|
135
|
+
await (cli as any).initControllerIfNeeded();
|
|
136
|
+
if (!(cli as any).controller?.config) {
|
|
137
|
+
MessageFormatter.error("Failed to initialize controller or load config", undefined, { prefix: "Functions" });
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Discover per-function .fnconfig.yaml definitions and merge with central list for selection
|
|
142
|
+
// No global prompt; we'll handle conflicts per-function if both exist.
|
|
143
|
+
let discovered: any[] = [];
|
|
144
|
+
let central: any[] = (cli as any).controller!.config!.functions || [];
|
|
145
|
+
try {
|
|
146
|
+
discovered = discoverFnConfigs((cli as any).currentDir) as any[];
|
|
147
|
+
const merged = mergeDiscoveredFunctions(central as any, discovered as any);
|
|
148
|
+
(cli as any).controller!.config!.functions = merged as any;
|
|
149
|
+
} catch {}
|
|
150
|
+
|
|
151
|
+
const functions = await (cli as any).selectFunctions(
|
|
152
|
+
"Select function(s) to deploy:",
|
|
153
|
+
true,
|
|
154
|
+
true
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
if (!functions?.length) {
|
|
158
|
+
MessageFormatter.error("No function selected", undefined, { prefix: "Functions" });
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (const functionConfig of functions) {
|
|
163
|
+
if (!functionConfig) {
|
|
164
|
+
MessageFormatter.error("Invalid function configuration", undefined, { prefix: "Functions" });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Resolve effective config for this function (prefer per-function choice if both sources exist)
|
|
169
|
+
const byIdOrName = (arr: any[]) => arr.find((f:any) => f?.$id === functionConfig.$id || f?.name === functionConfig.name);
|
|
170
|
+
const centralDef = byIdOrName(central as any[]);
|
|
171
|
+
const discoveredDef = byIdOrName(discovered as any[]);
|
|
172
|
+
|
|
173
|
+
let effectiveConfig = functionConfig;
|
|
174
|
+
if (centralDef && discoveredDef) {
|
|
175
|
+
try {
|
|
176
|
+
const answer = await inquirer.prompt([
|
|
177
|
+
{
|
|
178
|
+
type: 'list',
|
|
179
|
+
name: 'cfgChoice',
|
|
180
|
+
message: `Multiple configs found for '${functionConfig.name}'. Which to use?`,
|
|
181
|
+
choices: [
|
|
182
|
+
{ name: 'config.yaml (central)', value: 'central' },
|
|
183
|
+
{ name: '.fnconfig.yaml (local file)', value: 'fnconfig' },
|
|
184
|
+
{ name: 'Merge (.fnconfig overrides central)', value: 'merge' },
|
|
185
|
+
],
|
|
186
|
+
default: 'fnconfig'
|
|
187
|
+
}
|
|
188
|
+
]);
|
|
189
|
+
if (answer.cfgChoice === 'central') effectiveConfig = centralDef;
|
|
190
|
+
else if (answer.cfgChoice === 'fnconfig') effectiveConfig = discoveredDef;
|
|
191
|
+
else effectiveConfig = { ...centralDef, ...discoveredDef };
|
|
192
|
+
} catch {}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Ensure functions array exists
|
|
196
|
+
if (!(cli as any).controller.config.functions) {
|
|
197
|
+
(cli as any).controller.config.functions = [];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const functionNameLower = effectiveConfig.name
|
|
201
|
+
.toLowerCase()
|
|
202
|
+
.replace(/\s+/g, "-");
|
|
203
|
+
|
|
204
|
+
// Debug logging
|
|
205
|
+
MessageFormatter.info(`🔍 Function deployment debug:`, { prefix: "Functions" });
|
|
206
|
+
MessageFormatter.info(` Function name: ${effectiveConfig.name}`, { prefix: "Functions" });
|
|
207
|
+
MessageFormatter.info(` Function ID: ${effectiveConfig.$id}`, { prefix: "Functions" });
|
|
208
|
+
MessageFormatter.info(` Config dirPath: ${effectiveConfig.dirPath || 'undefined'}`, { prefix: "Functions" });
|
|
209
|
+
if (effectiveConfig.dirPath) {
|
|
210
|
+
const expandedPath = effectiveConfig.dirPath.startsWith('~/')
|
|
211
|
+
? effectiveConfig.dirPath.replace('~', os.homedir())
|
|
212
|
+
: effectiveConfig.dirPath;
|
|
213
|
+
MessageFormatter.info(` Expanded dirPath: ${expandedPath}`, { prefix: "Functions" });
|
|
214
|
+
}
|
|
215
|
+
MessageFormatter.info(` Appwrite folder: ${(cli as any).controller.getAppwriteFolderPath()}`, { prefix: "Functions" });
|
|
216
|
+
MessageFormatter.info(` Current working dir: ${process.cwd()}`, { prefix: "Functions" });
|
|
217
|
+
|
|
218
|
+
// Resolve config dirPath relative to central YAML if it's relative
|
|
219
|
+
const yamlConfigPath = findYamlConfig((cli as any).currentDir);
|
|
220
|
+
const yamlBaseDir = yamlConfigPath ? require('node:path').dirname(yamlConfigPath) : process.cwd();
|
|
221
|
+
const expandTildePath = (p: string): string => (p?.startsWith('~/') ? p.replace('~', os.homedir()) : p);
|
|
222
|
+
|
|
223
|
+
// Check locations in priority order:
|
|
224
|
+
const priorityLocations = [
|
|
225
|
+
// 1. Config dirPath if specified (with tilde expansion)
|
|
226
|
+
effectiveConfig.dirPath
|
|
227
|
+
? (require('node:path').isAbsolute(expandTildePath(effectiveConfig.dirPath))
|
|
228
|
+
? expandTildePath(effectiveConfig.dirPath)
|
|
229
|
+
: require('node:path').resolve(yamlBaseDir, expandTildePath(effectiveConfig.dirPath)))
|
|
230
|
+
: undefined,
|
|
231
|
+
// 2. Appwrite config folder/functions/name
|
|
232
|
+
join(
|
|
233
|
+
(cli as any).controller.getAppwriteFolderPath()!,
|
|
234
|
+
"functions",
|
|
235
|
+
functionNameLower
|
|
236
|
+
),
|
|
237
|
+
// 3. Current working directory/functions/name
|
|
238
|
+
join(process.cwd(), "functions", functionNameLower),
|
|
239
|
+
// 4. Current working directory/name
|
|
240
|
+
join(process.cwd(), functionNameLower),
|
|
241
|
+
].filter((val): val is string => val !== undefined);
|
|
242
|
+
|
|
243
|
+
MessageFormatter.info(`🔍 Priority locations to check:`, { prefix: "Functions" });
|
|
244
|
+
priorityLocations.forEach((loc, i) => {
|
|
245
|
+
MessageFormatter.info(` ${i + 1}. ${loc}`, { prefix: "Functions" });
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
let functionPath: string | null = null;
|
|
249
|
+
|
|
250
|
+
// Check each priority location
|
|
251
|
+
for (const location of priorityLocations) {
|
|
252
|
+
MessageFormatter.info(` Checking: ${location} - ${fs.existsSync(location) ? 'EXISTS' : 'NOT FOUND'}`, { prefix: "Functions" });
|
|
253
|
+
if (fs.existsSync(location)) {
|
|
254
|
+
MessageFormatter.success(`✅ Found function at: ${location}`, { prefix: "Functions" });
|
|
255
|
+
functionPath = location;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// If not found in priority locations, do a broader search
|
|
261
|
+
if (!functionPath) {
|
|
262
|
+
MessageFormatter.info(`Function not found in primary locations, searching subdirectories...`, { prefix: "Functions" });
|
|
263
|
+
|
|
264
|
+
// Search in both appwrite config directory and current working directory
|
|
265
|
+
functionPath = await (cli as any).findFunctionInSubdirectories(
|
|
266
|
+
[(cli as any).controller.getAppwriteFolderPath()!, process.cwd()],
|
|
267
|
+
functionNameLower
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (!functionPath) {
|
|
272
|
+
const { shouldDownload } = await inquirer.prompt([
|
|
273
|
+
{
|
|
274
|
+
type: "confirm",
|
|
275
|
+
name: "shouldDownload",
|
|
276
|
+
message:
|
|
277
|
+
"Function not found locally. Would you like to download the latest deployment?",
|
|
278
|
+
default: false,
|
|
279
|
+
},
|
|
280
|
+
]);
|
|
281
|
+
|
|
282
|
+
if (shouldDownload) {
|
|
283
|
+
try {
|
|
284
|
+
MessageFormatter.progress("Downloading latest deployment...", { prefix: "Functions" });
|
|
285
|
+
const { path: downloadedPath, function: remoteFunction } =
|
|
286
|
+
await downloadLatestFunctionDeployment(
|
|
287
|
+
(cli as any).controller.appwriteServer!,
|
|
288
|
+
effectiveConfig.$id,
|
|
289
|
+
join((cli as any).controller.getAppwriteFolderPath()!, "functions")
|
|
290
|
+
);
|
|
291
|
+
MessageFormatter.success(`✨ Function downloaded to ${downloadedPath}`, { prefix: "Functions" });
|
|
292
|
+
|
|
293
|
+
functionPath = downloadedPath;
|
|
294
|
+
effectiveConfig.dirPath = downloadedPath;
|
|
295
|
+
|
|
296
|
+
const existingIndex = (cli as any).controller.config.functions.findIndex(
|
|
297
|
+
(f: any) => f?.$id === remoteFunction.$id
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
if (existingIndex >= 0) {
|
|
301
|
+
(cli as any).controller.config.functions[existingIndex].dirPath =
|
|
302
|
+
downloadedPath;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
await (cli as any).reloadConfigWithSessionPreservation();
|
|
306
|
+
} catch (error) {
|
|
307
|
+
MessageFormatter.error("Failed to download function deployment", error instanceof Error ? error : new Error(String(error)), { prefix: "Functions" });
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
MessageFormatter.error(`Function ${effectiveConfig.name} not found locally. Cannot deploy.`, undefined, { prefix: "Functions" });
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (!(cli as any).controller.appwriteServer) {
|
|
317
|
+
MessageFormatter.error("Appwrite server not initialized", undefined, { prefix: "Functions" });
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
try {
|
|
322
|
+
await deployLocalFunction(
|
|
323
|
+
(cli as any).controller.appwriteServer,
|
|
324
|
+
effectiveConfig.name,
|
|
325
|
+
{
|
|
326
|
+
...effectiveConfig,
|
|
327
|
+
dirPath: functionPath,
|
|
328
|
+
},
|
|
329
|
+
functionPath
|
|
330
|
+
);
|
|
331
|
+
MessageFormatter.success("Function deployed successfully!", { prefix: "Functions" });
|
|
332
|
+
} catch (error) {
|
|
333
|
+
MessageFormatter.error("Failed to deploy function", error instanceof Error ? error : new Error(String(error)), { prefix: "Functions" });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
async deleteFunction(cli: InteractiveCLI): Promise<void> {
|
|
339
|
+
const functions = await (cli as any).selectFunctions(
|
|
340
|
+
"Select functions to delete:",
|
|
341
|
+
true,
|
|
342
|
+
false
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
if (!functions.length) {
|
|
346
|
+
MessageFormatter.error("No functions selected", undefined, { prefix: "Functions" });
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
for (const func of functions) {
|
|
351
|
+
try {
|
|
352
|
+
await deleteFunction((cli as any).controller!.appwriteServer!, func.$id);
|
|
353
|
+
MessageFormatter.success(`✨ Function ${func.name} deleted successfully!`, { prefix: "Functions" });
|
|
354
|
+
} catch (error) {
|
|
355
|
+
MessageFormatter.error(`Failed to delete function ${func.name}`, error instanceof Error ? error : new Error(String(error)), { prefix: "Functions" });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
|
|
360
|
+
async updateFunctionSpec(cli: InteractiveCLI): Promise<void> {
|
|
361
|
+
const remoteFunctions = await listFunctions(
|
|
362
|
+
(cli as any).controller!.appwriteServer!,
|
|
363
|
+
[Query.limit(1000)]
|
|
364
|
+
);
|
|
365
|
+
const localFunctions = (cli as any).getLocalFunctions();
|
|
366
|
+
|
|
367
|
+
const allFunctions = [
|
|
368
|
+
...remoteFunctions.functions,
|
|
369
|
+
...localFunctions.filter(
|
|
370
|
+
(f: any) => !remoteFunctions.functions.some((rf: any) => rf.name === f.name)
|
|
371
|
+
),
|
|
372
|
+
];
|
|
373
|
+
|
|
374
|
+
const functionsToUpdate = await inquirer.prompt([
|
|
375
|
+
{
|
|
376
|
+
type: "checkbox",
|
|
377
|
+
name: "functionId",
|
|
378
|
+
message: "Select functions to update:",
|
|
379
|
+
choices: allFunctions.map((f: any) => ({
|
|
380
|
+
name: `${f.name} (${f.$id})${
|
|
381
|
+
localFunctions.some((lf: any) => lf.name === f.name)
|
|
382
|
+
? " (Local)"
|
|
383
|
+
: " (Remote)"
|
|
384
|
+
}`,
|
|
385
|
+
value: f.$id,
|
|
386
|
+
})),
|
|
387
|
+
loop: true,
|
|
388
|
+
},
|
|
389
|
+
]);
|
|
390
|
+
|
|
391
|
+
const specifications = await listSpecifications(
|
|
392
|
+
(cli as any).controller!.appwriteServer!
|
|
393
|
+
);
|
|
394
|
+
const { specification } = await inquirer.prompt([
|
|
395
|
+
{
|
|
396
|
+
type: "list",
|
|
397
|
+
name: "specification",
|
|
398
|
+
message: "Select new specification:",
|
|
399
|
+
choices: specifications.specifications.map((s: any) => ({
|
|
400
|
+
name: `${s.slug}`,
|
|
401
|
+
value: s.slug,
|
|
402
|
+
})),
|
|
403
|
+
},
|
|
404
|
+
]);
|
|
405
|
+
|
|
406
|
+
try {
|
|
407
|
+
for (const functionId of functionsToUpdate.functionId) {
|
|
408
|
+
await (cli as any).controller!.updateFunctionSpecifications(
|
|
409
|
+
functionId,
|
|
410
|
+
specification
|
|
411
|
+
);
|
|
412
|
+
MessageFormatter.success(`Successfully updated function specification to ${specification}`, { prefix: "Functions" });
|
|
413
|
+
}
|
|
414
|
+
} catch (error) {
|
|
415
|
+
MessageFormatter.error("Error updating function specification", error instanceof Error ? error : new Error(String(error)), { prefix: "Functions" });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { MessageFormatter } from "../../shared/messageFormatter.js";
|
|
5
|
+
import { SchemaGenerator } from "../../shared/schemaGenerator.js";
|
|
6
|
+
import { setupDirsFiles } from "../../utils/setupFiles.js";
|
|
7
|
+
import { fetchAllDatabases } from "../../databases/methods.js";
|
|
8
|
+
import type { InteractiveCLI } from "../../interactiveCLI.js";
|
|
9
|
+
|
|
10
|
+
export const schemaCommands = {
|
|
11
|
+
async generateSchemas(cli: InteractiveCLI): Promise<void> {
|
|
12
|
+
MessageFormatter.progress("Generating schemas...", { prefix: "Schemas" });
|
|
13
|
+
|
|
14
|
+
// Prompt user for schema type preference
|
|
15
|
+
const { schemaType } = await inquirer.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: "list",
|
|
18
|
+
name: "schemaType",
|
|
19
|
+
message: "What type of schemas would you like to generate?",
|
|
20
|
+
choices: [
|
|
21
|
+
{ name: "TypeScript (Zod) schemas", value: "zod" },
|
|
22
|
+
{ name: "JSON schemas", value: "json" },
|
|
23
|
+
{ name: "Python (Pydantic) models", value: "pydantic" },
|
|
24
|
+
{ name: "TypeScript + JSON", value: "both" },
|
|
25
|
+
{ name: "All (Zod, JSON, Pydantic)", value: "all" },
|
|
26
|
+
],
|
|
27
|
+
default: "all",
|
|
28
|
+
},
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
// Get the config folder path (where the config file is located)
|
|
32
|
+
const configFolderPath = (cli as any).controller!.getAppwriteFolderPath();
|
|
33
|
+
if (!configFolderPath) {
|
|
34
|
+
MessageFormatter.error("Failed to get config folder path", undefined, { prefix: "Schemas" });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Prompt for schema output directory (optional override)
|
|
39
|
+
const defaultSchemaOut = path.join(configFolderPath, (cli as any).controller!.config?.schemaConfig?.outputDirectory || 'schemas');
|
|
40
|
+
const { schemaOutDir } = await inquirer.prompt([
|
|
41
|
+
{
|
|
42
|
+
type: 'input',
|
|
43
|
+
name: 'schemaOutDir',
|
|
44
|
+
message: 'Output directory for schemas:',
|
|
45
|
+
default: defaultSchemaOut,
|
|
46
|
+
validate: (input: string) => input && input.trim().length > 0 ? true : 'Please provide an output directory',
|
|
47
|
+
}
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
// Create SchemaGenerator with the correct base path and generate schemas
|
|
51
|
+
const schemaGenerator = new SchemaGenerator((cli as any).controller!.config!, configFolderPath);
|
|
52
|
+
const outDirRel = path.isAbsolute(schemaOutDir) ? schemaOutDir : path.relative(configFolderPath, schemaOutDir);
|
|
53
|
+
await schemaGenerator.generateSchemas({ format: schemaType as any, verbose: true, outputDir: outDirRel });
|
|
54
|
+
|
|
55
|
+
MessageFormatter.success("Schema generation completed", { prefix: "Schemas" });
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
async generateConstants(cli: InteractiveCLI): Promise<void> {
|
|
59
|
+
MessageFormatter.progress("Generating cross-language constants...", { prefix: "Constants" });
|
|
60
|
+
|
|
61
|
+
if (!(cli as any).controller?.config) {
|
|
62
|
+
MessageFormatter.error("No configuration found", undefined, { prefix: "Constants" });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Prompt for languages
|
|
67
|
+
const { languages } = await inquirer.prompt([
|
|
68
|
+
{
|
|
69
|
+
type: "checkbox",
|
|
70
|
+
name: "languages",
|
|
71
|
+
message: "Select languages for constants generation:",
|
|
72
|
+
choices: [
|
|
73
|
+
{ name: "TypeScript", value: "typescript", checked: true },
|
|
74
|
+
{ name: "JavaScript", value: "javascript" },
|
|
75
|
+
{ name: "Python", value: "python" },
|
|
76
|
+
{ name: "PHP", value: "php" },
|
|
77
|
+
{ name: "Dart", value: "dart" },
|
|
78
|
+
{ name: "JSON", value: "json" },
|
|
79
|
+
{ name: "Environment Variables", value: "env" },
|
|
80
|
+
],
|
|
81
|
+
validate: (input) => {
|
|
82
|
+
if (input.length === 0) {
|
|
83
|
+
return "Please select at least one language";
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
// Prompt for which constants to include
|
|
91
|
+
const { includeWhat } = await inquirer.prompt([
|
|
92
|
+
{
|
|
93
|
+
type: 'checkbox',
|
|
94
|
+
name: 'includeWhat',
|
|
95
|
+
message: 'Select which constants to generate:',
|
|
96
|
+
choices: [
|
|
97
|
+
{ name: 'Databases', value: 'databases', checked: true },
|
|
98
|
+
{ name: 'Collections/Tables', value: 'collections', checked: true },
|
|
99
|
+
{ name: 'Buckets', value: 'buckets', checked: true },
|
|
100
|
+
{ name: 'Functions', value: 'functions', checked: true },
|
|
101
|
+
],
|
|
102
|
+
validate: (input) => input.length > 0 ? true : 'Select at least one category',
|
|
103
|
+
}
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
// Determine default output directory based on config location
|
|
107
|
+
const configPath = (cli as any).controller!.getAppwriteFolderPath();
|
|
108
|
+
const defaultOutputDir = configPath
|
|
109
|
+
? path.join(configPath, "constants")
|
|
110
|
+
: path.join(process.cwd(), "constants");
|
|
111
|
+
|
|
112
|
+
// Prompt for output directory
|
|
113
|
+
const { outputDir } = await inquirer.prompt([
|
|
114
|
+
{
|
|
115
|
+
type: "input",
|
|
116
|
+
name: "outputDir",
|
|
117
|
+
message: "Output directory for constants files:",
|
|
118
|
+
default: defaultOutputDir,
|
|
119
|
+
validate: (input) => {
|
|
120
|
+
if (!input.trim()) {
|
|
121
|
+
return "Output directory cannot be empty";
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
const { ConstantsGenerator } = await import("../../utils/constantsGenerator.js");
|
|
130
|
+
const generator = new ConstantsGenerator((cli as any).controller.config);
|
|
131
|
+
|
|
132
|
+
const include = {
|
|
133
|
+
databases: includeWhat.includes('databases'),
|
|
134
|
+
collections: includeWhat.includes('collections'),
|
|
135
|
+
buckets: includeWhat.includes('buckets'),
|
|
136
|
+
functions: includeWhat.includes('functions'),
|
|
137
|
+
};
|
|
138
|
+
MessageFormatter.info(`Generating constants for: ${languages.join(", ")}`, { prefix: "Constants" });
|
|
139
|
+
await generator.generateFiles(languages, outputDir, include);
|
|
140
|
+
|
|
141
|
+
MessageFormatter.success(`Constants generated in ${outputDir}`, { prefix: "Constants" });
|
|
142
|
+
} catch (error) {
|
|
143
|
+
MessageFormatter.error("Failed to generate constants", error instanceof Error ? error : new Error(String(error)), { prefix: "Constants" });
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
async importData(cli: InteractiveCLI): Promise<void> {
|
|
148
|
+
MessageFormatter.progress("Importing data...", { prefix: "Import" });
|
|
149
|
+
|
|
150
|
+
const { doBackup } = await inquirer.prompt([
|
|
151
|
+
{
|
|
152
|
+
type: "confirm",
|
|
153
|
+
name: "doBackup",
|
|
154
|
+
message: "Do you want to perform a backup before importing?",
|
|
155
|
+
default: true,
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
|
|
159
|
+
const databases = await (cli as any).selectDatabases(
|
|
160
|
+
await fetchAllDatabases((cli as any).controller!.database!),
|
|
161
|
+
"Select databases to import data into:",
|
|
162
|
+
true
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const collections = await (cli as any).selectCollectionsAndTables(
|
|
166
|
+
databases[0],
|
|
167
|
+
(cli as any).controller!.database!,
|
|
168
|
+
"Select collections/tables to import data into (leave empty for all):",
|
|
169
|
+
true
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const { shouldWriteFile } = await inquirer.prompt([
|
|
173
|
+
{
|
|
174
|
+
type: "confirm",
|
|
175
|
+
name: "shouldWriteFile",
|
|
176
|
+
message: "Do you want to write the imported data to a file?",
|
|
177
|
+
default: false,
|
|
178
|
+
},
|
|
179
|
+
]);
|
|
180
|
+
|
|
181
|
+
const options = {
|
|
182
|
+
databases,
|
|
183
|
+
collections: collections.map((c: any) => c.name),
|
|
184
|
+
doBackup,
|
|
185
|
+
importData: true,
|
|
186
|
+
shouldWriteFile,
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
await (cli as any).controller!.importData(options);
|
|
191
|
+
MessageFormatter.success("Data import completed successfully", { prefix: "Import" });
|
|
192
|
+
} catch (error) {
|
|
193
|
+
MessageFormatter.error("Error importing data", error instanceof Error ? error : new Error(String(error)), { prefix: "Import" });
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
async setupDirsFiles(cli: InteractiveCLI, withExampleData: boolean = false): Promise<void> {
|
|
198
|
+
await setupDirsFiles(withExampleData, (cli as any).currentDir);
|
|
199
|
+
}
|
|
200
|
+
};
|