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