appwrite-utils-cli 1.5.1 → 1.6.0

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 (233) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +251 -29
  3. package/dist/adapters/AdapterFactory.d.ts +10 -3
  4. package/dist/adapters/AdapterFactory.js +213 -17
  5. package/dist/adapters/TablesDBAdapter.js +60 -17
  6. package/dist/backups/operations/bucketBackup.d.ts +19 -0
  7. package/dist/backups/operations/bucketBackup.js +197 -0
  8. package/dist/backups/operations/collectionBackup.d.ts +30 -0
  9. package/dist/backups/operations/collectionBackup.js +201 -0
  10. package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
  11. package/dist/backups/operations/comprehensiveBackup.js +238 -0
  12. package/dist/backups/schemas/bucketManifest.d.ts +93 -0
  13. package/dist/backups/schemas/bucketManifest.js +33 -0
  14. package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
  15. package/dist/backups/schemas/comprehensiveManifest.js +32 -0
  16. package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
  17. package/dist/backups/tracking/centralizedTracking.js +274 -0
  18. package/dist/cli/commands/configCommands.d.ts +8 -0
  19. package/dist/cli/commands/configCommands.js +160 -0
  20. package/dist/cli/commands/databaseCommands.d.ts +13 -0
  21. package/dist/cli/commands/databaseCommands.js +478 -0
  22. package/dist/cli/commands/functionCommands.d.ts +7 -0
  23. package/dist/cli/commands/functionCommands.js +289 -0
  24. package/dist/cli/commands/schemaCommands.d.ts +7 -0
  25. package/dist/cli/commands/schemaCommands.js +134 -0
  26. package/dist/cli/commands/transferCommands.d.ts +5 -0
  27. package/dist/cli/commands/transferCommands.js +384 -0
  28. package/dist/collections/attributes.d.ts +5 -4
  29. package/dist/collections/attributes.js +539 -246
  30. package/dist/collections/indexes.js +39 -37
  31. package/dist/collections/methods.d.ts +2 -16
  32. package/dist/collections/methods.js +90 -538
  33. package/dist/collections/transferOperations.d.ts +7 -0
  34. package/dist/collections/transferOperations.js +331 -0
  35. package/dist/collections/wipeOperations.d.ts +16 -0
  36. package/dist/collections/wipeOperations.js +328 -0
  37. package/dist/config/configMigration.d.ts +87 -0
  38. package/dist/config/configMigration.js +390 -0
  39. package/dist/config/configValidation.d.ts +66 -0
  40. package/dist/config/configValidation.js +358 -0
  41. package/dist/config/yamlConfig.d.ts +455 -1
  42. package/dist/config/yamlConfig.js +145 -52
  43. package/dist/databases/methods.js +3 -2
  44. package/dist/databases/setup.d.ts +1 -2
  45. package/dist/databases/setup.js +9 -87
  46. package/dist/examples/yamlTerminologyExample.d.ts +42 -0
  47. package/dist/examples/yamlTerminologyExample.js +269 -0
  48. package/dist/functions/deployments.js +11 -10
  49. package/dist/functions/methods.d.ts +1 -1
  50. package/dist/functions/methods.js +5 -4
  51. package/dist/init.js +9 -9
  52. package/dist/interactiveCLI.d.ts +8 -17
  53. package/dist/interactiveCLI.js +186 -1171
  54. package/dist/main.js +364 -21
  55. package/dist/migrations/afterImportActions.js +22 -30
  56. package/dist/migrations/appwriteToX.js +71 -25
  57. package/dist/migrations/dataLoader.js +35 -26
  58. package/dist/migrations/importController.js +29 -30
  59. package/dist/migrations/relationships.js +13 -12
  60. package/dist/migrations/services/ImportOrchestrator.js +16 -19
  61. package/dist/migrations/transfer.js +46 -46
  62. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +3 -1
  63. package/dist/migrations/yaml/YamlImportConfigLoader.js +6 -3
  64. package/dist/migrations/yaml/YamlImportIntegration.d.ts +9 -3
  65. package/dist/migrations/yaml/YamlImportIntegration.js +22 -11
  66. package/dist/migrations/yaml/generateImportSchemas.d.ts +14 -1
  67. package/dist/migrations/yaml/generateImportSchemas.js +736 -7
  68. package/dist/schemas/authUser.d.ts +1 -1
  69. package/dist/setupController.js +3 -2
  70. package/dist/shared/backupMetadataSchema.d.ts +94 -0
  71. package/dist/shared/backupMetadataSchema.js +38 -0
  72. package/dist/shared/backupTracking.d.ts +18 -0
  73. package/dist/shared/backupTracking.js +176 -0
  74. package/dist/shared/confirmationDialogs.js +15 -15
  75. package/dist/shared/errorUtils.d.ts +54 -0
  76. package/dist/shared/errorUtils.js +95 -0
  77. package/dist/shared/functionManager.js +20 -19
  78. package/dist/shared/indexManager.js +12 -11
  79. package/dist/shared/jsonSchemaGenerator.js +10 -26
  80. package/dist/shared/logging.d.ts +51 -0
  81. package/dist/shared/logging.js +70 -0
  82. package/dist/shared/messageFormatter.d.ts +2 -0
  83. package/dist/shared/messageFormatter.js +10 -0
  84. package/dist/shared/migrationHelpers.d.ts +6 -16
  85. package/dist/shared/migrationHelpers.js +24 -21
  86. package/dist/shared/operationLogger.d.ts +8 -1
  87. package/dist/shared/operationLogger.js +11 -24
  88. package/dist/shared/operationQueue.d.ts +28 -1
  89. package/dist/shared/operationQueue.js +268 -66
  90. package/dist/shared/operationsTable.d.ts +26 -0
  91. package/dist/shared/operationsTable.js +286 -0
  92. package/dist/shared/operationsTableSchema.d.ts +48 -0
  93. package/dist/shared/operationsTableSchema.js +35 -0
  94. package/dist/shared/relationshipExtractor.d.ts +56 -0
  95. package/dist/shared/relationshipExtractor.js +138 -0
  96. package/dist/shared/schemaGenerator.d.ts +19 -1
  97. package/dist/shared/schemaGenerator.js +56 -75
  98. package/dist/storage/backupCompression.d.ts +20 -0
  99. package/dist/storage/backupCompression.js +67 -0
  100. package/dist/storage/methods.d.ts +16 -2
  101. package/dist/storage/methods.js +98 -14
  102. package/dist/users/methods.js +9 -8
  103. package/dist/utils/configDiscovery.d.ts +78 -0
  104. package/dist/utils/configDiscovery.js +430 -0
  105. package/dist/utils/directoryUtils.d.ts +22 -0
  106. package/dist/utils/directoryUtils.js +59 -0
  107. package/dist/utils/getClientFromConfig.d.ts +17 -8
  108. package/dist/utils/getClientFromConfig.js +162 -17
  109. package/dist/utils/helperFunctions.d.ts +16 -2
  110. package/dist/utils/helperFunctions.js +19 -5
  111. package/dist/utils/loadConfigs.d.ts +34 -9
  112. package/dist/utils/loadConfigs.js +236 -316
  113. package/dist/utils/pathResolvers.d.ts +53 -0
  114. package/dist/utils/pathResolvers.js +72 -0
  115. package/dist/utils/projectConfig.d.ts +119 -0
  116. package/dist/utils/projectConfig.js +171 -0
  117. package/dist/utils/retryFailedPromises.js +4 -2
  118. package/dist/utils/sessionAuth.d.ts +48 -0
  119. package/dist/utils/sessionAuth.js +164 -0
  120. package/dist/utils/sessionPreservationExample.d.ts +1666 -0
  121. package/dist/utils/sessionPreservationExample.js +101 -0
  122. package/dist/utils/setupFiles.js +301 -41
  123. package/dist/utils/typeGuards.d.ts +35 -0
  124. package/dist/utils/typeGuards.js +57 -0
  125. package/dist/utils/versionDetection.js +145 -9
  126. package/dist/utils/yamlConverter.d.ts +53 -3
  127. package/dist/utils/yamlConverter.js +232 -13
  128. package/dist/utils/yamlLoader.d.ts +70 -0
  129. package/dist/utils/yamlLoader.js +263 -0
  130. package/dist/utilsController.d.ts +36 -3
  131. package/dist/utilsController.js +186 -56
  132. package/package.json +12 -2
  133. package/src/adapters/AdapterFactory.ts +263 -35
  134. package/src/adapters/TablesDBAdapter.ts +225 -36
  135. package/src/backups/operations/bucketBackup.ts +277 -0
  136. package/src/backups/operations/collectionBackup.ts +310 -0
  137. package/src/backups/operations/comprehensiveBackup.ts +342 -0
  138. package/src/backups/schemas/bucketManifest.ts +78 -0
  139. package/src/backups/schemas/comprehensiveManifest.ts +76 -0
  140. package/src/backups/tracking/centralizedTracking.ts +352 -0
  141. package/src/cli/commands/configCommands.ts +194 -0
  142. package/src/cli/commands/databaseCommands.ts +635 -0
  143. package/src/cli/commands/functionCommands.ts +379 -0
  144. package/src/cli/commands/schemaCommands.ts +163 -0
  145. package/src/cli/commands/transferCommands.ts +457 -0
  146. package/src/collections/attributes.ts +900 -621
  147. package/src/collections/attributes.ts.backup +1555 -0
  148. package/src/collections/indexes.ts +116 -114
  149. package/src/collections/methods.ts +295 -968
  150. package/src/collections/transferOperations.ts +516 -0
  151. package/src/collections/wipeOperations.ts +501 -0
  152. package/src/config/README.md +274 -0
  153. package/src/config/configMigration.ts +575 -0
  154. package/src/config/configValidation.ts +445 -0
  155. package/src/config/yamlConfig.ts +168 -55
  156. package/src/databases/methods.ts +3 -2
  157. package/src/databases/setup.ts +11 -138
  158. package/src/examples/yamlTerminologyExample.ts +341 -0
  159. package/src/functions/deployments.ts +14 -12
  160. package/src/functions/methods.ts +11 -11
  161. package/src/functions/templates/hono-typescript/README.md +286 -0
  162. package/src/functions/templates/hono-typescript/package.json +26 -0
  163. package/src/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  164. package/src/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  165. package/src/functions/templates/hono-typescript/src/app.ts +180 -0
  166. package/src/functions/templates/hono-typescript/src/context.ts +103 -0
  167. package/src/functions/templates/hono-typescript/src/index.ts +54 -0
  168. package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  169. package/src/functions/templates/hono-typescript/tsconfig.json +20 -0
  170. package/src/functions/templates/typescript-node/package.json +2 -1
  171. package/src/functions/templates/typescript-node/src/context.ts +103 -0
  172. package/src/functions/templates/typescript-node/src/index.ts +18 -12
  173. package/src/functions/templates/uv/pyproject.toml +1 -0
  174. package/src/functions/templates/uv/src/context.py +125 -0
  175. package/src/functions/templates/uv/src/index.py +35 -5
  176. package/src/init.ts +9 -11
  177. package/src/interactiveCLI.ts +276 -1591
  178. package/src/main.ts +418 -24
  179. package/src/migrations/afterImportActions.ts +71 -44
  180. package/src/migrations/appwriteToX.ts +100 -34
  181. package/src/migrations/dataLoader.ts +48 -34
  182. package/src/migrations/importController.ts +44 -39
  183. package/src/migrations/relationships.ts +28 -18
  184. package/src/migrations/services/ImportOrchestrator.ts +24 -27
  185. package/src/migrations/transfer.ts +159 -121
  186. package/src/migrations/yaml/YamlImportConfigLoader.ts +11 -4
  187. package/src/migrations/yaml/YamlImportIntegration.ts +47 -20
  188. package/src/migrations/yaml/generateImportSchemas.ts +751 -12
  189. package/src/setupController.ts +3 -2
  190. package/src/shared/backupMetadataSchema.ts +93 -0
  191. package/src/shared/backupTracking.ts +211 -0
  192. package/src/shared/confirmationDialogs.ts +19 -19
  193. package/src/shared/errorUtils.ts +110 -0
  194. package/src/shared/functionManager.ts +21 -20
  195. package/src/shared/indexManager.ts +12 -11
  196. package/src/shared/jsonSchemaGenerator.ts +38 -52
  197. package/src/shared/logging.ts +75 -0
  198. package/src/shared/messageFormatter.ts +14 -1
  199. package/src/shared/migrationHelpers.ts +45 -38
  200. package/src/shared/operationLogger.ts +11 -36
  201. package/src/shared/operationQueue.ts +322 -93
  202. package/src/shared/operationsTable.ts +338 -0
  203. package/src/shared/operationsTableSchema.ts +60 -0
  204. package/src/shared/relationshipExtractor.ts +214 -0
  205. package/src/shared/schemaGenerator.ts +179 -219
  206. package/src/storage/backupCompression.ts +88 -0
  207. package/src/storage/methods.ts +131 -34
  208. package/src/users/methods.ts +11 -9
  209. package/src/utils/configDiscovery.ts +502 -0
  210. package/src/utils/directoryUtils.ts +61 -0
  211. package/src/utils/getClientFromConfig.ts +205 -22
  212. package/src/utils/helperFunctions.ts +23 -5
  213. package/src/utils/loadConfigs.ts +313 -345
  214. package/src/utils/pathResolvers.ts +81 -0
  215. package/src/utils/projectConfig.ts +299 -0
  216. package/src/utils/retryFailedPromises.ts +4 -2
  217. package/src/utils/sessionAuth.ts +230 -0
  218. package/src/utils/setupFiles.ts +322 -54
  219. package/src/utils/typeGuards.ts +65 -0
  220. package/src/utils/versionDetection.ts +218 -64
  221. package/src/utils/yamlConverter.ts +296 -13
  222. package/src/utils/yamlLoader.ts +364 -0
  223. package/src/utilsController.ts +314 -110
  224. package/tests/README.md +497 -0
  225. package/tests/adapters/AdapterFactory.test.ts +277 -0
  226. package/tests/integration/syncOperations.test.ts +463 -0
  227. package/tests/jest.config.js +25 -0
  228. package/tests/migration/configMigration.test.ts +546 -0
  229. package/tests/setup.ts +62 -0
  230. package/tests/testUtils.ts +340 -0
  231. package/tests/utils/loadConfigs.test.ts +350 -0
  232. package/tests/validation/configValidation.test.ts +412 -0
  233. package/src/utils/schemaStrings.ts +0 -517
