appwrite-utils-cli 0.10.86 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/.appwrite/.yaml_schemas/appwrite-config.schema.json +380 -0
  2. package/.appwrite/.yaml_schemas/collection.schema.json +255 -0
  3. package/.appwrite/collections/Categories.yaml +182 -0
  4. package/.appwrite/collections/ExampleCollection.yaml +36 -0
  5. package/.appwrite/collections/Posts.yaml +227 -0
  6. package/.appwrite/collections/Users.yaml +149 -0
  7. package/.appwrite/config.yaml +109 -0
  8. package/.appwrite/import/README.md +148 -0
  9. package/.appwrite/import/categories-import.yaml +129 -0
  10. package/.appwrite/import/posts-import.yaml +208 -0
  11. package/.appwrite/import/users-import.yaml +130 -0
  12. package/.appwrite/importData/categories.json +194 -0
  13. package/.appwrite/importData/posts.json +270 -0
  14. package/.appwrite/importData/users.json +220 -0
  15. package/.appwrite/schemas/categories.json +128 -0
  16. package/.appwrite/schemas/exampleCollection.json +52 -0
  17. package/.appwrite/schemas/posts.json +173 -0
  18. package/.appwrite/schemas/users.json +125 -0
  19. package/README.md +260 -33
  20. package/dist/collections/attributes.js +3 -2
  21. package/dist/collections/methods.js +56 -38
  22. package/dist/config/yamlConfig.d.ts +501 -0
  23. package/dist/config/yamlConfig.js +452 -0
  24. package/dist/databases/setup.d.ts +6 -0
  25. package/dist/databases/setup.js +119 -0
  26. package/dist/functions/methods.d.ts +1 -1
  27. package/dist/functions/methods.js +5 -2
  28. package/dist/functions/openapi.d.ts +4 -0
  29. package/dist/functions/openapi.js +60 -0
  30. package/dist/interactiveCLI.d.ts +5 -0
  31. package/dist/interactiveCLI.js +194 -49
  32. package/dist/main.js +91 -30
  33. package/dist/migrations/afterImportActions.js +2 -2
  34. package/dist/migrations/appwriteToX.d.ts +10 -0
  35. package/dist/migrations/appwriteToX.js +15 -4
  36. package/dist/migrations/backup.d.ts +16 -16
  37. package/dist/migrations/dataLoader.d.ts +83 -1
  38. package/dist/migrations/dataLoader.js +4 -4
  39. package/dist/migrations/importController.js +25 -18
  40. package/dist/migrations/importDataActions.js +2 -2
  41. package/dist/migrations/logging.d.ts +9 -1
  42. package/dist/migrations/logging.js +41 -22
  43. package/dist/migrations/migrationHelper.d.ts +4 -4
  44. package/dist/migrations/relationships.js +1 -1
  45. package/dist/migrations/services/DataTransformationService.d.ts +55 -0
  46. package/dist/migrations/services/DataTransformationService.js +158 -0
  47. package/dist/migrations/services/FileHandlerService.d.ts +75 -0
  48. package/dist/migrations/services/FileHandlerService.js +236 -0
  49. package/dist/migrations/services/ImportOrchestrator.d.ts +97 -0
  50. package/dist/migrations/services/ImportOrchestrator.js +488 -0
  51. package/dist/migrations/services/RateLimitManager.d.ts +138 -0
  52. package/dist/migrations/services/RateLimitManager.js +279 -0
  53. package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
  54. package/dist/migrations/services/RelationshipResolver.js +332 -0
  55. package/dist/migrations/services/UserMappingService.d.ts +109 -0
  56. package/dist/migrations/services/UserMappingService.js +277 -0
  57. package/dist/migrations/services/ValidationService.d.ts +74 -0
  58. package/dist/migrations/services/ValidationService.js +260 -0
  59. package/dist/migrations/transfer.d.ts +0 -6
  60. package/dist/migrations/transfer.js +16 -132
  61. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +384 -0
  62. package/dist/migrations/yaml/YamlImportConfigLoader.js +375 -0
  63. package/dist/migrations/yaml/YamlImportIntegration.d.ts +87 -0
  64. package/dist/migrations/yaml/YamlImportIntegration.js +330 -0
  65. package/dist/migrations/yaml/generateImportSchemas.d.ts +17 -0
  66. package/dist/migrations/yaml/generateImportSchemas.js +575 -0
  67. package/dist/schemas/authUser.d.ts +9 -9
  68. package/dist/shared/attributeManager.d.ts +17 -0
  69. package/dist/shared/attributeManager.js +273 -0
  70. package/dist/shared/confirmationDialogs.d.ts +75 -0
  71. package/dist/shared/confirmationDialogs.js +236 -0
  72. package/dist/shared/functionManager.d.ts +48 -0
  73. package/dist/shared/functionManager.js +322 -0
  74. package/dist/shared/indexManager.d.ts +24 -0
  75. package/dist/shared/indexManager.js +150 -0
  76. package/dist/shared/jsonSchemaGenerator.d.ts +51 -0
  77. package/dist/shared/jsonSchemaGenerator.js +313 -0
  78. package/dist/shared/logging.d.ts +10 -0
  79. package/dist/shared/logging.js +46 -0
  80. package/dist/shared/messageFormatter.d.ts +37 -0
  81. package/dist/shared/messageFormatter.js +152 -0
  82. package/dist/shared/migrationHelpers.d.ts +173 -0
  83. package/dist/shared/migrationHelpers.js +142 -0
  84. package/dist/shared/operationLogger.d.ts +3 -0
  85. package/dist/shared/operationLogger.js +25 -0
  86. package/dist/shared/operationQueue.d.ts +13 -0
  87. package/dist/shared/operationQueue.js +79 -0
  88. package/dist/shared/progressManager.d.ts +62 -0
  89. package/dist/shared/progressManager.js +215 -0
  90. package/dist/shared/schemaGenerator.d.ts +18 -0
  91. package/dist/shared/schemaGenerator.js +523 -0
  92. package/dist/storage/methods.d.ts +3 -1
  93. package/dist/storage/methods.js +144 -55
  94. package/dist/storage/schemas.d.ts +56 -16
  95. package/dist/types.d.ts +2 -2
  96. package/dist/types.js +1 -1
  97. package/dist/users/methods.d.ts +16 -0
  98. package/dist/users/methods.js +276 -0
  99. package/dist/utils/configMigration.d.ts +1 -0
  100. package/dist/utils/configMigration.js +156 -0
  101. package/dist/utils/dataConverters.d.ts +46 -0
  102. package/dist/utils/dataConverters.js +139 -0
  103. package/dist/utils/loadConfigs.d.ts +15 -4
  104. package/dist/utils/loadConfigs.js +377 -51
  105. package/dist/utils/schemaStrings.js +2 -1
  106. package/dist/utils/setupFiles.d.ts +2 -1
  107. package/dist/utils/setupFiles.js +723 -28
  108. package/dist/utils/validationRules.d.ts +43 -0
  109. package/dist/utils/validationRules.js +42 -0
  110. package/dist/utils/yamlConverter.d.ts +48 -0
  111. package/dist/utils/yamlConverter.js +98 -0
  112. package/dist/utilsController.js +65 -43
  113. package/package.json +19 -15
  114. package/src/collections/attributes.ts +3 -2
  115. package/src/collections/methods.ts +85 -51
  116. package/src/config/yamlConfig.ts +488 -0
  117. package/src/{migrations/setupDatabase.ts → databases/setup.ts} +11 -5
  118. package/src/functions/methods.ts +8 -4
  119. package/src/functions/templates/count-docs-in-collection/package.json +25 -0
  120. package/src/functions/templates/count-docs-in-collection/tsconfig.json +28 -0
  121. package/src/functions/templates/typescript-node/package.json +24 -0
  122. package/src/functions/templates/typescript-node/tsconfig.json +28 -0
  123. package/src/functions/templates/uv/README.md +31 -0
  124. package/src/functions/templates/uv/pyproject.toml +29 -0
  125. package/src/interactiveCLI.ts +226 -61
  126. package/src/main.ts +111 -37
  127. package/src/migrations/afterImportActions.ts +2 -2
  128. package/src/migrations/appwriteToX.ts +17 -4
  129. package/src/migrations/dataLoader.ts +4 -4
  130. package/src/migrations/importController.ts +30 -22
  131. package/src/migrations/importDataActions.ts +2 -2
  132. package/src/migrations/relationships.ts +1 -1
  133. package/src/migrations/services/DataTransformationService.ts +196 -0
  134. package/src/migrations/services/FileHandlerService.ts +311 -0
  135. package/src/migrations/services/ImportOrchestrator.ts +669 -0
  136. package/src/migrations/services/RateLimitManager.ts +363 -0
  137. package/src/migrations/services/RelationshipResolver.ts +461 -0
  138. package/src/migrations/services/UserMappingService.ts +345 -0
  139. package/src/migrations/services/ValidationService.ts +349 -0
  140. package/src/migrations/transfer.ts +22 -228
  141. package/src/migrations/yaml/YamlImportConfigLoader.ts +427 -0
  142. package/src/migrations/yaml/YamlImportIntegration.ts +419 -0
  143. package/src/migrations/yaml/generateImportSchemas.ts +589 -0
  144. package/src/shared/attributeManager.ts +429 -0
  145. package/src/shared/confirmationDialogs.ts +327 -0
  146. package/src/shared/functionManager.ts +515 -0
  147. package/src/shared/indexManager.ts +253 -0
  148. package/src/shared/jsonSchemaGenerator.ts +403 -0
  149. package/src/shared/logging.ts +74 -0
  150. package/src/shared/messageFormatter.ts +195 -0
  151. package/src/{migrations/migrationHelper.ts → shared/migrationHelpers.ts} +22 -4
  152. package/src/{migrations/helper.ts → shared/operationLogger.ts} +7 -2
  153. package/src/{migrations/queue.ts → shared/operationQueue.ts} +1 -1
  154. package/src/shared/progressManager.ts +278 -0
  155. package/src/{migrations/schemaStrings.ts → shared/schemaGenerator.ts} +71 -17
  156. package/src/storage/methods.ts +199 -78
  157. package/src/types.ts +2 -2
  158. package/src/{migrations/users.ts → users/methods.ts} +2 -2
  159. package/src/utils/configMigration.ts +212 -0
  160. package/src/utils/loadConfigs.ts +414 -52
  161. package/src/utils/schemaStrings.ts +2 -1
  162. package/src/utils/setupFiles.ts +742 -40
  163. package/src/{migrations → utils}/validationRules.ts +1 -1
  164. package/src/utils/yamlConverter.ts +131 -0
  165. package/src/utilsController.ts +75 -54
  166. package/src/functions/templates/poetry/README.md +0 -30
  167. package/src/functions/templates/poetry/pyproject.toml +0 -16
  168. package/src/migrations/attributes.ts +0 -561
  169. package/src/migrations/backup.ts +0 -205
  170. package/src/migrations/databases.ts +0 -39
  171. package/src/migrations/dbHelpers.ts +0 -92
  172. package/src/migrations/indexes.ts +0 -40
  173. package/src/migrations/logging.ts +0 -29
  174. package/src/migrations/storage.ts +0 -538
  175. /package/src/{migrations → functions}/openapi.ts +0 -0
  176. /package/src/functions/templates/{poetry → uv}/src/__init__.py +0 -0
  177. /package/src/functions/templates/{poetry → uv}/src/index.py +0 -0
  178. /package/src/{migrations/converters.ts → utils/dataConverters.ts} +0 -0
