appwrite-utils-cli 0.10.86 → 1.0.2

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 +264 -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 +262 -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 +379 -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 +349 -0
  160. package/src/utils/loadConfigs.ts +416 -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
@@ -67,7 +67,7 @@ export const validationRules = {
67
67
  isDate: (value: any): boolean => isDate(value),
68
68
  isEmpty: (value: any): boolean => isEmpty(value),
69
69
  isInteger: (value: any): boolean => isInteger(value),
70
- isFloat: (value: any): boolean => isNumber(value) && !isInteger(value),
70
+ isFloat: (value: any): boolean => isNumber(value) && !isInteger(value), // Note: Works for double precision numbers
71
71
  isArrayLike: (value: any): boolean => isArrayLike(value),
72
72
  isArrayLikeObject: (value: any): boolean => isArrayLikeObject(value),
73
73
  isFunction: (value: any): boolean => isFunction(value),
@@ -0,0 +1,131 @@
1
+ import yaml from "js-yaml";
2
+ import type { Collection, CollectionCreate } from "appwrite-utils";
3
+
4
+ export interface YamlCollectionData {
5
+ name: string;
6
+ id?: string;
7
+ documentSecurity?: boolean;
8
+ enabled?: boolean;
9
+ permissions?: Array<{
10
+ permission: string;
11
+ target: string;
12
+ }>;
13
+ attributes?: Array<{
14
+ key: string;
15
+ type: string;
16
+ size?: number;
17
+ required?: boolean;
18
+ array?: boolean;
19
+ default?: any;
20
+ description?: string;
21
+ min?: number;
22
+ max?: number;
23
+ elements?: string[];
24
+ relatedCollection?: string;
25
+ relationType?: string;
26
+ twoWay?: boolean;
27
+ twoWayKey?: string;
28
+ onDelete?: string;
29
+ side?: string;
30
+ }>;
31
+ indexes?: Array<{
32
+ key: string;
33
+ type: string;
34
+ attributes: string[];
35
+ orders?: string[];
36
+ }>;
37
+ importDefs?: any[];
38
+ }
39
+
40
+ /**
41
+ * Converts a Collection object to YAML format with proper schema reference
42
+ */
43
+ export function collectionToYaml(collection: Collection | CollectionCreate, schemaPath = "../.yaml_schemas/collection.schema.json"): string {
44
+ // Convert Collection to YamlCollectionData format
45
+ const yamlData: YamlCollectionData = {
46
+ name: collection.name,
47
+ id: collection.$id,
48
+ documentSecurity: collection.documentSecurity,
49
+ enabled: collection.enabled,
50
+ };
51
+
52
+ // Convert permissions
53
+ if (collection.$permissions && collection.$permissions.length > 0) {
54
+ yamlData.permissions = collection.$permissions.map(p => ({
55
+ permission: p.permission,
56
+ target: p.target
57
+ }));
58
+ }
59
+
60
+ // Convert attributes
61
+ if (collection.attributes && collection.attributes.length > 0) {
62
+ yamlData.attributes = collection.attributes.map(attr => {
63
+ const yamlAttr: any = {
64
+ key: attr.key,
65
+ type: attr.type,
66
+ };
67
+
68
+ // Add optional properties only if they exist (safely access with 'in' operator)
69
+ if ('size' in attr && attr.size !== undefined) yamlAttr.size = attr.size;
70
+ if (attr.required !== undefined) yamlAttr.required = attr.required;
71
+ if (attr.array !== undefined) yamlAttr.array = attr.array;
72
+ if ('xdefault' in attr && attr.xdefault !== undefined) yamlAttr.default = attr.xdefault;
73
+ if (attr.description !== undefined) yamlAttr.description = attr.description;
74
+ if ('min' in attr && attr.min !== undefined) yamlAttr.min = attr.min;
75
+ if ('max' in attr && attr.max !== undefined) yamlAttr.max = attr.max;
76
+ if ('elements' in attr && attr.elements !== undefined) yamlAttr.elements = attr.elements;
77
+ if ('relatedCollection' in attr && attr.relatedCollection !== undefined) yamlAttr.relatedCollection = attr.relatedCollection;
78
+ if ('relationType' in attr && attr.relationType !== undefined) yamlAttr.relationType = attr.relationType;
79
+ if ('twoWay' in attr && attr.twoWay !== undefined) yamlAttr.twoWay = attr.twoWay;
80
+ if ('twoWayKey' in attr && attr.twoWayKey !== undefined) yamlAttr.twoWayKey = attr.twoWayKey;
81
+ if ('onDelete' in attr && attr.onDelete !== undefined) yamlAttr.onDelete = attr.onDelete;
82
+ if ('side' in attr && attr.side !== undefined) yamlAttr.side = attr.side;
83
+
84
+ return yamlAttr;
85
+ });
86
+ }
87
+
88
+ // Convert indexes
89
+ if (collection.indexes && collection.indexes.length > 0) {
90
+ yamlData.indexes = collection.indexes.map(idx => ({
91
+ key: idx.key,
92
+ type: idx.type,
93
+ attributes: idx.attributes,
94
+ ...(idx.orders && idx.orders.length > 0 ? { orders: idx.orders } : {})
95
+ }));
96
+ }
97
+
98
+ // Add import definitions if they exist
99
+ if (collection.importDefs && collection.importDefs.length > 0) {
100
+ yamlData.importDefs = collection.importDefs;
101
+ } else {
102
+ yamlData.importDefs = [];
103
+ }
104
+
105
+ // Generate YAML with schema reference
106
+ const yamlContent = yaml.dump(yamlData, {
107
+ indent: 2,
108
+ lineWidth: 120,
109
+ sortKeys: false,
110
+ quotingType: '"',
111
+ forceQuotes: false,
112
+ });
113
+
114
+ return `# yaml-language-server: $schema=${schemaPath}
115
+ # Collection Definition: ${collection.name}
116
+ ${yamlContent}`;
117
+ }
118
+
119
+ /**
120
+ * Sanitizes a collection name for use as a filename
121
+ */
122
+ export function sanitizeFilename(name: string): string {
123
+ return name.replace(/[^a-zA-Z0-9_-]/g, '_');
124
+ }
125
+
126
+ /**
127
+ * Generates the filename for a collection YAML file
128
+ */
129
+ export function getCollectionYamlFilename(collection: Collection | CollectionCreate): string {
130
+ return `${sanitizeFilename(collection.name)}.yaml`;
131
+ }
@@ -13,10 +13,11 @@ import {
13
13
  } from "appwrite-utils";
14
14
  import {
15
15
  loadConfig,
16
+ loadConfigWithPath,
16
17
  findAppwriteConfig,
17
18
  findFunctionsDir,
18
19
  } from "./utils/loadConfigs.js";
19
- import { UsersController } from "./migrations/users.js";
20
+ import { UsersController } from "./users/methods.js";
20
21
  import { AppwriteToX } from "./migrations/appwriteToX.js";
21
22
  import { ImportController } from "./migrations/importController.js";
22
23
  import { ImportDataActions } from "./migrations/importDataActions.js";
@@ -25,7 +26,7 @@ import {
25
26
  ensureDatabasesExist,
26
27
  wipeOtherDatabases,
27
28
  ensureCollectionsExist,
28
- } from "./migrations/setupDatabase.js";
29
+ } from "./databases/setup.js";
29
30
  import {
30
31
  createOrUpdateCollections,
31
32
  wipeDatabase,
@@ -57,7 +58,7 @@ import {
57
58
  type TransferOptions,
58
59
  } from "./migrations/transfer.js";
59
60
  import { getClient } from "./utils/getClientFromConfig.js";
60
- import { fetchAllDatabases } from "./migrations/databases.js";
61
+ import { fetchAllDatabases } from "./databases/methods.js";
61
62
  import {
62
63
  listFunctions,
63
64
  updateFunctionSpecifications,
@@ -65,6 +66,8 @@ import {
65
66
  import chalk from "chalk";
66
67
  import { deployLocalFunction } from "./functions/deployments.js";
67
68
  import fs from "node:fs";
69
+ import { configureLogging, updateLogger } from "./shared/logging.js";
70
+ import { MessageFormatter, Messages } from "./shared/messageFormatter.js";
68
71
 
69
72
  export interface SetupOptions {
70
73
  databases?: Models.Database[];
@@ -105,15 +108,15 @@ export class UtilsController {
105
108
  if (directConfig) {
106
109
  let hasErrors = false;
107
110
  if (!directConfig.appwriteEndpoint) {
108
- console.log(chalk.red("Appwrite endpoint is required"));
111
+ MessageFormatter.error("Appwrite endpoint is required", undefined, { prefix: "Config" });
109
112
  hasErrors = true;
110
113
  }
111
114
  if (!directConfig.appwriteProject) {
112
- console.log(chalk.red("Appwrite project is required"));
115
+ MessageFormatter.error("Appwrite project is required", undefined, { prefix: "Config" });
113
116
  hasErrors = true;
114
117
  }
115
118
  if (!directConfig.appwriteKey) {
116
- console.log(chalk.red("Appwrite key is required"));
119
+ MessageFormatter.error("Appwrite key is required", undefined, { prefix: "Config" });
117
120
  hasErrors = true;
118
121
  }
119
122
  if (!hasErrors) {
@@ -130,42 +133,56 @@ export class UtilsController {
130
133
  enableMockData: false,
131
134
  documentBucketId: "",
132
135
  usersCollectionName: "",
136
+ useMigrations: true,
133
137
  databases: [],
134
138
  buckets: [],
135
139
  functions: [],
140
+ logging: {
141
+ enabled: false,
142
+ level: "info",
143
+ console: false,
144
+ },
136
145
  };
137
146
  }
138
147
  } else {
139
148
  // Try to find config file
140
149
  const appwriteConfigFound = findAppwriteConfig(basePath);
141
150
  if (!appwriteConfigFound) {
142
- console.log(
143
- chalk.yellow(
144
- "No appwriteConfig.ts found and no direct configuration provided"
145
- )
151
+ MessageFormatter.warning(
152
+ "No appwriteConfig.ts found and no direct configuration provided",
153
+ { prefix: "Config" }
146
154
  );
147
155
  return;
148
156
  }
149
157
  this.appwriteConfigPath = appwriteConfigFound;
150
- this.appwriteFolderPath = path.dirname(appwriteConfigFound);
158
+ this.appwriteFolderPath = appwriteConfigFound; // For YAML configs, findAppwriteConfig already returns the correct directory
151
159
  }
152
160
  }
153
161
 
154
162
  async init() {
155
163
  if (!this.config) {
156
164
  if (this.appwriteFolderPath && this.appwriteConfigPath) {
157
- console.log("Loading config from file...");
158
- this.config = await loadConfig(this.appwriteFolderPath);
159
- if (!this.config) {
160
- console.log(chalk.red("Failed to load config from file"));
165
+ MessageFormatter.progress("Loading config from file...", { prefix: "Config" });
166
+ try {
167
+ const { config, actualConfigPath } = await loadConfigWithPath(this.appwriteFolderPath);
168
+ this.config = config;
169
+ MessageFormatter.info(`Loaded config from: ${actualConfigPath}`, { prefix: "Config" });
170
+ } catch (error) {
171
+ MessageFormatter.error("Failed to load config from file", undefined, { prefix: "Config" });
161
172
  return;
162
173
  }
163
174
  } else {
164
- console.log(chalk.red("No configuration available"));
175
+ MessageFormatter.error("No configuration available", undefined, { prefix: "Config" });
165
176
  return;
166
177
  }
167
178
  }
168
179
 
180
+ // Configure logging based on config
181
+ if (this.config.logging) {
182
+ configureLogging(this.config.logging);
183
+ updateLogger();
184
+ }
185
+
169
186
  this.appwriteServer = new Client();
170
187
  this.appwriteServer
171
188
  .setEndpoint(this.config.appwriteEndpoint)
@@ -179,7 +196,7 @@ export class UtilsController {
179
196
 
180
197
  async reloadConfig() {
181
198
  if (!this.appwriteFolderPath) {
182
- console.log(chalk.red("Failed to get appwriteFolderPath"));
199
+ MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
183
200
  return;
184
201
  }
185
202
  this.config = await loadConfig(this.appwriteFolderPath);
@@ -187,6 +204,13 @@ export class UtilsController {
187
204
  console.log(chalk.red("Failed to load config"));
188
205
  return;
189
206
  }
207
+
208
+ // Configure logging based on updated config
209
+ if (this.config.logging) {
210
+ configureLogging(this.config.logging);
211
+ updateLogger();
212
+ }
213
+
190
214
  this.appwriteServer = new Client();
191
215
  this.appwriteServer
192
216
  .setEndpoint(this.config.appwriteEndpoint)
@@ -200,7 +224,7 @@ export class UtilsController {
200
224
  async setupMigrationDatabase() {
201
225
  await this.init();
202
226
  if (!this.config) {
203
- console.log(chalk.red("Config not initialized"));
227
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
204
228
  return;
205
229
  }
206
230
  await setupMigrationDatabase(this.config);
@@ -209,11 +233,11 @@ export class UtilsController {
209
233
  async ensureDatabaseConfigBucketsExist(databases: Models.Database[] = []) {
210
234
  await this.init();
211
235
  if (!this.storage) {
212
- console.log(chalk.red("Storage not initialized"));
236
+ MessageFormatter.error("Storage not initialized", undefined, { prefix: "Controller" });
213
237
  return;
214
238
  }
215
239
  if (!this.config) {
216
- console.log(chalk.red("Config not initialized"));
240
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
217
241
  return;
218
242
  }
219
243
  await ensureDatabaseConfigBucketsExist(
@@ -226,7 +250,7 @@ export class UtilsController {
226
250
  async ensureDatabasesExist(databases?: Models.Database[]) {
227
251
  await this.init();
228
252
  if (!this.config) {
229
- console.log(chalk.red("Config not initialized"));
253
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
230
254
  return;
231
255
  }
232
256
  await this.setupMigrationDatabase();
@@ -240,7 +264,7 @@ export class UtilsController {
240
264
  ) {
241
265
  await this.init();
242
266
  if (!this.config) {
243
- console.log(chalk.red("Config not initialized"));
267
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
244
268
  return;
245
269
  }
246
270
  await ensureCollectionsExist(this.config, database, collections);
@@ -249,7 +273,7 @@ export class UtilsController {
249
273
  async getDatabasesByIds(ids: string[]) {
250
274
  await this.init();
251
275
  if (!this.database) {
252
- console.log(chalk.red("Database not initialized"));
276
+ MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
253
277
  return;
254
278
  }
255
279
  if (ids.length === 0) return [];
@@ -263,10 +287,10 @@ export class UtilsController {
263
287
  async wipeOtherDatabases(databasesToKeep: Models.Database[]) {
264
288
  await this.init();
265
289
  if (!this.database) {
266
- console.log(chalk.red("Database not initialized"));
290
+ MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
267
291
  return;
268
292
  }
269
- await wipeOtherDatabases(this.database, databasesToKeep);
293
+ await wipeOtherDatabases(this.database, databasesToKeep, this.config?.useMigrations ?? true);
270
294
  }
271
295
 
272
296
  async wipeUsers() {
@@ -307,7 +331,7 @@ export class UtilsController {
307
331
 
308
332
  async findFunctionDirectories() {
309
333
  if (!this.appwriteFolderPath) {
310
- console.log(chalk.red("Failed to get appwriteFolderPath"));
334
+ MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
311
335
  return new Map();
312
336
  }
313
337
  const functionsDir = findFunctionsDir(this.appwriteFolderPath);
@@ -378,11 +402,11 @@ export class UtilsController {
378
402
  ]);
379
403
 
380
404
  for (const localFunction of localFunctions) {
381
- console.log(chalk.blue(`Syncing function ${localFunction.name}...`));
405
+ MessageFormatter.progress(`Syncing function ${localFunction.name}...`, { prefix: "Functions" });
382
406
  await this.deployFunction(localFunction.name);
383
407
  }
384
408
 
385
- console.log(chalk.green("All functions synchronized successfully!"));
409
+ MessageFormatter.success("All functions synchronized successfully!", { prefix: "Functions" });
386
410
  }
387
411
 
388
412
  async wipeDatabase(database: Models.Database, wipeBucket: boolean = false) {
@@ -443,7 +467,7 @@ export class UtilsController {
443
467
  if (!this.database || !this.config)
444
468
  throw new Error("Database or config not initialized");
445
469
  for (const database of databases) {
446
- if (database.$id === "migrations") continue;
470
+ if (!this.config.useMigrations && database.$id === "migrations") continue;
447
471
  await this.createOrUpdateCollections(database, undefined, collections);
448
472
  }
449
473
  }
@@ -468,11 +492,11 @@ export class UtilsController {
468
492
  async generateSchemas() {
469
493
  await this.init();
470
494
  if (!this.config) {
471
- console.log(chalk.red("Config not initialized"));
495
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
472
496
  return;
473
497
  }
474
498
  if (!this.appwriteFolderPath) {
475
- console.log(chalk.red("Failed to get appwriteFolderPath"));
499
+ MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
476
500
  return;
477
501
  }
478
502
  await generateSchemas(this.config, this.appwriteFolderPath);
@@ -481,19 +505,19 @@ export class UtilsController {
481
505
  async importData(options: SetupOptions = {}) {
482
506
  await this.init();
483
507
  if (!this.database) {
484
- console.log(chalk.red("Database not initialized"));
508
+ MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
485
509
  return;
486
510
  }
487
511
  if (!this.storage) {
488
- console.log(chalk.red("Storage not initialized"));
512
+ MessageFormatter.error("Storage not initialized", undefined, { prefix: "Controller" });
489
513
  return;
490
514
  }
491
515
  if (!this.config) {
492
- console.log(chalk.red("Config not initialized"));
516
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
493
517
  return;
494
518
  }
495
519
  if (!this.appwriteFolderPath) {
496
- console.log(chalk.red("Failed to get appwriteFolderPath"));
520
+ MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
497
521
  return;
498
522
  }
499
523
 
@@ -524,16 +548,16 @@ export class UtilsController {
524
548
  ) {
525
549
  await this.init();
526
550
  if (!this.storage) {
527
- console.log(chalk.red("Storage not initialized"));
551
+ MessageFormatter.error("Storage not initialized", undefined, { prefix: "Controller" });
528
552
  return;
529
553
  }
530
554
  const configToUse = config || this.config;
531
555
  if (!configToUse) {
532
- console.log(chalk.red("Config not initialized"));
556
+ MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
533
557
  return;
534
558
  }
535
559
  if (!this.appwriteFolderPath) {
536
- console.log(chalk.red("Failed to get appwriteFolderPath"));
560
+ MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
537
561
  return;
538
562
  }
539
563
  const appwriteToX = new AppwriteToX(
@@ -550,7 +574,7 @@ export class UtilsController {
550
574
  ) {
551
575
  await this.init();
552
576
  if (!this.database) {
553
- console.log(chalk.red("Database not initialized"));
577
+ MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
554
578
  return;
555
579
  }
556
580
  if (databases.length === 0) {
@@ -644,7 +668,7 @@ export class UtilsController {
644
668
  console.log(chalk.red("Appwrite server not initialized"));
645
669
  return;
646
670
  } else {
647
- console.log(chalk.blue("Starting user transfer..."));
671
+ MessageFormatter.progress("Starting user transfer...", { prefix: "Transfer" });
648
672
  const localUsers = new Users(this.appwriteServer);
649
673
  await transferUsersLocalToRemote(
650
674
  localUsers,
@@ -652,7 +676,7 @@ export class UtilsController {
652
676
  options.transferProject!,
653
677
  options.transferKey!
654
678
  );
655
- console.log(chalk.green("User transfer completed"));
679
+ MessageFormatter.success("User transfer completed", { prefix: "Transfer" });
656
680
  }
657
681
  }
658
682
 
@@ -677,10 +701,9 @@ export class UtilsController {
677
701
  .replace(/\s+/g, "")}`);
678
702
 
679
703
  if (sourceBucketId && targetBucketId) {
680
- console.log(
681
- chalk.blue(
682
- `Starting storage transfer from ${sourceBucketId} to ${targetBucketId}`
683
- )
704
+ MessageFormatter.progress(
705
+ `Starting storage transfer from ${sourceBucketId} to ${targetBucketId}`,
706
+ { prefix: "Transfer" }
684
707
  );
685
708
 
686
709
  if (options.isRemote) {
@@ -702,7 +725,7 @@ export class UtilsController {
702
725
  }
703
726
  }
704
727
 
705
- console.log(chalk.green("Transfer completed"));
728
+ MessageFormatter.success("Transfer completed", { prefix: "Transfer" });
706
729
  }
707
730
 
708
731
  async updateFunctionSpecifications(
@@ -712,20 +735,18 @@ export class UtilsController {
712
735
  await this.init();
713
736
  if (!this.appwriteServer)
714
737
  throw new Error("Appwrite server not initialized");
715
- console.log(
716
- chalk.green(
717
- `Updating function specifications for ${functionId} to ${specification}`
718
- )
738
+ MessageFormatter.progress(
739
+ `Updating function specifications for ${functionId} to ${specification}`,
740
+ { prefix: "Functions" }
719
741
  );
720
742
  await updateFunctionSpecifications(
721
743
  this.appwriteServer,
722
744
  functionId,
723
745
  specification
724
746
  );
725
- console.log(
726
- chalk.green(
727
- `Successfully updated function specifications for ${functionId} to ${specification}`
728
- )
747
+ MessageFormatter.success(
748
+ `Successfully updated function specifications for ${functionId} to ${specification}`,
749
+ { prefix: "Functions" }
729
750
  );
730
751
  }
731
752
  }
@@ -1,30 +0,0 @@
1
- # Python Poetry Function Template
2
-
3
- This is a Python template for Appwrite Functions using Poetry for dependency management.
4
-
5
- ## Structure
6
- - `src/index.py`: Main function entry point
7
- - `pyproject.toml`: Poetry 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 Poetry: `curl -sSL https://install.python-poetry.org | python3 -`
25
- 2. Install dependencies: `poetry install`
26
- 3. Deploy: Dependencies will be installed during deployment
27
-
28
- ## Deployment
29
- Make sure it's inside `appwriteConfig.ts` functions array, and if you want to install dependencies FIRST, before Appwrite (using your system), you can
30
- add the `predeployCommands` to the function in `appwriteConfig.ts`.
@@ -1,16 +0,0 @@
1
- [tool.poetry]
2
- name = "{{functionName}}"
3
- version = "0.1.0"
4
- description = ""
5
- authors = ["Your Name <you@example.com>"]
6
- packages = [
7
- { include = "src" }
8
- ]
9
-
10
- [tool.poetry.dependencies]
11
- python = "^3.9"
12
- appwrite = "^7.0.1"
13
-
14
- [build-system]
15
- requires = ["poetry-core>=1.0.0"]
16
- build-backend = "poetry.core.masonry.api"