@@ -3,11 +3,20 @@ import yaml from "js-yaml";
3
3
  import fs from "fs";
4
4
  import path from "path";
5
5
  import { AppwriteConfigSchema, RuntimeSchema, FunctionScopes, FunctionSpecifications, permissionsSchema, PermissionToAppwritePermission } from "appwrite-utils";
6
+ import { shouldIgnoreDirectory } from "../utils/directoryUtils.js";
7
+ import { MessageFormatter } from "../shared/messageFormatter.js";
6
8
  const YamlConfigSchema = z.object({
7
9
  appwrite: z.object({
8
10
  endpoint: z.string().default("https://cloud.appwrite.io/v1"),
9
11
  project: z.string(),
10
12
  key: z.string(),
13
+ // Session authentication support
14
+ sessionCookie: z.string().optional(),
15
+ authMethod: z.enum(["session", "apikey", "auto"]).optional().default("auto"),
16
+ sessionMetadata: z.object({
17
+ email: z.string().optional(),
18
+ expiresAt: z.string().optional(),
19
+ }).optional(),
11
20
  }),
12
21
  logging: z
13
22
  .object({
@@ -46,12 +55,14 @@ const YamlConfigSchema = z.object({
46
55
  outputDirectory: z.string().default("schemas"),
47
56
  yamlSchemaDirectory: z.string().default(".yaml_schemas"),
48
57
  collectionsDirectory: z.string().default("collections"),
58
+ tablesDirectory: z.string().default("tables"),
49
59
  })
50
60
  .optional()
51
61
  .default({
52
62
  outputDirectory: "schemas",
53
63
  yamlSchemaDirectory: ".yaml_schemas",
54
64
  collectionsDirectory: "collections",
65
+ tablesDirectory: "tables",
55
66
  }),
56
67
  migrations: z
57
68
  .object({
@@ -140,6 +151,10 @@ export const convertYamlToAppwriteConfig = (yamlConfig) => {
140
151
  appwriteEndpoint: yamlConfig.appwrite.endpoint,
141
152
  appwriteProject: yamlConfig.appwrite.project,
142
153
  appwriteKey: yamlConfig.appwrite.key,
154
+ // Session authentication support from YAML
155
+ sessionCookie: yamlConfig.appwrite.sessionCookie,
156
+ authMethod: yamlConfig.appwrite.authMethod || "auto",
157
+ sessionMetadata: yamlConfig.appwrite.sessionMetadata,
143
158
  apiMode: "auto", // Default to auto-detect for dual API support
144
159
  appwriteClient: null,
145
160
  logging: {
@@ -155,12 +170,12 @@ export const convertYamlToAppwriteConfig = (yamlConfig) => {
155
170
  enableMockData: yamlConfig.data.enableMockData,
156
171
  documentBucketId: yamlConfig.data.documentBucketId,
157
172
  usersCollectionName: yamlConfig.data.usersCollectionName,
158
- useMigrations: yamlConfig.migrations.enabled,
159
173
  schemaConfig: {
160
174
  outputDirectory: yamlConfig.schemas.outputDirectory,
161
175
  yamlSchemaDirectory: yamlConfig.schemas.yamlSchemaDirectory,
162
176
  importDirectory: yamlConfig.data.importDirectory,
163
177
  collectionsDirectory: yamlConfig.schemas.collectionsDirectory || "collections",
178
+ tablesDirectory: yamlConfig.schemas.tablesDirectory || "tables",
164
179
  },
165
180
  databases: yamlConfig.databases.map((db) => ({
166
181
  $id: db.id,
@@ -226,6 +241,46 @@ export const convertYamlToAppwriteConfig = (yamlConfig) => {
226
241
  };
227
242
  return appwriteConfig;
228
243
  };
244
+ /**
245
+ * Load YAML config with optional session preservation
246
+ * Maintains authentication priority: explicit session > YAML file > system prefs
247
+ */
248
+ export const loadYamlConfigWithSession = async (configPath, sessionOptions) => {
249
+ try {
250
+ const fileContent = fs.readFileSync(configPath, "utf8");
251
+ const yamlData = yaml.load(fileContent);
252
+ const yamlConfig = YamlConfigSchema.parse(yamlData);
253
+ const appwriteConfig = convertYamlToAppwriteConfig(yamlConfig);
254
+ // Apply session preservation if provided (explicit overrides take priority)
255
+ if (sessionOptions) {
256
+ if (sessionOptions.sessionCookie) {
257
+ appwriteConfig.sessionCookie = sessionOptions.sessionCookie;
258
+ }
259
+ if (sessionOptions.authMethod) {
260
+ appwriteConfig.authMethod = sessionOptions.authMethod;
261
+ }
262
+ if (sessionOptions.sessionMetadata) {
263
+ appwriteConfig.sessionMetadata = sessionOptions.sessionMetadata;
264
+ }
265
+ }
266
+ return appwriteConfig;
267
+ }
268
+ catch (error) {
269
+ if (error instanceof z.ZodError) {
270
+ MessageFormatter.error("YAML config validation failed", undefined, { prefix: "Config" });
271
+ error.issues.forEach((err) => {
272
+ MessageFormatter.error(`${err.path.join('.')} → ${err.message}`, undefined, { prefix: "Config" });
273
+ });
274
+ }
275
+ else {
276
+ MessageFormatter.error("Error loading YAML config", error instanceof Error ? error : undefined, { prefix: "Config" });
277
+ if (error instanceof Error && error.stack) {
278
+ MessageFormatter.debug("Stack trace", error.stack, { prefix: "Config" });
279
+ }
280
+ }
281
+ return null;
282
+ }
283
+ };
229
284
  export const loadYamlConfig = async (configPath) => {
230
285
  try {
231
286
  const fileContent = fs.readFileSync(configPath, "utf8");
@@ -235,15 +290,15 @@ export const loadYamlConfig = async (configPath) => {
235
290
  }
236
291
  catch (error) {
237
292
  if (error instanceof z.ZodError) {
238
- console.error("YAML config validation failed:");
293
+ MessageFormatter.error("YAML config validation failed", undefined, { prefix: "Config" });
239
294
  error.issues.forEach((err) => {
240
- console.error(` ${err.path.join('.')} → ${err.message}`);
295
+ MessageFormatter.error(`${err.path.join('.')} → ${err.message}`, undefined, { prefix: "Config" });
241
296
  });
242
297
  }
243
298
  else {
244
- console.error("Error loading YAML config:", error instanceof Error ? error.message : error);
299
+ MessageFormatter.error("Error loading YAML config", error instanceof Error ? error : undefined, { prefix: "Config" });
245
300
  if (error instanceof Error && error.stack) {
246
- console.error("Stack trace:", error.stack);
301
+ MessageFormatter.debug("Stack trace", error.stack, { prefix: "Config" });
247
302
  }
248
303
  }
249
304
  return null;
@@ -288,45 +343,6 @@ export const findYamlConfig = (startDir) => {
288
343
  }
289
344
  return null;
290
345
  };
291
- const shouldIgnoreDirectory = (dirName) => {
292
- const ignoredDirs = [
293
- 'node_modules',
294
- 'dist',
295
- 'build',
296
- 'coverage',
297
- '.next',
298
- '.nuxt',
299
- '.cache',
300
- '.git',
301
- '.svn',
302
- '.hg',
303
- '__pycache__',
304
- '.pytest_cache',
305
- '.mypy_cache',
306
- 'venv',
307
- '.venv',
308
- 'env',
309
- '.env',
310
- 'target',
311
- 'out',
312
- 'bin',
313
- 'obj',
314
- '.vs',
315
- '.vscode',
316
- '.idea',
317
- 'temp',
318
- 'tmp',
319
- '.tmp',
320
- 'logs',
321
- 'log',
322
- '.DS_Store',
323
- 'Thumbs.db'
324
- ];
325
- return ignoredDirs.includes(dirName) ||
326
- dirName.startsWith('.git') ||
327
- dirName.startsWith('node_modules') ||
328
- (dirName.startsWith('.') && dirName !== '.appwrite');
329
- };
330
346
  const findYamlConfigRecursive = (dir, depth = 0) => {
331
347
  // Limit search depth to prevent infinite recursion
332
348
  if (depth > 5) {
@@ -372,6 +388,9 @@ export const generateYamlConfigTemplate = (outputPath) => {
372
388
  endpoint: "https://cloud.appwrite.io/v1",
373
389
  project: "YOUR_PROJECT_ID",
374
390
  key: "YOUR_API_KEY",
391
+ authMethod: "auto",
392
+ // Optional session authentication (leave empty to use API key)
393
+ // sessionCookie: "session_cookie_from_appwrite_cli",
375
394
  },
376
395
  logging: {
377
396
  enabled: false,
@@ -394,6 +413,7 @@ export const generateYamlConfigTemplate = (outputPath) => {
394
413
  outputDirectory: "schemas",
395
414
  yamlSchemaDirectory: ".yaml_schemas",
396
415
  collectionsDirectory: "collections",
416
+ tablesDirectory: "tables",
397
417
  },
398
418
  migrations: {
399
419
  enabled: true,
@@ -406,14 +426,38 @@ export const generateYamlConfigTemplate = (outputPath) => {
406
426
  buckets: [],
407
427
  functions: [],
408
428
  };
409
- const yamlContent = yaml.dump(template, {
429
+ let yamlContent = yaml.dump(template, {
410
430
  indent: 2,
411
431
  lineWidth: 120,
412
432
  sortKeys: false,
413
433
  });
414
- // Add schema reference header
434
+ // Add inline comments to the schemas section
435
+ yamlContent = yamlContent.replace(/schemas:\s*\n(\s*)outputDirectory: schemas\n(\s*)yamlSchemaDirectory: \.yaml_schemas\n(\s*)collectionsDirectory: collections\n(\s*)tablesDirectory: tables/, `schemas:
436
+ $1outputDirectory: schemas
437
+ $2yamlSchemaDirectory: .yaml_schemas
438
+ $3# Directory for legacy Databases API collection definitions
439
+ $3collectionsDirectory: collections
440
+ $4# Directory for new TablesDB API table definitions
441
+ $4tablesDirectory: tables`);
442
+ // Add schema reference header and documentation
415
443
  const schemaReference = "# yaml-language-server: $schema=./.yaml_schemas/appwrite-config.schema.json\n";
416
- const finalContent = schemaReference + "# Appwrite Project Configuration\n" + yamlContent;
444
+ const documentation = `# Appwrite Project Configuration
445
+ #
446
+ # Authentication Configuration:
447
+ # - key: Standard API key authentication
448
+ # - sessionCookie: Session cookie from Appwrite CLI authentication
449
+ # - authMethod: "auto" (detects available method), "session" (prefer session), "apikey" (prefer API key)
450
+ # - Priority: Explicit CLI args > YAML config > ~/.appwrite/prefs.json > Error
451
+ #
452
+ # Directory Configuration:
453
+ # - collectionsDirectory: Use for legacy Databases API (default: "collections")
454
+ # - tablesDirectory: Use for new TablesDB API (default: "tables")
455
+ # - API mode is auto-detected based on server version, or set explicitly via apiMode
456
+ #
457
+ # For dual API support, both directories can coexist with different definitions
458
+
459
+ `;
460
+ const finalContent = schemaReference + documentation + yamlContent;
417
461
  fs.writeFileSync(outputPath, finalContent, "utf8");
418
462
  };
419
463
  /**
@@ -429,6 +473,10 @@ export const writeYamlConfig = async (configPath, config) => {
429
473
  endpoint: config.appwriteEndpoint,
430
474
  project: config.appwriteProject,
431
475
  key: config.appwriteKey,
476
+ // Include session authentication fields
477
+ sessionCookie: config.sessionCookie,
478
+ authMethod: config.authMethod || "auto",
479
+ sessionMetadata: config.sessionMetadata,
432
480
  },
433
481
  logging: {
434
482
  enabled: config.logging?.enabled || false,
@@ -452,9 +500,10 @@ export const writeYamlConfig = async (configPath, config) => {
452
500
  outputDirectory: config.schemaConfig?.outputDirectory || "schemas",
453
501
  yamlSchemaDirectory: config.schemaConfig?.yamlSchemaDirectory || ".yaml_schemas",
454
502
  collectionsDirectory: config.schemaConfig?.collectionsDirectory || "collections",
503
+ tablesDirectory: config.schemaConfig?.tablesDirectory || "tables",
455
504
  },
456
505
  migrations: {
457
- enabled: config.useMigrations !== false,
506
+ enabled: true,
458
507
  },
459
508
  databases: config.databases?.map(db => ({
460
509
  id: db.$id,
@@ -541,10 +590,10 @@ export const writeYamlConfig = async (configPath, config) => {
541
590
  finalContent = schemaReference + "# Appwrite Project Configuration\n" + yamlContent;
542
591
  }
543
592
  fs.writeFileSync(configPath, finalContent, "utf8");
544
- console.log(`✅ Updated YAML configuration at ${configPath}`);
593
+ MessageFormatter.success(`Updated YAML configuration at ${configPath}`, { prefix: "Config" });
545
594
  }
546
595
  catch (error) {
547
- console.error("Error writing YAML config:", error instanceof Error ? error.message : error);
596
+ MessageFormatter.error("Error writing YAML config", error instanceof Error ? error : undefined, { prefix: "Config" });
548
597
  throw error;
549
598
  }
550
599
  };
@@ -600,10 +649,54 @@ export const addFunctionToYamlConfig = async (configPath, newFunction) => {
600
649
  finalContent = schemaLine + '\n' + updatedYamlContent;
601
650
  }
602
651
  fs.writeFileSync(configPath, finalContent, "utf8");
603
- console.log(`✅ Added function "${newFunction.name}" to YAML config`);
652
+ MessageFormatter.success(`Added function "${newFunction.name}" to YAML config`, { prefix: "Config" });
604
653
  }
605
654
  catch (error) {
606
- console.error("Error adding function to YAML config:", error instanceof Error ? error.message : error);
655
+ MessageFormatter.error("Error adding function to YAML config", error instanceof Error ? error : undefined, { prefix: "Config" });
607
656
  throw error;
608
657
  }
609
658
  };
659
+ /**
660
+ * Extract session options from AppwriteConfig for YAML operations
661
+ * Useful for preserving session state during config reloads
662
+ */
663
+ export const extractSessionOptionsFromConfig = (config) => {
664
+ return {
665
+ sessionCookie: config.sessionCookie,
666
+ authMethod: config.authMethod,
667
+ sessionMetadata: config.sessionMetadata,
668
+ };
669
+ };
670
+ /**
671
+ * Create session-preserved YAML config operations
672
+ * Maintains authentication state during config file updates
673
+ */
674
+ export const createSessionPreservingYamlConfig = (configPath, sessionOptions) => {
675
+ return {
676
+ load: () => loadYamlConfigWithSession(configPath, sessionOptions),
677
+ write: (config) => {
678
+ // Merge session options into config before writing
679
+ const enhancedConfig = {
680
+ ...config,
681
+ sessionCookie: sessionOptions.sessionCookie || config.sessionCookie,
682
+ authMethod: sessionOptions.authMethod || config.authMethod,
683
+ sessionMetadata: sessionOptions.sessionMetadata || config.sessionMetadata,
684
+ };
685
+ return writeYamlConfig(configPath, enhancedConfig);
686
+ },
687
+ addFunction: (func) => addFunctionToYamlConfig(configPath, func),
688
+ };
689
+ };
690
+ /**
691
+ * Determine if YAML config has session authentication configured
692
+ */
693
+ export const hasYamlSessionAuth = (configPath) => {
694
+ try {
695
+ const fileContent = fs.readFileSync(configPath, "utf8");
696
+ const yamlData = yaml.load(fileContent);
697
+ return !!(yamlData?.appwrite?.sessionCookie && yamlData.appwrite.sessionCookie.trim());
698
+ }
699
+ catch (error) {
700
+ return false;
701
+ }
702
+ };
@@ -1,6 +1,7 @@
1
1
  import { Databases, Query } from "node-appwrite";
2
2
  import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
3
3
  import { fetchAllCollections } from "../collections/methods.js";
4
+ import { MessageFormatter } from "../shared/messageFormatter.js";
4
5
  export const fetchAllDatabases = async (database) => {
5
6
  const databases = await tryAwaitWithRetry(async () => await database.list([Query.limit(25)]));
6
7
  const allDatabases = databases.databases;
@@ -21,11 +22,11 @@ export const fetchAllDatabases = async (database) => {
21
22
  return allDatabases;
22
23
  };
23
24
  export const wipeDatabase = async (database, databaseId) => {
24
- console.log(`Wiping database: ${databaseId}`);
25
+ MessageFormatter.info(`Wiping database: ${databaseId}`, { prefix: "Database" });
25
26
  const existingCollections = await fetchAllCollections(databaseId, database);
26
27
  let collectionsDeleted = [];
27
28
  for (const { $id: collectionId, name } of existingCollections) {
28
- console.log(`Deleting collection: ${collectionId}`);
29
+ MessageFormatter.info(`Deleting collection: ${collectionId}`, { prefix: "Database" });
29
30
  collectionsDeleted.push({ collectionId, collectionName: name });
30
31
  await tryAwaitWithRetry(async () => await database.deleteCollection(databaseId, collectionId));
31
32
  await delay(100);
@@ -1,6 +1,5 @@
1
1
  import { Databases, type Models } from "node-appwrite";
2
2
  import { type AppwriteConfig } from "appwrite-utils";
3
- export declare const setupMigrationDatabase: (config: AppwriteConfig) => Promise<void>;
4
3
  export declare const ensureDatabasesExist: (config: AppwriteConfig, databasesToEnsure?: Models.Database[]) => Promise<void>;
5
- export declare const wipeOtherDatabases: (database: Databases, databasesToKeep: Models.Database[], useMigrations?: boolean) => Promise<void>;
4
+ export declare const wipeOtherDatabases: (database: Databases, databasesToKeep: Models.Database[]) => Promise<void>;
6
5
  export declare const ensureCollectionsExist: (config: AppwriteConfig, database: Models.Database, collectionsToEnsure?: Models.Collection[]) => Promise<void>;
@@ -1,111 +1,33 @@
1
1
  import { Databases, Query } from "node-appwrite";
2
- import { createOrUpdateAttributeWithStatusCheck } from "../collections/attributes.js";
3
- import { getMigrationCollectionSchemas } from "../storage/schemas.js";
4
- import { areCollectionNamesSame, delay, toCamelCase, tryAwaitWithRetry, } from "../utils/index.js";
2
+ import { tryAwaitWithRetry } from "../utils/index.js";
5
3
  import {} from "appwrite-utils";
6
4
  import { ulid } from "ulidx";
7
- export const setupMigrationDatabase = async (config) => {
8
- if (!config.useMigrations) {
9
- console.log("Migrations database disabled, skipping setup");
10
- return;
11
- }
12
- console.log("---------------------------------");
13
- console.log("Starting Migrations Setup");
14
- console.log("---------------------------------");
15
- const database = new Databases(config.appwriteClient);
16
- if (!config.appwriteClient) {
17
- throw new Error("Appwrite client is not initialized in the config");
18
- }
19
- let db;
20
- const migrationCollectionsSetup = getMigrationCollectionSchemas();
21
- try {
22
- db = await tryAwaitWithRetry(async () => await database.get("migrations"), undefined, true);
23
- console.log("Migrations database found");
24
- }
25
- catch (e) {
26
- db = await tryAwaitWithRetry(async () => await database.create("migrations", "Migrations", true));
27
- console.log("Migrations database created");
28
- }
29
- if (!db) {
30
- console.error("Failed to create or retrieve the migrations database");
31
- return;
32
- }
33
- for (const [collectionName, { collection, attributes }] of Object.entries(migrationCollectionsSetup)) {
34
- const collectionId = toCamelCase(collectionName);
35
- let collectionFound;
36
- try {
37
- collectionFound = await tryAwaitWithRetry(async () => await database.getCollection(db.$id, collectionId), undefined, true);
38
- console.log(`Collection found: ${collectionId}`);
39
- }
40
- catch (e) {
41
- console.log(`Collection not found: ${collectionId}`);
42
- try {
43
- collectionFound = await tryAwaitWithRetry(async () => await database.createCollection(db.$id, collectionId, collectionName, undefined, collection.documentSecurity, collection.enabled), undefined, true);
44
- console.log(`Collection created: ${collectionId}`);
45
- }
46
- catch (createError) {
47
- console.error(`Failed to create collection: ${collectionId}`, createError);
48
- continue;
49
- }
50
- }
51
- if (!collectionFound) {
52
- console.error(`Failed to create or retrieve collection: ${collectionId}`);
53
- continue;
54
- }
55
- for (const attribute of attributes) {
56
- try {
57
- await createOrUpdateAttributeWithStatusCheck(database, db.$id, collectionFound, attribute);
58
- await delay(100);
59
- console.log(`Attribute created/updated: ${attribute.key}`);
60
- }
61
- catch (attrError) {
62
- console.error(`Failed to create/update attribute: ${attribute.key}`, attrError);
63
- }
64
- }
65
- }
66
- console.log("---------------------------------");
67
- console.log("Migrations Setup Complete");
68
- console.log("---------------------------------");
69
- };
5
+ import { MessageFormatter } from "../shared/messageFormatter.js";
70
6
  export const ensureDatabasesExist = async (config, databasesToEnsure) => {
71
7
  if (!config.appwriteClient) {
72
8
  throw new Error("Appwrite client is not initialized in the config");
73
9
  }
74
10
  const database = new Databases(config.appwriteClient);
75
- // Work on a shallow copy so we don't mutate caller-provided arrays
76
- const databasesToCreate = [...(databasesToEnsure || config.databases || [])];
11
+ const databasesToCreate = databasesToEnsure || config.databases || [];
77
12
  if (!databasesToCreate.length) {
78
- console.log("No databases to create");
13
+ MessageFormatter.info("No databases to create");
79
14
  return;
80
15
  }
81
16
  const existingDatabases = await tryAwaitWithRetry(async () => await database.list([Query.limit(500)]));
82
- const migrationsDatabase = existingDatabases.databases.find((d) => d.name.toLowerCase().trim().replace(" ", "") === "migrations");
83
- if (config.useMigrations && existingDatabases.databases.length !== 0 && migrationsDatabase) {
84
- console.log("Creating all databases including migrations");
85
- // Ensure migrations exists, but do not mutate the caller's array
86
- if (!databasesToCreate.some((d) => d.$id === migrationsDatabase.$id)) {
87
- databasesToCreate.push(migrationsDatabase);
88
- }
89
- }
90
17
  for (const db of databasesToCreate) {
91
18
  if (!existingDatabases.databases.some((d) => d.name === db.name)) {
92
19
  await tryAwaitWithRetry(async () => await database.create(db.$id || ulid(), db.name, true));
93
- console.log(`${db.name} database created`);
20
+ MessageFormatter.success(`${db.name} database created`);
94
21
  }
95
22
  }
96
23
  };
97
- export const wipeOtherDatabases = async (database, databasesToKeep, useMigrations = true) => {
98
- console.log(`Databases to keep: ${databasesToKeep.map(db => db.name).join(", ")}`);
24
+ export const wipeOtherDatabases = async (database, databasesToKeep) => {
25
+ MessageFormatter.info(`Databases to keep: ${databasesToKeep.map(db => db.name).join(", ")}`);
99
26
  const allDatabases = await tryAwaitWithRetry(async () => await database.list([Query.limit(500)]));
100
- const migrationsDatabase = allDatabases.databases.find((d) => d.name.toLowerCase().trim().replace(" ", "") === "migrations");
101
- if (useMigrations && allDatabases.databases.length !== 0 && migrationsDatabase) {
102
- console.log("Wiping all databases except migrations");
103
- databasesToKeep.push(migrationsDatabase);
104
- }
105
27
  for (const db of allDatabases.databases) {
106
28
  if (!databasesToKeep.some((d) => d.name === db.name)) {
107
29
  await tryAwaitWithRetry(async () => await database.delete(db.$id));
108
- console.log(`Deleted database: ${db.name}`);
30
+ MessageFormatter.success(`Deleted database: ${db.name}`);
109
31
  }
110
32
  }
111
33
  };
@@ -117,7 +39,7 @@ export const ensureCollectionsExist = async (config, database, collectionsToEnsu
117
39
  for (const collection of collectionsToCreate) {
118
40
  if (!existingCollections.collections.some((c) => c.name === collection.name)) {
119
41
  await tryAwaitWithRetry(async () => await databaseClient.createCollection(database.$id, ulid(), collection.name, undefined, true, true));
120
- console.log(`${collection.name} collection created in ${database.name}`);
42
+ MessageFormatter.success(`${collection.name} collection created in ${database.name}`);
121
43
  }
122
44
  }
123
45
  };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Example demonstrating YAML import/export with dual terminology support
3
+ *
4
+ * This example shows how to:
5
+ * 1. Generate YAML files for both collections and tables
6
+ * 2. Load and convert between terminologies
7
+ * 3. Validate terminology consistency
8
+ * 4. Migrate between formats
9
+ */
10
+ import type { CollectionCreate } from "appwrite-utils";
11
+ /**
12
+ * Example 1: Generate YAML templates for both collection and table formats
13
+ */
14
+ export declare function generateTemplateExamples(outputDir: string): Promise<void>;
15
+ /**
16
+ * Example 2: Convert existing collection definition to different formats
17
+ */
18
+ export declare function convertCollectionFormats(collection: CollectionCreate): void;
19
+ /**
20
+ * Example 3: Load and process YAML files with mixed terminologies
21
+ */
22
+ export declare function processYamlFiles(baseDir: string): Promise<void>;
23
+ /**
24
+ * Example 4: Migrate between terminologies
25
+ */
26
+ export declare function migrateTerminology(baseDir: string): Promise<void>;
27
+ /**
28
+ * Example 5: Validate terminology consistency
29
+ */
30
+ export declare function validateTerminology(baseDir: string): Promise<void>;
31
+ /**
32
+ * Example 6: Import configuration with terminology support
33
+ */
34
+ export declare function importConfigurationExample(appwriteFolderPath: string): Promise<void>;
35
+ /**
36
+ * Example 7: Manual terminology conversion
37
+ */
38
+ export declare function manualTerminologyConversion(): void;
39
+ /**
40
+ * Main example runner
41
+ */
42
+ export declare function runYamlTerminologyExamples(outputDir: string): Promise<void>;