@@ -0,0 +1,31 @@
1
+ # Python UV Function Template
2
+
3
+ This is a Python template for Appwrite Functions using UV for fast dependency management.
4
+
5
+ ## Structure
6
+ - `src/index.py`: Main function entry point
7
+ - `pyproject.toml`: UV/PyPI project configuration and dependencies
8
+
9
+ ## Usage
10
+ Your function will receive a context object with:
11
+ - `req`: Request object containing request data, headers, and environment variables
12
+ - `res`: Response object for sending responses
13
+ - `log`: Function for logging (shows in your function logs)
14
+ - `error`: Function for error logging
15
+
16
+ ## Example Request
17
+ ```json
18
+ {
19
+ "key": "value"
20
+ }
21
+ ```
22
+
23
+ ## Development
24
+ 1. Install UV: `curl -LsSf https://astral.sh/uv/install.sh | sh`
25
+ 2. Install dependencies: `uv sync`
26
+ 3. Run locally: `uv run python src/index.py`
27
+ 4. Deploy: Dependencies will be installed during deployment
28
+
29
+ ## Deployment
30
+ Make sure it's inside `appwriteConfig.yaml` functions array, and if you want to install dependencies FIRST, before Appwrite (using your system), you can
31
+ add the `predeployCommands` to the function in `appwriteConfig.yaml`.
@@ -0,0 +1,29 @@
1
+ [project]
2
+ name = "{{functionName}}"
3
+ version = "0.1.0"
4
+ description = "Appwrite Python function using UV"
5
+ authors = [{name = "Your Name", email = "you@example.com"}]
6
+ readme = "README.md"
7
+ requires-python = ">=3.9"
8
+ dependencies = [
9
+ "appwrite>=7.0.1",
10
+ ]
11
+
12
+ [build-system]
13
+ requires = ["hatchling"]
14
+ build-backend = "hatchling.build"
15
+
16
+ [tool.uv]
17
+ dev-dependencies = [
18
+ "pytest>=7.0.0",
19
+ "black>=23.0.0",
20
+ "ruff>=0.1.0",
21
+ ]
22
+
23
+ [tool.ruff]
24
+ line-length = 88
25
+ target-version = "py39"
26
+
27
+ [tool.ruff.lint]
28
+ select = ["E", "F", "W", "I"]
29
+ ignore = ["E501"]
@@ -42,9 +42,15 @@ import {
42
42
  import { deployLocalFunction } from "./functions/deployments.js";
43
43
  import { join } from "node:path";
44
44
  import fs from "node:fs";
45
- import { SchemaGenerator } from "./migrations/schemaStrings.js";
45
+ import { SchemaGenerator } from "./shared/schemaGenerator.js";
46
+ import { ConfirmationDialogs } from "./shared/confirmationDialogs.js";
47
+ import { MessageFormatter } from "./shared/messageFormatter.js";
48
+ import { migrateConfig } from "./utils/configMigration.js";
49
+ import { findAppwriteConfig } from "./utils/loadConfigs.js";
50
+ import { findYamlConfig, addFunctionToYamlConfig } from "./config/yamlConfig.js";
46
51
 
47
52
  enum CHOICES {
53
+ MIGRATE_CONFIG = "🔄 Migrate TypeScript config to YAML (.appwrite structure)",
48
54
  CREATE_COLLECTION_CONFIG = "Create collection config file",
49
55
  CREATE_FUNCTION = "Create a new function, from scratch or using a template",
50
56
  DEPLOY_FUNCTION = "Deploy function(s)",
@@ -66,32 +72,45 @@ enum CHOICES {
66
72
 
67
73
  export class InteractiveCLI {
68
74
  private controller: UtilsController | undefined;
75
+ private isUsingTypeScriptConfig: boolean = false;
69
76
 
70
77
  constructor(private currentDir: string) {}
71
78
 
72
79
  async run(): Promise<void> {
73
- console.log(
74
- chalk.green("Welcome to Appwrite Utils CLI Tool by Zach Handley")
80
+ MessageFormatter.banner(
81
+ "Appwrite Utils CLI",
82
+ "Welcome to Appwrite Utils CLI Tool by Zach Handley"
75
83
  );
76
- console.log(
77
- chalk.blue(
78
- "For more information, visit https://github.com/zachhandley/AppwriteUtils"
79
- )
84
+ MessageFormatter.info(
85
+ "For more information, visit https://github.com/zachhandley/AppwriteUtils"
80
86
  );
81
87
 
88
+ // Detect configuration type
89
+ try {
90
+ await this.detectConfigurationType();
91
+ } catch (error) {
92
+ // Continue if detection fails
93
+ this.isUsingTypeScriptConfig = false;
94
+ }
95
+
82
96
  while (true) {
97
+ // Build choices array dynamically based on config type
98
+ const choices = this.buildChoicesList();
99
+
83
100
  const { action } = await inquirer.prompt([
84
101
  {
85
102
  type: "list",
86
103
  name: "action",
87
104
  message: chalk.yellow("What would you like to do?"),
88
- choices: Object.values(CHOICES),
105
+ choices,
89
106
  },
90
107
  ]);
91
108
 
92
109
  switch (action) {
110
+ case CHOICES.MIGRATE_CONFIG:
111
+ await this.migrateTypeScriptConfig();
112
+ break;
93
113
  case CHOICES.CREATE_COLLECTION_CONFIG:
94
- await this.initControllerIfNeeded();
95
114
  await this.createCollectionConfig();
96
115
  break;
97
116
  case CHOICES.CREATE_FUNCTION:
@@ -153,7 +172,7 @@ export class InteractiveCLI {
153
172
  await this.updateFunctionSpec();
154
173
  break;
155
174
  case CHOICES.EXIT:
156
- console.log(chalk.green("Goodbye!"));
175
+ MessageFormatter.success("Goodbye!");
157
176
  process.exit(0);
158
177
  }
159
178
  }
@@ -190,7 +209,10 @@ export class InteractiveCLI {
190
209
  }
191
210
  return acc;
192
211
  }, [] as Models.Database[])
193
- .filter((db) => db.name.toLowerCase() !== "migrations");
212
+ .filter((db) => {
213
+ const useMigrations = this.controller?.config?.useMigrations ?? true;
214
+ return useMigrations || db.name.toLowerCase() !== "migrations";
215
+ });
194
216
 
195
217
  const hasLocalAndRemote =
196
218
  allDatabases.some((db) =>
@@ -212,7 +234,10 @@ export class InteractiveCLI {
212
234
  : ""),
213
235
  value: db,
214
236
  }))
215
- .filter((db) => db.name.toLowerCase() !== "migrations");
237
+ .filter((db) => {
238
+ const useMigrations = this.controller?.config?.useMigrations ?? true;
239
+ return useMigrations || db.name.toLowerCase() !== "migrations";
240
+ });
216
241
 
217
242
  const { selectedDatabases } = await inquirer.prompt([
218
243
  {
@@ -316,6 +341,36 @@ export class InteractiveCLI {
316
341
  return selectedCollections;
317
342
  }
318
343
 
344
+ private getTemplateDefaults(template: string) {
345
+ const defaults = {
346
+ "typescript-node": {
347
+ runtime: "node-21.0" as Runtime,
348
+ entrypoint: "src/index.ts",
349
+ commands: "npm install && npm run build",
350
+ specification: "s-0.5vcpu-512mb" as Specification,
351
+ },
352
+ "uv": {
353
+ runtime: "python-3.12" as Runtime,
354
+ entrypoint: "src/index.py",
355
+ commands: "uv sync && uv build",
356
+ specification: "s-0.5vcpu-512mb" as Specification,
357
+ },
358
+ "count-docs-in-collection": {
359
+ runtime: "node-21.0" as Runtime,
360
+ entrypoint: "src/main.ts",
361
+ commands: "npm install && npm run build",
362
+ specification: "s-1vcpu-512mb" as Specification,
363
+ },
364
+ };
365
+
366
+ return defaults[template as keyof typeof defaults] || {
367
+ runtime: "node-21.0" as Runtime,
368
+ entrypoint: "",
369
+ commands: "",
370
+ specification: "s-0.5vcpu-512mb" as Specification,
371
+ };
372
+ }
373
+
319
374
  private async createFunction(): Promise<void> {
320
375
  const { name } = await inquirer.prompt([
321
376
  {
@@ -332,20 +387,24 @@ export class InteractiveCLI {
332
387
  name: "template",
333
388
  message: "Select a template:",
334
389
  choices: [
335
- "typescript-node",
336
- "poetry",
337
- "count-docs-in-collection",
338
- "none",
390
+ { name: "TypeScript Node.js", value: "typescript-node" },
391
+ { name: "Python with UV", value: "uv" },
392
+ { name: "Count Documents in Collection", value: "count-docs-in-collection" },
393
+ { name: "None (Empty Function)", value: "none" },
339
394
  ],
340
395
  },
341
396
  ]);
342
397
 
398
+ // Get template defaults
399
+ const templateDefaults = this.getTemplateDefaults(template);
400
+
343
401
  const { runtime } = await inquirer.prompt([
344
402
  {
345
403
  type: "list",
346
404
  name: "runtime",
347
405
  message: "Select runtime:",
348
406
  choices: Object.values(RuntimeSchema.Values),
407
+ default: templateDefaults.runtime,
349
408
  },
350
409
  ]);
351
410
 
@@ -364,6 +423,7 @@ export class InteractiveCLI {
364
423
  value: s.slug,
365
424
  })),
366
425
  ],
426
+ default: templateDefaults.specification,
367
427
  },
368
428
  ]);
369
429
 
@@ -375,29 +435,50 @@ export class InteractiveCLI {
375
435
  execute: ["any"],
376
436
  enabled: true,
377
437
  logging: true,
378
- entrypoint: template === "none" ? "src/index.ts" : undefined,
379
- specification,
380
- predeployCommands: template.includes("typescript")
381
- ? ["npm install", "npm run build"]
382
- : undefined,
383
- deployDir: template.includes("typescript") ? "dist" : undefined,
438
+ entrypoint: templateDefaults.entrypoint,
439
+ commands: templateDefaults.commands,
440
+ specification: specification || templateDefaults.specification,
441
+ scopes: [],
442
+ timeout: 15,
443
+ schedule: "",
444
+ installationId: "",
445
+ providerRepositoryId: "",
446
+ providerBranch: "",
447
+ providerSilentMode: false,
448
+ providerRootDirectory: "",
449
+ templateRepository: "",
450
+ templateOwner: "",
451
+ templateRootDirectory: "",
384
452
  };
385
453
 
386
454
  if (template !== "none") {
387
455
  await createFunctionTemplate(
388
- template as "typescript-node" | "poetry" | "count-docs-in-collection",
456
+ template as "typescript-node" | "uv" | "count-docs-in-collection",
389
457
  name,
390
458
  "./functions"
391
459
  );
392
460
  }
393
461
 
394
- // Add to config
462
+ // Add to in-memory config
395
463
  if (!this.controller!.config!.functions) {
396
464
  this.controller!.config!.functions = [];
397
465
  }
398
466
  this.controller!.config!.functions.push(functionConfig);
399
467
 
400
- console.log(chalk.green("✨ Function created successfully!"));
468
+ // If using YAML config, also add to YAML file
469
+ const yamlConfigPath = findYamlConfig(this.currentDir);
470
+ if (yamlConfigPath) {
471
+ try {
472
+ await addFunctionToYamlConfig(yamlConfigPath, functionConfig);
473
+ } catch (error) {
474
+ MessageFormatter.warning(
475
+ `Function created but failed to update YAML config: ${error instanceof Error ? error.message : error}`,
476
+ { prefix: "Functions" }
477
+ );
478
+ }
479
+ }
480
+
481
+ MessageFormatter.success("Function created successfully!", { prefix: "Functions" });
401
482
  }
402
483
 
403
484
  private async findFunctionInSubdirectories(
@@ -638,7 +719,7 @@ export class InteractiveCLI {
638
719
  dirPath: functionPath,
639
720
  }
640
721
  );
641
- console.log(chalk.green("Function deployed successfully!"));
722
+ MessageFormatter.success("Function deployed successfully!", { prefix: "Functions" });
642
723
  } catch (error) {
643
724
  console.error(chalk.red("Failed to deploy function:"), error);
644
725
  }
@@ -1373,7 +1454,7 @@ export class InteractiveCLI {
1373
1454
  console.log(chalk.yellow(`Backing up database: ${db.name}`));
1374
1455
  await this.controller!.backupDatabase(db);
1375
1456
  }
1376
- console.log(chalk.green("Database backup completed."));
1457
+ MessageFormatter.success("Database backup completed", { prefix: "Backup" });
1377
1458
  }
