appwrite-utils-cli 0.10.85 → 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 +261 -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 +196 -52
  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 +230 -63
  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
@@ -2,15 +2,23 @@ import { mkdirSync, writeFileSync, existsSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import type { AppwriteConfig } from "appwrite-utils";
4
4
  import { findAppwriteConfig } from "./loadConfigs.js";
5
+ import { findYamlConfig } from "../config/yamlConfig.js";
5
6
  import { ID } from "node-appwrite";
6
7
  import { ulid } from "ulidx";
8
+ import { generateYamlConfigTemplate } from "../config/yamlConfig.js";
7
9
 
8
10
  // Example base configuration using types from appwrite-utils
9
11
  const baseConfig: AppwriteConfig = {
10
12
  appwriteEndpoint: "https://cloud.appwrite.io/v1",
11
13
  appwriteProject: "YOUR_PROJECT_ID",
12
14
  appwriteKey: "YOUR_API_KEY",
15
+ logging: {
16
+ enabled: false,
17
+ level: "info",
18
+ console: false,
19
+ },
13
20
  enableBackups: true,
21
+ useMigrations: true,
14
22
  backupInterval: 3600,
15
23
  backupRetention: 30,
16
24
  enableBackupCleanup: true,
@@ -121,7 +129,78 @@ export const customAfterImportActions: AfterImportActions = {
121
129
  }`;
122
130
 
123
131
  export const createEmptyCollection = (collectionName: string) => {
124
- const emptyCollection = `import type { CollectionCreate } from "appwrite-utils";
132
+ const currentDir = process.cwd();
133
+
134
+ // Check for YAML config first (preferred)
135
+ const yamlConfigPath = findYamlConfig(currentDir);
136
+ const tsConfigPath = findAppwriteConfig(currentDir);
137
+
138
+ let configDir: string;
139
+ let isYamlProject = false;
140
+
141
+ if (yamlConfigPath) {
142
+ configDir = path.dirname(yamlConfigPath);
143
+ isYamlProject = true;
144
+ } else if (tsConfigPath) {
145
+ configDir = path.dirname(tsConfigPath);
146
+ isYamlProject = false;
147
+ } else {
148
+ // No config found - assume .appwrite directory and use YAML as default
149
+ configDir = path.join(currentDir, ".appwrite");
150
+ isYamlProject = true;
151
+
152
+ // Create .appwrite directory if it doesn't exist
153
+ if (!existsSync(configDir)) {
154
+ mkdirSync(configDir, { recursive: true });
155
+ }
156
+ }
157
+
158
+ const collectionsFolder = path.join(configDir, "collections");
159
+ if (!existsSync(collectionsFolder)) {
160
+ mkdirSync(collectionsFolder, { recursive: true });
161
+ }
162
+
163
+ if (isYamlProject) {
164
+ // Create YAML collection
165
+ const yamlCollection = `# yaml-language-server: $schema=../.yaml_schemas/collection.schema.json
166
+ # Collection Definition: ${collectionName}
167
+ name: ${collectionName}
168
+ id: ${ulid()}
169
+ documentSecurity: false
170
+ enabled: true
171
+ permissions:
172
+ - permission: read
173
+ target: any
174
+ - permission: create
175
+ target: users
176
+ - permission: update
177
+ target: users
178
+ - permission: delete
179
+ target: users
180
+ attributes:
181
+ # Add your attributes here
182
+ # Example:
183
+ # - key: title
184
+ # type: string
185
+ # size: 255
186
+ # required: true
187
+ # description: "The title of the item"
188
+ indexes:
189
+ # Add your indexes here
190
+ # Example:
191
+ # - key: title_search
192
+ # type: fulltext
193
+ # attributes:
194
+ # - title
195
+ importDefs: []
196
+ `;
197
+
198
+ const collectionFilePath = path.join(collectionsFolder, `${collectionName}.yaml`);
199
+ writeFileSync(collectionFilePath, yamlCollection);
200
+ console.log(`✨ Created YAML collection: ${collectionFilePath}`);
201
+ } else {
202
+ // Create TypeScript collection
203
+ const emptyCollection = `import type { CollectionCreate } from "appwrite-utils";
125
204
 
126
205
  const ${collectionName}: Partial<CollectionCreate> = {
127
206
  $id: '${ulid()}',
@@ -144,49 +223,49 @@ const ${collectionName}: Partial<CollectionCreate> = {
144
223
 
145
224
  export default ${collectionName};`;
146
225
 
147
- const appwriteConfigPath = findAppwriteConfig(process.cwd());
148
- if (!appwriteConfigPath) {
149
- console.error("Failed to find appwriteConfig.ts");
150
- return;
226
+ const collectionFilePath = path.join(collectionsFolder, `${collectionName}.ts`);
227
+ writeFileSync(collectionFilePath, emptyCollection);
228
+ console.log(`✨ Created TypeScript collection: ${collectionFilePath}`);
151
229
  }
230
+ };
152
231
 
153
- const collectionsFolder = path.join(
154
- path.dirname(appwriteConfigPath),
155
- "collections"
156
- );
157
- const collectionFilePath = path.join(
158
- collectionsFolder,
159
- `${collectionName}.ts`
160
- );
161
- writeFileSync(collectionFilePath, emptyCollection);
232
+ export const generateYamlConfig = (currentDir?: string, useAppwriteDir: boolean = true) => {
233
+ const basePath = currentDir || process.cwd();
234
+ const configDir = useAppwriteDir ? path.join(basePath, ".appwrite") : basePath;
235
+
236
+ if (!existsSync(configDir)) {
237
+ mkdirSync(configDir, { recursive: true });
238
+ }
239
+
240
+ const configPath = path.join(configDir, "config.yaml");
241
+ generateYamlConfigTemplate(configPath);
242
+
243
+ console.log(`✨ Generated YAML config template at: ${configPath}`);
244
+ console.log("📝 Please update the configuration with your Appwrite project details.");
245
+
246
+ return configPath;
162
247
  };
163
248
 
164
249
  export const setupDirsFiles = async (
165
250
  example: boolean = false,
166
- currentDir?: string
251
+ currentDir?: string,
252
+ useYaml: boolean = true
167
253
  ) => {
168
254
  const basePath = currentDir || process.cwd();
169
- const srcPath = path.join(basePath);
170
-
171
- // Check if src directory exists in the current working directory
172
- if (!existsSync(srcPath)) {
173
- console.error("No 'src' directory found in the current working directory.");
174
- return;
175
- }
176
-
177
- const appwriteFolder = path.join(srcPath, "appwrite");
255
+
256
+ // Create .appwrite folder directly in project root
257
+ const appwriteFolder = path.join(basePath, ".appwrite");
178
258
  const appwriteConfigFile = path.join(appwriteFolder, "appwriteConfig.ts");
179
259
  const appwriteCustomDefsFile = path.join(
180
260
  appwriteFolder,
181
261
  "customDefinitions.ts"
182
262
  );
183
- // const appwriteMigrationsFolder = path.join(appwriteFolder, "migrations");
184
263
  const appwriteSchemaFolder = path.join(appwriteFolder, "schemas");
264
+ const appwriteYamlSchemaFolder = path.join(appwriteFolder, ".yaml_schemas");
185
265
  const appwriteDataFolder = path.join(appwriteFolder, "importData");
186
- const appwriteHiddenFolder = path.join(appwriteFolder, ".appwrite");
187
266
  const collectionsFolder = path.join(appwriteFolder, "collections");
188
267
 
189
- // Directory creation and file writing logic remains the same
268
+ // Create directory structure
190
269
  if (!existsSync(appwriteFolder)) {
191
270
  mkdirSync(appwriteFolder, { recursive: true });
192
271
  }
@@ -195,7 +274,12 @@ export const setupDirsFiles = async (
195
274
  mkdirSync(collectionsFolder, { recursive: true });
196
275
  }
197
276
 
198
- if (!existsSync(appwriteConfigFile)) {
277
+ // Handle configuration file creation - YAML is now default
278
+ if (useYaml) {
279
+ // Generate YAML config in .appwrite directory
280
+ const configPath = path.join(appwriteFolder, "config.yaml");
281
+ generateYamlConfigTemplate(configPath);
282
+ } else if (!existsSync(appwriteConfigFile)) {
199
283
  if (example) {
200
284
  writeFileSync(appwriteConfigFile, configFileExample);
201
285
  } else {
@@ -209,14 +293,618 @@ export default appwriteConfig;
209
293
  }
210
294
  }
211
295
 
212
- // Create TypeScript files for each collection
213
- collectionsConfig.forEach((collection) => {
214
- const collectionFilePath = path.join(
215
- collectionsFolder,
216
- `${collection.name}.ts`
217
- );
218
- writeFileSync(collectionFilePath, collection.content);
219
- });
296
+ // Create TypeScript files for each collection only if not using YAML
297
+ if (!useYaml) {
298
+ collectionsConfig.forEach((collection) => {
299
+ const collectionFilePath = path.join(
300
+ collectionsFolder,
301
+ `${collection.name}.ts`
302
+ );
303
+ writeFileSync(collectionFilePath, collection.content);
304
+ });
305
+ }
306
+
307
+ // Create YAML collection example if using YAML config
308
+ if (useYaml) {
309
+ const yamlCollectionExample = `# yaml-language-server: $schema=../.yaml_schemas/collection.schema.json
310
+ # Example Collection Definition
311
+ name: ExampleCollection
312
+ id: example_collection_${Date.now()}
313
+ documentSecurity: false
314
+ enabled: true
315
+ permissions:
316
+ - permission: read
317
+ target: any
318
+ - permission: create
319
+ target: users
320
+ - permission: update
321
+ target: users
322
+ - permission: delete
323
+ target: users
324
+ attributes:
325
+ - key: title
326
+ type: string
327
+ size: 255
328
+ required: true
329
+ description: "The title of the item"
330
+ - key: description
331
+ type: string
332
+ size: 1000
333
+ required: false
334
+ description: "A longer description"
335
+ - key: isActive
336
+ type: boolean
337
+ required: false
338
+ default: true
339
+ indexes:
340
+ - key: title_search
341
+ type: fulltext
342
+ attributes:
343
+ - title
344
+ importDefs: []
345
+ `;
346
+ const yamlCollectionPath = path.join(collectionsFolder, "ExampleCollection.yaml");
347
+ writeFileSync(yamlCollectionPath, yamlCollectionExample);
348
+
349
+ // Create JSON schema for collection definitions
350
+ const collectionJsonSchema = {
351
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
352
+ "$id": "https://appwrite-utils.dev/schemas/collection.schema.json",
353
+ "title": "Appwrite Collection Definition",
354
+ "description": "Schema for defining Appwrite collections in YAML",
355
+ "type": "object",
356
+ "properties": {
357
+ "name": {
358
+ "type": "string",
359
+ "description": "The name of the collection"
360
+ },
361
+ "id": {
362
+ "type": "string",
363
+ "description": "The ID of the collection (optional, auto-generated if not provided)",
364
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,35}$"
365
+ },
366
+ "documentSecurity": {
367
+ "type": "boolean",
368
+ "default": false,
369
+ "description": "Enable document-level permissions"
370
+ },
371
+ "enabled": {
372
+ "type": "boolean",
373
+ "default": true,
374
+ "description": "Whether the collection is enabled"
375
+ },
376
+ "permissions": {
377
+ "type": "array",
378
+ "description": "Collection-level permissions",
379
+ "items": {
380
+ "type": "object",
381
+ "properties": {
382
+ "permission": {
383
+ "type": "string",
384
+ "enum": ["read", "create", "update", "delete"],
385
+ "description": "The permission type"
386
+ },
387
+ "target": {
388
+ "type": "string",
389
+ "description": "Permission target (e.g., 'any', 'users', 'users/verified', 'label:admin')"
390
+ }
391
+ },
392
+ "required": ["permission", "target"],
393
+ "additionalProperties": false
394
+ }
395
+ },
396
+ "attributes": {
397
+ "type": "array",
398
+ "description": "Collection attributes (fields)",
399
+ "items": {
400
+ "type": "object",
401
+ "properties": {
402
+ "key": {
403
+ "type": "string",
404
+ "description": "Attribute name",
405
+ "pattern": "^[a-zA-Z][a-zA-Z0-9]*$"
406
+ },
407
+ "type": {
408
+ "type": "string",
409
+ "enum": ["string", "integer", "double", "boolean", "datetime", "email", "ip", "url", "enum", "relationship"],
410
+ "description": "Attribute data type"
411
+ },
412
+ "size": {
413
+ "type": "number",
414
+ "description": "Maximum size for string attributes",
415
+ "minimum": 1,
416
+ "maximum": 1073741824
417
+ },
418
+ "required": {
419
+ "type": "boolean",
420
+ "default": false,
421
+ "description": "Whether the attribute is required"
422
+ },
423
+ "array": {
424
+ "type": "boolean",
425
+ "default": false,
426
+ "description": "Whether the attribute is an array"
427
+ },
428
+ "default": {
429
+ "description": "Default value for the attribute"
430
+ },
431
+ "description": {
432
+ "type": "string",
433
+ "description": "Attribute description"
434
+ },
435
+ "min": {
436
+ "type": "number",
437
+ "description": "Minimum value for numeric attributes"
438
+ },
439
+ "max": {
440
+ "type": "number",
441
+ "description": "Maximum value for numeric attributes"
442
+ },
443
+ "elements": {
444
+ "type": "array",
445
+ "items": {
446
+ "type": "string"
447
+ },
448
+ "description": "Allowed values for enum attributes"
449
+ },
450
+ "relatedCollection": {
451
+ "type": "string",
452
+ "description": "Related collection name for relationship attributes"
453
+ },
454
+ "relationType": {
455
+ "type": "string",
456
+ "enum": ["oneToOne", "oneToMany", "manyToOne", "manyToMany"],
457
+ "description": "Type of relationship"
458
+ },
459
+ "twoWay": {
460
+ "type": "boolean",
461
+ "description": "Whether the relationship is bidirectional"
462
+ },
463
+ "twoWayKey": {
464
+ "type": "string",
465
+ "description": "Key name for the reverse relationship"
466
+ },
467
+ "onDelete": {
468
+ "type": "string",
469
+ "enum": ["cascade", "restrict", "setNull"],
470
+ "description": "Action to take when related document is deleted"
471
+ },
472
+ "side": {
473
+ "type": "string",
474
+ "enum": ["parent", "child"],
475
+ "description": "Side of the relationship"
476
+ }
477
+ },
478
+ "required": ["key", "type"],
479
+ "additionalProperties": false,
480
+ "allOf": [
481
+ {
482
+ "if": {
483
+ "properties": { "type": { "const": "enum" } }
484
+ },
485
+ "then": {
486
+ "required": ["elements"]
487
+ }
488
+ },
489
+ {
490
+ "if": {
491
+ "properties": { "type": { "const": "relationship" } }
492
+ },
493
+ "then": {
494
+ "required": ["relatedCollection", "relationType"]
495
+ }
496
+ }
497
+ ]
498
+ }
499
+ },
500
+ "indexes": {
501
+ "type": "array",
502
+ "description": "Database indexes for the collection",
503
+ "items": {
504
+ "type": "object",
505
+ "properties": {
506
+ "key": {
507
+ "type": "string",
508
+ "description": "Index name"
509
+ },
510
+ "type": {
511
+ "type": "string",
512
+ "enum": ["key", "fulltext", "unique"],
513
+ "description": "Index type"
514
+ },
515
+ "attributes": {
516
+ "type": "array",
517
+ "items": {
518
+ "type": "string"
519
+ },
520
+ "description": "Attributes to index",
521
+ "minItems": 1
522
+ },
523
+ "orders": {
524
+ "type": "array",
525
+ "items": {
526
+ "type": "string",
527
+ "enum": ["ASC", "DESC"]
528
+ },
529
+ "description": "Sort order for each attribute"
530
+ }
531
+ },
532
+ "required": ["key", "type", "attributes"],
533
+ "additionalProperties": false
534
+ }
535
+ },
536
+ "importDefs": {
537
+ "type": "array",
538
+ "description": "Import definitions for data migration",
539
+ "default": []
540
+ }
541
+ },
542
+ "required": ["name"],
543
+ "additionalProperties": false
544
+ };
545
+
546
+ // Ensure YAML schemas directory exists before writing schema
547
+ if (!existsSync(appwriteYamlSchemaFolder)) {
548
+ mkdirSync(appwriteYamlSchemaFolder, { recursive: true });
549
+ }
550
+
551
+ const collectionSchemaPath = path.join(appwriteYamlSchemaFolder, "collection.schema.json");
552
+ writeFileSync(collectionSchemaPath, JSON.stringify(collectionJsonSchema, null, 2));
553
+
554
+ // Create JSON schema for appwriteConfig.yaml
555
+ const configJsonSchema = {
556
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
557
+ "$id": "https://appwrite-utils.dev/schemas/appwrite-config.schema.json",
558
+ "title": "Appwrite Configuration",
559
+ "description": "Schema for Appwrite project configuration in YAML",
560
+ "type": "object",
561
+ "properties": {
562
+ "appwrite": {
563
+ "type": "object",
564
+ "description": "Appwrite connection settings",
565
+ "properties": {
566
+ "endpoint": {
567
+ "type": "string",
568
+ "default": "https://cloud.appwrite.io/v1",
569
+ "description": "Appwrite server endpoint URL"
570
+ },
571
+ "project": {
572
+ "type": "string",
573
+ "description": "Appwrite project ID"
574
+ },
575
+ "key": {
576
+ "type": "string",
577
+ "description": "Appwrite API key with appropriate permissions"
578
+ }
579
+ },
580
+ "required": ["project", "key"],
581
+ "additionalProperties": false
582
+ },
583
+ "logging": {
584
+ "type": "object",
585
+ "description": "Logging configuration",
586
+ "properties": {
587
+ "enabled": {
588
+ "type": "boolean",
589
+ "default": false,
590
+ "description": "Enable file logging"
591
+ },
592
+ "level": {
593
+ "type": "string",
594
+ "enum": ["error", "warn", "info", "debug"],
595
+ "default": "info",
596
+ "description": "Logging level"
597
+ },
598
+ "directory": {
599
+ "type": "string",
600
+ "description": "Custom log directory path (optional)"
601
+ },
602
+ "console": {
603
+ "type": "boolean",
604
+ "default": false,
605
+ "description": "Enable console logging"
606
+ }
607
+ },
608
+ "additionalProperties": false
609
+ },
610
+ "backups": {
611
+ "type": "object",
612
+ "description": "Backup configuration",
613
+ "properties": {
614
+ "enabled": {
615
+ "type": "boolean",
616
+ "default": true,
617
+ "description": "Enable automatic backups"
618
+ },
619
+ "interval": {
620
+ "type": "number",
621
+ "default": 3600,
622
+ "description": "Backup interval in seconds"
623
+ },
624
+ "retention": {
625
+ "type": "number",
626
+ "default": 30,
627
+ "description": "Backup retention in days"
628
+ },
629
+ "cleanup": {
630
+ "type": "boolean",
631
+ "default": true,
632
+ "description": "Enable automatic backup cleanup"
633
+ }
634
+ },
635
+ "additionalProperties": false
636
+ },
637
+ "data": {
638
+ "type": "object",
639
+ "description": "Data management settings",
640
+ "properties": {
641
+ "enableMockData": {
642
+ "type": "boolean",
643
+ "default": false,
644
+ "description": "Enable mock data generation"
645
+ },
646
+ "documentBucketId": {
647
+ "type": "string",
648
+ "default": "documents",
649
+ "description": "Default bucket ID for document attachments"
650
+ },
651
+ "usersCollectionName": {
652
+ "type": "string",
653
+ "default": "Members",
654
+ "description": "Name of the users/members collection"
655
+ },
656
+ "importDirectory": {
657
+ "type": "string",
658
+ "default": "importData",
659
+ "description": "Directory containing import data files"
660
+ }
661
+ },
662
+ "additionalProperties": false
663
+ },
664
+ "schemas": {
665
+ "type": "object",
666
+ "description": "Schema generation settings",
667
+ "properties": {
668
+ "outputDirectory": {
669
+ "type": "string",
670
+ "default": "schemas",
671
+ "description": "Directory where generated schemas are saved"
672
+ },
673
+ "yamlSchemaDirectory": {
674
+ "type": "string",
675
+ "default": ".yaml_schemas",
676
+ "description": "Directory containing YAML validation schemas"
677
+ }
678
+ },
679
+ "additionalProperties": false
680
+ },
681
+ "migrations": {
682
+ "type": "object",
683
+ "description": "Migration settings",
684
+ "properties": {
685
+ "enabled": {
686
+ "type": "boolean",
687
+ "default": true,
688
+ "description": "Enable migration tracking database"
689
+ }
690
+ },
691
+ "additionalProperties": false
692
+ },
693
+ "databases": {
694
+ "type": "array",
695
+ "description": "Database configurations",
696
+ "items": {
697
+ "type": "object",
698
+ "properties": {
699
+ "id": {
700
+ "type": "string",
701
+ "description": "Database ID",
702
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,35}$"
703
+ },
704
+ "name": {
705
+ "type": "string",
706
+ "description": "Database display name"
707
+ },
708
+ "bucket": {
709
+ "type": "object",
710
+ "description": "Associated storage bucket",
711
+ "properties": {
712
+ "id": {
713
+ "type": "string",
714
+ "description": "Bucket ID"
715
+ },
716
+ "name": {
717
+ "type": "string",
718
+ "description": "Bucket display name"
719
+ },
720
+ "permissions": {
721
+ "type": "array",
722
+ "items": {
723
+ "type": "string"
724
+ },
725
+ "description": "Bucket permissions"
726
+ },
727
+ "fileSecurity": {
728
+ "type": "boolean",
729
+ "description": "Enable file-level security"
730
+ },
731
+ "enabled": {
732
+ "type": "boolean",
733
+ "default": true,
734
+ "description": "Enable the bucket"
735
+ },
736
+ "maximumFileSize": {
737
+ "type": "number",
738
+ "default": 30000000,
739
+ "description": "Maximum file size in bytes"
740
+ },
741
+ "allowedFileExtensions": {
742
+ "type": "array",
743
+ "items": {
744
+ "type": "string"
745
+ },
746
+ "description": "Allowed file extensions (empty = all allowed)"
747
+ },
748
+ "compression": {
749
+ "type": "string",
750
+ "enum": ["none", "gzip", "zstd"],
751
+ "default": "none",
752
+ "description": "Compression algorithm"
753
+ },
754
+ "encryption": {
755
+ "type": "boolean",
756
+ "default": false,
757
+ "description": "Enable file encryption"
758
+ },
759
+ "antivirus": {
760
+ "type": "boolean",
761
+ "default": false,
762
+ "description": "Enable antivirus scanning"
763
+ }
764
+ },
765
+ "required": ["id", "name"],
766
+ "additionalProperties": false
767
+ }
768
+ },
769
+ "required": ["id", "name"],
770
+ "additionalProperties": false
771
+ }
772
+ },
773
+ "buckets": {
774
+ "type": "array",
775
+ "description": "Global storage buckets",
776
+ "items": {
777
+ "type": "object",
778
+ "properties": {
779
+ "id": {
780
+ "type": "string",
781
+ "description": "Bucket ID"
782
+ },
783
+ "name": {
784
+ "type": "string",
785
+ "description": "Bucket display name"
786
+ },
787
+ "permissions": {
788
+ "type": "array",
789
+ "items": {
790
+ "type": "string"
791
+ },
792
+ "description": "Bucket permissions"
793
+ },
794
+ "fileSecurity": {
795
+ "type": "boolean",
796
+ "description": "Enable file-level security"
797
+ },
798
+ "enabled": {
799
+ "type": "boolean",
800
+ "default": true,
801
+ "description": "Enable the bucket"
802
+ },
803
+ "maximumFileSize": {
804
+ "type": "number",
805
+ "default": 30000000,
806
+ "description": "Maximum file size in bytes"
807
+ },
808
+ "allowedFileExtensions": {
809
+ "type": "array",
810
+ "items": {
811
+ "type": "string"
812
+ },
813
+ "description": "Allowed file extensions (empty = all allowed)"
814
+ },
815
+ "compression": {
816
+ "type": "string",
817
+ "enum": ["none", "gzip", "zstd"],
818
+ "default": "none",
819
+ "description": "Compression algorithm"
820
+ },
821
+ "encryption": {
822
+ "type": "boolean",
823
+ "default": false,
824
+ "description": "Enable file encryption"
825
+ },
826
+ "antivirus": {
827
+ "type": "boolean",
828
+ "default": false,
829
+ "description": "Enable antivirus scanning"
830
+ }
831
+ },
832
+ "required": ["id", "name"],
833
+ "additionalProperties": false
834
+ }
835
+ },
836
+ "functions": {
837
+ "type": "array",
838
+ "description": "Appwrite Functions",
839
+ "items": {
840
+ "type": "object",
841
+ "properties": {
842
+ "id": {
843
+ "type": "string",
844
+ "description": "Function ID"
845
+ },
846
+ "name": {
847
+ "type": "string",
848
+ "description": "Function name"
849
+ },
850
+ "runtime": {
851
+ "type": "string",
852
+ "description": "Runtime environment"
853
+ },
854
+ "execute": {
855
+ "type": "array",
856
+ "items": {
857
+ "type": "string"
858
+ },
859
+ "description": "Execution permissions"
860
+ },
861
+ "events": {
862
+ "type": "array",
863
+ "items": {
864
+ "type": "string"
865
+ },
866
+ "description": "Event triggers"
867
+ },
868
+ "schedule": {
869
+ "type": "string",
870
+ "description": "Cron schedule"
871
+ },
872
+ "timeout": {
873
+ "type": "number",
874
+ "default": 15,
875
+ "description": "Execution timeout in seconds"
876
+ },
877
+ "enabled": {
878
+ "type": "boolean",
879
+ "default": true,
880
+ "description": "Enable the function"
881
+ },
882
+ "logging": {
883
+ "type": "boolean",
884
+ "default": true,
885
+ "description": "Enable function logging"
886
+ },
887
+ "entrypoint": {
888
+ "type": "string",
889
+ "description": "Function entrypoint file"
890
+ },
891
+ "commands": {
892
+ "type": "string",
893
+ "description": "Build commands"
894
+ }
895
+ },
896
+ "required": ["id", "name", "runtime"],
897
+ "additionalProperties": false
898
+ }
899
+ }
900
+ },
901
+ "required": ["appwrite"],
902
+ "additionalProperties": false
903
+ };
904
+
905
+ const configSchemaPath = path.join(appwriteYamlSchemaFolder, "appwrite-config.schema.json");
906
+ writeFileSync(configSchemaPath, JSON.stringify(configJsonSchema, null, 2));
907
+ }
220
908
 
221
909
  if (!existsSync(appwriteSchemaFolder)) {
222
910
  mkdirSync(appwriteSchemaFolder, { recursive: true });
@@ -226,9 +914,23 @@ export default appwriteConfig;
226
914
  mkdirSync(appwriteDataFolder, { recursive: true });
227
915
  }
228
916
 
229
- if (!existsSync(appwriteHiddenFolder)) {
230
- mkdirSync(appwriteHiddenFolder, { recursive: true });
231
- }
917
+ // Remove the nested .appwrite folder creation since we're using .appwrite as the main folder
232
918
 
233
- console.log("Created config and setup files/directories successfully.");
919
+ const configType = useYaml ? "YAML" : "TypeScript";
920
+ console.log(`✨ Created ${configType} config and setup files/directories in .appwrite/ folder.`);
921
+
922
+ if (useYaml) {
923
+ console.log("🔧 You can now configure your project in .appwrite/config.yaml");
924
+ console.log("📁 Collections can be defined in .appwrite/collections/ as .ts or .yaml files");
925
+ console.log("📊 Schemas will be generated in .appwrite/schemas/");
926
+ console.log("📦 Import data can be placed in .appwrite/importData/");
927
+ } else {
928
+ console.log("🔧 You can now configure logging in your .appwrite/appwriteConfig.ts file:");
929
+ console.log(" logging: {");
930
+ console.log(" enabled: true,");
931
+ console.log(" level: 'info',");
932
+ console.log(" console: true,");
933
+ console.log(" logDirectory: './logs' // optional custom directory");
934
+ console.log(" }");
935
+ }
234
936
  };