1378
1459
 
1379
1460
  private async wipeDatabase(): Promise<void> {
@@ -1408,19 +1489,14 @@ export class InteractiveCLI {
1408
1489
  },
1409
1490
  ]);
1410
1491
 
1411
- const { confirm } = await inquirer.prompt([
1412
- {
1413
- type: "confirm",
1414
- name: "confirm",
1415
- message: chalk.red(
1416
- "Are you sure you want to wipe the selected items? This action cannot be undone."
1417
- ),
1418
- default: false,
1419
- },
1420
- ]);
1492
+ const databaseNames = selectedDatabases.map(db => db.name);
1493
+ const confirmed = await ConfirmationDialogs.confirmDatabaseWipe(databaseNames, {
1494
+ includeStorage: selectedStorage.length > 0,
1495
+ includeUsers: wipeUsers
1496
+ });
1421
1497
 
1422
- if (confirm) {
1423
- console.log(chalk.yellow("Wiping selected items..."));
1498
+ if (confirmed) {
1499
+ MessageFormatter.info("Starting wipe operation...", { prefix: "Wipe" });
1424
1500
  for (const db of selectedDatabases) {
1425
1501
  await this.controller!.wipeDatabase(db);
1426
1502
  }
@@ -1430,9 +1506,9 @@ export class InteractiveCLI {
1430
1506
  if (wipeUsers) {
1431
1507
  await this.controller!.wipeUsers();
1432
1508
  }
1433
- console.log(chalk.green("Wipe operation completed."));
1509
+ MessageFormatter.success("Wipe operation completed", { prefix: "Wipe" });
1434
1510
  } else {
1435
- console.log(chalk.blue("Wipe operation cancelled."));
1511
+ MessageFormatter.info("Wipe operation cancelled", { prefix: "Wipe" });
1436
1512
  }
1437
1513
  }
1438
1514
 
@@ -1459,40 +1535,64 @@ export class InteractiveCLI {
1459
1535
  true
1460
1536
  );
1461
1537
 
1462
- const { confirm } = await inquirer.prompt([
1463
- {
1464
- type: "confirm",
1465
- name: "confirm",
1466
- message: chalk.red(
1467
- `Are you sure you want to wipe the selected collections from ${database.name}? This action cannot be undone.`
1468
- ),
1469
- default: false,
1470
- },
1471
- ]);
1538
+ const collectionNames = collections.map(c => c.name);
1539
+ const confirmed = await ConfirmationDialogs.confirmCollectionWipe(
1540
+ database.name,
1541
+ collectionNames
1542
+ );
1472
1543
 
1473
- if (confirm) {
1474
- console.log(
1475
- chalk.yellow(`Wiping selected collections from ${database.name}...`)
1544
+ if (confirmed) {
1545
+ MessageFormatter.info(
1546
+ `Wiping selected collections from ${database.name}...`,
1547
+ { prefix: "Wipe" }
1476
1548
  );
1477
1549
  for (const collection of collections) {
1478
1550
  await this.controller!.wipeCollection(database, collection);
1479
- console.log(
1480
- chalk.green(`Collection ${collection.name} wiped successfully.`)
1551
+ MessageFormatter.success(
1552
+ `Collection ${collection.name} wiped successfully`,
1553
+ { prefix: "Wipe" }
1481
1554
  );
1482
1555
  }
1483
1556
  } else {
1484
- console.log(
1485
- chalk.blue(`Wipe operation cancelled for ${database.name}.`)
1557
+ MessageFormatter.info(
1558
+ `Wipe operation cancelled for ${database.name}`,
1559
+ { prefix: "Wipe" }
1486
1560
  );
1487
1561
  }
1488
1562
  }
1489
- console.log(chalk.green("Wipe collections operation completed."));
1563
+ MessageFormatter.success("Wipe collections operation completed", { prefix: "Wipe" });
1490
1564
  }
1491
1565
 
1492
1566
  private async generateSchemas(): Promise<void> {
1493
1567
  console.log(chalk.yellow("Generating schemas..."));
1494
- await this.controller!.generateSchemas();
1495
- console.log(chalk.green("Schema generation completed."));
1568
+
1569
+ // Prompt user for schema type preference
1570
+ const { schemaType } = await inquirer.prompt([
1571
+ {
1572
+ type: "list",
1573
+ name: "schemaType",
1574
+ message: "What type of schemas would you like to generate?",
1575
+ choices: [
1576
+ { name: "TypeScript (Zod) schemas", value: "zod" },
1577
+ { name: "JSON schemas", value: "json" },
1578
+ { name: "Both TypeScript and JSON schemas", value: "both" },
1579
+ ],
1580
+ default: "both",
1581
+ },
1582
+ ]);
1583
+
1584
+ // Get the config folder path (where the config file is located)
1585
+ const configFolderPath = this.controller!.getAppwriteFolderPath();
1586
+ if (!configFolderPath) {
1587
+ MessageFormatter.error("Failed to get config folder path", undefined, { prefix: "Schemas" });
1588
+ return;
1589
+ }
1590
+
1591
+ // Create SchemaGenerator with the correct base path and generate schemas
1592
+ const schemaGenerator = new SchemaGenerator(this.controller!.config!, configFolderPath);
1593
+ schemaGenerator.generateSchemas({ format: schemaType, verbose: true });
1594
+
1595
+ MessageFormatter.success("Schema generation completed", { prefix: "Schemas" });
1496
1596
  }
1497
1597
 
1498
1598
  private async importData(): Promise<void> {
@@ -1801,4 +1901,69 @@ export class InteractiveCLI {
1801
1901
  console.error(chalk.red("Error updating function specification:"), error);
1802
1902
  }
1803
1903
  }
1904
+
1905
+ private async detectConfigurationType(): Promise<void> {
1906
+ try {
1907
+ // Check for YAML config first
1908
+ const yamlConfigPath = findYamlConfig(this.currentDir);
1909
+ if (yamlConfigPath) {
1910
+ this.isUsingTypeScriptConfig = false;
1911
+ MessageFormatter.info("Using YAML configuration", { prefix: "Config" });
1912
+ return;
1913
+ }
1914
+
1915
+ // Then check for TypeScript config
1916
+ const configPath = findAppwriteConfig(this.currentDir);
1917
+ if (configPath && configPath.endsWith('.ts')) {
1918
+ this.isUsingTypeScriptConfig = true;
1919
+ MessageFormatter.info("TypeScript configuration detected", { prefix: "Config" });
1920
+ MessageFormatter.info("Consider migrating to YAML for better organization", { prefix: "Config" });
1921
+ return;
1922
+ }
1923
+
1924
+ // No config found
1925
+ this.isUsingTypeScriptConfig = false;
1926
+ MessageFormatter.info("No configuration file found", { prefix: "Config" });
1927
+ } catch (error) {
1928
+ // Silently handle detection errors and continue
1929
+ this.isUsingTypeScriptConfig = false;
1930
+ }
1931
+ }
1932
+
1933
+ private buildChoicesList(): string[] {
1934
+ const allChoices = Object.values(CHOICES);
1935
+
1936
+ if (this.isUsingTypeScriptConfig) {
1937
+ // Place migration option at the top when TS config is detected
1938
+ return [
1939
+ CHOICES.MIGRATE_CONFIG,
1940
+ ...allChoices.filter(choice => choice !== CHOICES.MIGRATE_CONFIG)
1941
+ ];
1942
+ } else {
1943
+ // Hide migration option when using YAML config
1944
+ return allChoices.filter(choice => choice !== CHOICES.MIGRATE_CONFIG);
1945
+ }
1946
+ }
1947
+
1948
+ private async migrateTypeScriptConfig(): Promise<void> {
1949
+ try {
1950
+ MessageFormatter.info("Starting TypeScript to YAML configuration migration...", { prefix: "Migration" });
1951
+
1952
+ // Perform the migration
1953
+ await migrateConfig(this.currentDir);
1954
+
1955
+ // Reset the detection flag
1956
+ this.isUsingTypeScriptConfig = false;
1957
+
1958
+ // Reset the controller to pick up the new config
1959
+ this.controller = undefined;
1960
+
1961
+ MessageFormatter.success("Migration completed successfully!", { prefix: "Migration" });
1962
+ MessageFormatter.info("Your configuration has been migrated to the .appwrite directory structure", { prefix: "Migration" });
1963
+ MessageFormatter.info("You can now use YAML configuration for easier management", { prefix: "Migration" });
1964
+
1965
+ } catch (error) {
1966
+ MessageFormatter.error("Migration failed", error instanceof Error ? error : new Error(String(error)), { prefix: "Migration" });
1967
+ }
1968
+ }
1804
1969
  }