appwrite-utils-cli 1.11.0 → 1.12.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 (250) hide show
  1. package/{src/adapters/index.ts → dist/adapters/index.d.ts} +0 -1
  2. package/dist/adapters/index.js +10 -0
  3. package/dist/backups/operations/bucketBackup.d.ts +19 -0
  4. package/dist/backups/operations/bucketBackup.js +197 -0
  5. package/dist/backups/operations/collectionBackup.d.ts +30 -0
  6. package/dist/backups/operations/collectionBackup.js +201 -0
  7. package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
  8. package/dist/backups/operations/comprehensiveBackup.js +238 -0
  9. package/dist/backups/schemas/bucketManifest.d.ts +93 -0
  10. package/dist/backups/schemas/bucketManifest.js +33 -0
  11. package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
  12. package/dist/backups/schemas/comprehensiveManifest.js +32 -0
  13. package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
  14. package/dist/backups/tracking/centralizedTracking.js +274 -0
  15. package/dist/cli/commands/configCommands.d.ts +8 -0
  16. package/dist/cli/commands/configCommands.js +210 -0
  17. package/dist/cli/commands/databaseCommands.d.ts +14 -0
  18. package/dist/cli/commands/databaseCommands.js +696 -0
  19. package/dist/cli/commands/functionCommands.d.ts +7 -0
  20. package/dist/cli/commands/functionCommands.js +330 -0
  21. package/dist/cli/commands/importFileCommands.d.ts +7 -0
  22. package/dist/cli/commands/importFileCommands.js +674 -0
  23. package/dist/cli/commands/schemaCommands.d.ts +7 -0
  24. package/dist/cli/commands/schemaCommands.js +169 -0
  25. package/dist/cli/commands/storageCommands.d.ts +5 -0
  26. package/dist/cli/commands/storageCommands.js +142 -0
  27. package/dist/cli/commands/transferCommands.d.ts +5 -0
  28. package/dist/cli/commands/transferCommands.js +382 -0
  29. package/dist/collections/columns.d.ts +13 -0
  30. package/dist/collections/columns.js +1339 -0
  31. package/dist/collections/indexes.d.ts +12 -0
  32. package/dist/collections/indexes.js +215 -0
  33. package/dist/collections/methods.d.ts +19 -0
  34. package/dist/collections/methods.js +605 -0
  35. package/dist/collections/tableOperations.d.ts +87 -0
  36. package/dist/collections/tableOperations.js +466 -0
  37. package/dist/collections/transferOperations.d.ts +8 -0
  38. package/dist/collections/transferOperations.js +411 -0
  39. package/dist/collections/wipeOperations.d.ts +17 -0
  40. package/dist/collections/wipeOperations.js +306 -0
  41. package/dist/databases/methods.d.ts +6 -0
  42. package/dist/databases/methods.js +35 -0
  43. package/dist/databases/setup.d.ts +5 -0
  44. package/dist/databases/setup.js +45 -0
  45. package/dist/examples/yamlTerminologyExample.d.ts +42 -0
  46. package/dist/examples/yamlTerminologyExample.js +272 -0
  47. package/dist/functions/deployments.d.ts +4 -0
  48. package/dist/functions/deployments.js +146 -0
  49. package/dist/functions/fnConfigDiscovery.d.ts +3 -0
  50. package/dist/functions/fnConfigDiscovery.js +108 -0
  51. package/dist/functions/methods.d.ts +16 -0
  52. package/dist/functions/methods.js +174 -0
  53. package/dist/init.d.ts +2 -0
  54. package/dist/init.js +57 -0
  55. package/dist/interactiveCLI.d.ts +36 -0
  56. package/dist/interactiveCLI.js +952 -0
  57. package/dist/main.d.ts +2 -0
  58. package/dist/main.js +1125 -0
  59. package/dist/migrations/afterImportActions.d.ts +17 -0
  60. package/dist/migrations/afterImportActions.js +305 -0
  61. package/dist/migrations/appwriteToX.d.ts +211 -0
  62. package/dist/migrations/appwriteToX.js +493 -0
  63. package/dist/migrations/comprehensiveTransfer.d.ts +147 -0
  64. package/dist/migrations/comprehensiveTransfer.js +1315 -0
  65. package/dist/migrations/dataLoader.d.ts +755 -0
  66. package/dist/migrations/dataLoader.js +1272 -0
  67. package/dist/migrations/importController.d.ts +25 -0
  68. package/dist/migrations/importController.js +283 -0
  69. package/dist/migrations/importDataActions.d.ts +50 -0
  70. package/dist/migrations/importDataActions.js +230 -0
  71. package/dist/migrations/relationships.d.ts +29 -0
  72. package/dist/migrations/relationships.js +203 -0
  73. package/dist/migrations/services/DataTransformationService.d.ts +55 -0
  74. package/dist/migrations/services/DataTransformationService.js +158 -0
  75. package/dist/migrations/services/FileHandlerService.d.ts +75 -0
  76. package/dist/migrations/services/FileHandlerService.js +236 -0
  77. package/dist/migrations/services/ImportOrchestrator.d.ts +99 -0
  78. package/dist/migrations/services/ImportOrchestrator.js +493 -0
  79. package/dist/migrations/services/RateLimitManager.d.ts +138 -0
  80. package/dist/migrations/services/RateLimitManager.js +279 -0
  81. package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
  82. package/dist/migrations/services/RelationshipResolver.js +332 -0
  83. package/dist/migrations/services/UserMappingService.d.ts +109 -0
  84. package/dist/migrations/services/UserMappingService.js +277 -0
  85. package/dist/migrations/services/ValidationService.d.ts +74 -0
  86. package/dist/migrations/services/ValidationService.js +260 -0
  87. package/dist/migrations/transfer.d.ts +30 -0
  88. package/dist/migrations/transfer.js +661 -0
  89. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +131 -0
  90. package/dist/migrations/yaml/YamlImportConfigLoader.js +383 -0
  91. package/dist/migrations/yaml/YamlImportIntegration.d.ts +93 -0
  92. package/dist/migrations/yaml/YamlImportIntegration.js +341 -0
  93. package/dist/migrations/yaml/generateImportSchemas.d.ts +30 -0
  94. package/dist/migrations/yaml/generateImportSchemas.js +1327 -0
  95. package/dist/schemas/authUser.d.ts +24 -0
  96. package/dist/schemas/authUser.js +17 -0
  97. package/dist/setup.d.ts +2 -0
  98. package/{src/setup.ts → dist/setup.js} +0 -3
  99. package/dist/setupCommands.d.ts +58 -0
  100. package/dist/setupCommands.js +489 -0
  101. package/dist/setupController.d.ts +9 -0
  102. package/dist/setupController.js +34 -0
  103. package/dist/shared/backupMetadataSchema.d.ts +94 -0
  104. package/dist/shared/backupMetadataSchema.js +38 -0
  105. package/dist/shared/backupTracking.d.ts +18 -0
  106. package/dist/shared/backupTracking.js +176 -0
  107. package/dist/shared/confirmationDialogs.d.ts +75 -0
  108. package/dist/shared/confirmationDialogs.js +236 -0
  109. package/dist/shared/migrationHelpers.d.ts +61 -0
  110. package/dist/shared/migrationHelpers.js +145 -0
  111. package/{src/shared/operationLogger.ts → dist/shared/operationLogger.d.ts} +1 -11
  112. package/dist/shared/operationLogger.js +12 -0
  113. package/dist/shared/operationQueue.d.ts +40 -0
  114. package/dist/shared/operationQueue.js +310 -0
  115. package/dist/shared/operationsTable.d.ts +26 -0
  116. package/dist/shared/operationsTable.js +287 -0
  117. package/dist/shared/operationsTableSchema.d.ts +48 -0
  118. package/dist/shared/operationsTableSchema.js +35 -0
  119. package/dist/shared/progressManager.d.ts +62 -0
  120. package/dist/shared/progressManager.js +215 -0
  121. package/dist/shared/relationshipExtractor.d.ts +56 -0
  122. package/dist/shared/relationshipExtractor.js +138 -0
  123. package/dist/shared/selectionDialogs.d.ts +220 -0
  124. package/dist/shared/selectionDialogs.js +588 -0
  125. package/dist/storage/backupCompression.d.ts +20 -0
  126. package/dist/storage/backupCompression.js +67 -0
  127. package/dist/storage/methods.d.ts +44 -0
  128. package/dist/storage/methods.js +475 -0
  129. package/dist/storage/schemas.d.ts +842 -0
  130. package/dist/storage/schemas.js +175 -0
  131. package/dist/tables/indexManager.d.ts +65 -0
  132. package/dist/tables/indexManager.js +294 -0
  133. package/{src/types.ts → dist/types.d.ts} +1 -6
  134. package/dist/types.js +3 -0
  135. package/dist/users/methods.d.ts +16 -0
  136. package/dist/users/methods.js +276 -0
  137. package/dist/utils/configMigration.d.ts +1 -0
  138. package/dist/utils/configMigration.js +261 -0
  139. package/dist/utils/index.js +2 -0
  140. package/dist/utils/loadConfigs.d.ts +50 -0
  141. package/dist/utils/loadConfigs.js +357 -0
  142. package/dist/utils/setupFiles.d.ts +4 -0
  143. package/dist/utils/setupFiles.js +1190 -0
  144. package/dist/utilsController.d.ts +114 -0
  145. package/dist/utilsController.js +898 -0
  146. package/package.json +6 -3
  147. package/CHANGELOG.md +0 -35
  148. package/CONFIG_TODO.md +0 -1189
  149. package/SELECTION_DIALOGS.md +0 -146
  150. package/SERVICE_IMPLEMENTATION_REPORT.md +0 -462
  151. package/scripts/copy-templates.ts +0 -23
  152. package/src/backups/operations/bucketBackup.ts +0 -277
  153. package/src/backups/operations/collectionBackup.ts +0 -310
  154. package/src/backups/operations/comprehensiveBackup.ts +0 -342
  155. package/src/backups/schemas/bucketManifest.ts +0 -78
  156. package/src/backups/schemas/comprehensiveManifest.ts +0 -76
  157. package/src/backups/tracking/centralizedTracking.ts +0 -352
  158. package/src/cli/commands/configCommands.ts +0 -265
  159. package/src/cli/commands/databaseCommands.ts +0 -931
  160. package/src/cli/commands/functionCommands.ts +0 -419
  161. package/src/cli/commands/importFileCommands.ts +0 -815
  162. package/src/cli/commands/schemaCommands.ts +0 -200
  163. package/src/cli/commands/storageCommands.ts +0 -151
  164. package/src/cli/commands/transferCommands.ts +0 -454
  165. package/src/collections/attributes.ts.backup +0 -1555
  166. package/src/collections/columns.ts +0 -2025
  167. package/src/collections/indexes.ts +0 -350
  168. package/src/collections/methods.ts +0 -714
  169. package/src/collections/tableOperations.ts +0 -542
  170. package/src/collections/transferOperations.ts +0 -589
  171. package/src/collections/wipeOperations.ts +0 -449
  172. package/src/databases/methods.ts +0 -49
  173. package/src/databases/setup.ts +0 -77
  174. package/src/examples/yamlTerminologyExample.ts +0 -346
  175. package/src/functions/deployments.ts +0 -221
  176. package/src/functions/fnConfigDiscovery.ts +0 -103
  177. package/src/functions/methods.ts +0 -284
  178. package/src/init.ts +0 -62
  179. package/src/interactiveCLI.ts +0 -1201
  180. package/src/main.ts +0 -1517
  181. package/src/migrations/afterImportActions.ts +0 -579
  182. package/src/migrations/appwriteToX.ts +0 -668
  183. package/src/migrations/comprehensiveTransfer.ts +0 -2285
  184. package/src/migrations/dataLoader.ts +0 -1729
  185. package/src/migrations/importController.ts +0 -440
  186. package/src/migrations/importDataActions.ts +0 -315
  187. package/src/migrations/relationships.ts +0 -333
  188. package/src/migrations/services/DataTransformationService.ts +0 -196
  189. package/src/migrations/services/FileHandlerService.ts +0 -311
  190. package/src/migrations/services/ImportOrchestrator.ts +0 -675
  191. package/src/migrations/services/RateLimitManager.ts +0 -363
  192. package/src/migrations/services/RelationshipResolver.ts +0 -461
  193. package/src/migrations/services/UserMappingService.ts +0 -345
  194. package/src/migrations/services/ValidationService.ts +0 -349
  195. package/src/migrations/transfer.ts +0 -1113
  196. package/src/migrations/yaml/YamlImportConfigLoader.ts +0 -439
  197. package/src/migrations/yaml/YamlImportIntegration.ts +0 -446
  198. package/src/migrations/yaml/generateImportSchemas.ts +0 -1354
  199. package/src/schemas/authUser.ts +0 -23
  200. package/src/setupCommands.ts +0 -602
  201. package/src/setupController.ts +0 -43
  202. package/src/shared/backupMetadataSchema.ts +0 -93
  203. package/src/shared/backupTracking.ts +0 -211
  204. package/src/shared/confirmationDialogs.ts +0 -327
  205. package/src/shared/migrationHelpers.ts +0 -232
  206. package/src/shared/operationQueue.ts +0 -376
  207. package/src/shared/operationsTable.ts +0 -338
  208. package/src/shared/operationsTableSchema.ts +0 -60
  209. package/src/shared/progressManager.ts +0 -278
  210. package/src/shared/relationshipExtractor.ts +0 -214
  211. package/src/shared/selectionDialogs.ts +0 -802
  212. package/src/storage/backupCompression.ts +0 -88
  213. package/src/storage/methods.ts +0 -711
  214. package/src/storage/schemas.ts +0 -205
  215. package/src/tables/indexManager.ts +0 -409
  216. package/src/types/node-appwrite-tablesdb.d.ts +0 -44
  217. package/src/users/methods.ts +0 -358
  218. package/src/utils/configMigration.ts +0 -348
  219. package/src/utils/loadConfigs.ts +0 -457
  220. package/src/utils/setupFiles.ts +0 -1236
  221. package/src/utilsController.ts +0 -1263
  222. package/tests/README.md +0 -497
  223. package/tests/adapters/AdapterFactory.test.ts +0 -277
  224. package/tests/integration/syncOperations.test.ts +0 -463
  225. package/tests/jest.config.js +0 -25
  226. package/tests/migration/configMigration.test.ts +0 -546
  227. package/tests/setup.ts +0 -62
  228. package/tests/testUtils.ts +0 -340
  229. package/tests/utils/loadConfigs.test.ts +0 -350
  230. package/tests/validation/configValidation.test.ts +0 -412
  231. package/tsconfig.json +0 -44
  232. /package/{src → dist}/functions/templates/count-docs-in-collection/README.md +0 -0
  233. /package/{src → dist}/functions/templates/count-docs-in-collection/src/main.ts +0 -0
  234. /package/{src → dist}/functions/templates/count-docs-in-collection/src/request.ts +0 -0
  235. /package/{src → dist}/functions/templates/hono-typescript/README.md +0 -0
  236. /package/{src → dist}/functions/templates/hono-typescript/src/adapters/request.ts +0 -0
  237. /package/{src → dist}/functions/templates/hono-typescript/src/adapters/response.ts +0 -0
  238. /package/{src → dist}/functions/templates/hono-typescript/src/app.ts +0 -0
  239. /package/{src → dist}/functions/templates/hono-typescript/src/context.ts +0 -0
  240. /package/{src → dist}/functions/templates/hono-typescript/src/main.ts +0 -0
  241. /package/{src → dist}/functions/templates/hono-typescript/src/middleware/appwrite.ts +0 -0
  242. /package/{src → dist}/functions/templates/typescript-node/README.md +0 -0
  243. /package/{src → dist}/functions/templates/typescript-node/src/context.ts +0 -0
  244. /package/{src → dist}/functions/templates/typescript-node/src/main.ts +0 -0
  245. /package/{src → dist}/functions/templates/uv/README.md +0 -0
  246. /package/{src → dist}/functions/templates/uv/pyproject.toml +0 -0
  247. /package/{src → dist}/functions/templates/uv/src/__init__.py +0 -0
  248. /package/{src → dist}/functions/templates/uv/src/context.py +0 -0
  249. /package/{src → dist}/functions/templates/uv/src/main.py +0 -0
  250. /package/{src/utils/index.ts → dist/utils/index.d.ts} +0 -0
@@ -0,0 +1,238 @@
1
+ import { ID } from "node-appwrite";
2
+ import { InputFile } from "node-appwrite/file";
3
+ import { ulid } from "ulidx";
4
+ import { MessageFormatter } from 'appwrite-utils-helpers';
5
+ import { logger } from 'appwrite-utils-helpers';
6
+ import { backupDatabase } from "../../storage/methods.js";
7
+ import { backupBucket } from "./bucketBackup.js";
8
+ import { recordCentralizedBackup, createCentralizedBackupTrackingTable } from "../tracking/centralizedTracking.js";
9
+ import { fetchAllDatabases } from "../../databases/methods.js";
10
+ /**
11
+ * Orchestrates comprehensive backup of ALL databases and ALL storage buckets
12
+ */
13
+ export async function comprehensiveBackup(config, databases, storage, adapter, options) {
14
+ const startTime = Date.now();
15
+ const backupId = ulid();
16
+ const errors = [];
17
+ const databaseBackups = [];
18
+ const bucketBackups = [];
19
+ let totalSizeBytes = 0;
20
+ try {
21
+ // Ensure tracking table exists
22
+ await createCentralizedBackupTrackingTable(adapter, options.trackingDatabaseId);
23
+ // Initialize backup bucket
24
+ const backupBucketId = "appwrite-backups";
25
+ MessageFormatter.info(`Starting comprehensive backup ${backupId}`, { prefix: "Backup" });
26
+ // Phase 1: Backup ALL databases
27
+ if (!options.skipDatabases) {
28
+ MessageFormatter.info("Phase 1: Backing up ALL databases", { prefix: "Backup" });
29
+ const allDatabases = await fetchAllDatabases(databases);
30
+ // Validate each database exists before attempting backup
31
+ const validDatabases = [];
32
+ const skippedDatabases = [];
33
+ MessageFormatter.info(`Validating ${allDatabases.length} databases...`, { prefix: "Backup" });
34
+ for (const db of allDatabases) {
35
+ try {
36
+ await databases.get(db.$id); // Validate existence
37
+ validDatabases.push(db);
38
+ }
39
+ catch (error) {
40
+ skippedDatabases.push(`${db.name} (${db.$id})`);
41
+ MessageFormatter.warning(`Database ${db.name} not found - skipping`, { prefix: "Backup" });
42
+ logger.warn('Database validation failed', {
43
+ databaseId: db.$id,
44
+ databaseName: db.name,
45
+ error: error instanceof Error ? error.message : String(error)
46
+ });
47
+ }
48
+ }
49
+ if (skippedDatabases.length > 0) {
50
+ MessageFormatter.info(`Skipped ${skippedDatabases.length} invalid databases: ${skippedDatabases.join(', ')}`, { prefix: "Backup" });
51
+ }
52
+ MessageFormatter.info(`Found ${validDatabases.length} valid databases to backup`, { prefix: "Backup" });
53
+ for (const db of validDatabases) {
54
+ try {
55
+ if (options.onProgress) {
56
+ options.onProgress(`Backing up database: ${db.name}`);
57
+ }
58
+ MessageFormatter.info(`Backing up database: ${db.name} (${db.$id})`, { prefix: "Backup" });
59
+ // Use existing backupDatabase function
60
+ const dbBackupResult = await backupDatabase(config, databases, db.$id, storage, options.backupFormat || 'zip');
61
+ // Create database manifest with complete data
62
+ const manifestData = {
63
+ version: "1.0",
64
+ databaseId: dbBackupResult.databaseId,
65
+ databaseName: dbBackupResult.databaseName,
66
+ format: dbBackupResult.format,
67
+ collectionCount: dbBackupResult.collectionCount,
68
+ documentCount: dbBackupResult.documentCount,
69
+ backupFileId: dbBackupResult.backupFileId,
70
+ createdAt: new Date().toISOString()
71
+ };
72
+ const manifestBuffer = Buffer.from(JSON.stringify(manifestData, null, 2), 'utf-8');
73
+ const manifestFile = await storage.createFile(backupBucketId, ID.unique(), InputFile.fromBuffer(new Uint8Array(manifestBuffer), `${db.$id}-manifest.json`));
74
+ databaseBackups.push({
75
+ databaseId: dbBackupResult.databaseId,
76
+ databaseName: dbBackupResult.databaseName,
77
+ backupFileId: dbBackupResult.backupFileId,
78
+ manifestFileId: manifestFile.$id,
79
+ collectionCount: dbBackupResult.collectionCount,
80
+ documentCount: dbBackupResult.documentCount,
81
+ sizeBytes: dbBackupResult.backupSizeBytes,
82
+ status: 'completed'
83
+ });
84
+ totalSizeBytes += dbBackupResult.backupSizeBytes;
85
+ // Record individual database backup in tracking
86
+ await recordCentralizedBackup(adapter, options.trackingDatabaseId, {
87
+ backupType: 'database',
88
+ backupId: dbBackupResult.backupFileId,
89
+ manifestFileId: manifestFile.$id,
90
+ format: dbBackupResult.format,
91
+ sizeBytes: dbBackupResult.backupSizeBytes,
92
+ databaseId: dbBackupResult.databaseId,
93
+ collections: dbBackupResult.collectionCount,
94
+ documents: dbBackupResult.documentCount,
95
+ status: 'completed',
96
+ restorationStatus: 'not_restored'
97
+ });
98
+ MessageFormatter.success(`Database ${db.name} backed up successfully`, { prefix: "Backup" });
99
+ }
100
+ catch (error) {
101
+ const errorMsg = `Failed to backup database ${db.name}: ${error instanceof Error ? error.message : String(error)}`;
102
+ errors.push(errorMsg);
103
+ logger.error(errorMsg);
104
+ databaseBackups.push({
105
+ databaseId: db.$id,
106
+ databaseName: db.name,
107
+ backupFileId: '',
108
+ manifestFileId: '',
109
+ collectionCount: 0,
110
+ documentCount: 0,
111
+ sizeBytes: 0,
112
+ status: 'failed',
113
+ error: errorMsg
114
+ });
115
+ }
116
+ }
117
+ }
118
+ // Phase 2: Backup ALL storage buckets
119
+ if (!options.skipBuckets) {
120
+ MessageFormatter.info("Phase 2: Backing up ALL storage buckets", { prefix: "Backup" });
121
+ const allBuckets = await storage.listBuckets();
122
+ const bucketsToBackup = allBuckets.buckets.filter(b => b.$id !== backupBucketId);
123
+ MessageFormatter.info(`Found ${bucketsToBackup.length} buckets to backup`, { prefix: "Backup" });
124
+ for (const bucket of bucketsToBackup) {
125
+ try {
126
+ if (options.onProgress) {
127
+ options.onProgress(`Backing up bucket: ${bucket.name}`);
128
+ }
129
+ MessageFormatter.info(`Backing up bucket: ${bucket.name} (${bucket.$id})`, { prefix: "Backup" });
130
+ const bucketBackupResult = await backupBucket(storage, bucket.$id, backupBucketId, {
131
+ parallelDownloads: options.parallelDownloads || 10,
132
+ onProgress: (current, total, fileName) => {
133
+ if (options.onProgress) {
134
+ options.onProgress(`Downloading ${fileName} (${current}/${total})`);
135
+ }
136
+ }
137
+ });
138
+ bucketBackups.push({
139
+ bucketId: bucket.$id,
140
+ bucketName: bucket.name,
141
+ backupFileId: bucketBackupResult.backupFileId,
142
+ manifestFileId: bucketBackupResult.manifestFileId,
143
+ fileCount: bucketBackupResult.fileCount,
144
+ sizeBytes: bucketBackupResult.totalSizeBytes,
145
+ status: bucketBackupResult.status,
146
+ error: bucketBackupResult.errors?.join('; ')
147
+ });
148
+ totalSizeBytes += bucketBackupResult.zipSizeBytes;
149
+ // Record individual bucket backup in tracking
150
+ await recordCentralizedBackup(adapter, options.trackingDatabaseId, {
151
+ backupType: 'bucket',
152
+ backupId: bucketBackupResult.backupFileId,
153
+ manifestFileId: bucketBackupResult.manifestFileId,
154
+ format: 'zip',
155
+ sizeBytes: bucketBackupResult.zipSizeBytes,
156
+ bucketId: bucket.$id,
157
+ fileCount: bucketBackupResult.fileCount,
158
+ status: bucketBackupResult.status,
159
+ error: bucketBackupResult.errors?.join('; '),
160
+ restorationStatus: 'not_restored'
161
+ });
162
+ MessageFormatter.success(`Bucket ${bucket.name} backed up successfully`, { prefix: "Backup" });
163
+ }
164
+ catch (error) {
165
+ const errorMsg = `Failed to backup bucket ${bucket.name}: ${error instanceof Error ? error.message : String(error)}`;
166
+ errors.push(errorMsg);
167
+ logger.error(errorMsg);
168
+ bucketBackups.push({
169
+ bucketId: bucket.$id,
170
+ bucketName: bucket.name,
171
+ backupFileId: '',
172
+ manifestFileId: '',
173
+ fileCount: 0,
174
+ sizeBytes: 0,
175
+ status: 'failed',
176
+ error: errorMsg
177
+ });
178
+ }
179
+ }
180
+ }
181
+ // Phase 3: Create comprehensive manifest
182
+ MessageFormatter.info("Creating comprehensive backup manifest", { prefix: "Backup" });
183
+ const comprehensiveStatus = errors.length === 0 ? 'completed' :
184
+ (databaseBackups.length > 0 || bucketBackups.length > 0) ? 'partial' :
185
+ 'failed';
186
+ const manifest = {
187
+ version: "1.0",
188
+ backupId,
189
+ createdAt: new Date().toISOString(),
190
+ databases: databaseBackups,
191
+ buckets: bucketBackups,
192
+ totalSizeBytes,
193
+ status: comprehensiveStatus,
194
+ errors: errors.length > 0 ? errors : undefined
195
+ };
196
+ // Upload comprehensive manifest
197
+ const manifestFileName = `comprehensive-${backupId}.json`;
198
+ const manifestBuffer = Buffer.from(JSON.stringify(manifest, null, 2), 'utf-8');
199
+ const manifestFile = await storage.createFile(backupBucketId, ID.unique(), InputFile.fromBuffer(new Uint8Array(manifestBuffer), manifestFileName));
200
+ // Record comprehensive backup in tracking
201
+ await recordCentralizedBackup(adapter, options.trackingDatabaseId, {
202
+ backupType: 'comprehensive',
203
+ backupId,
204
+ manifestFileId: manifestFile.$id,
205
+ format: 'zip',
206
+ sizeBytes: totalSizeBytes,
207
+ comprehensiveBackupId: backupId,
208
+ status: comprehensiveStatus,
209
+ error: errors.length > 0 ? errors.join('; ') : undefined,
210
+ restorationStatus: 'not_restored'
211
+ });
212
+ const duration = Date.now() - startTime;
213
+ MessageFormatter.success(`Comprehensive backup ${comprehensiveStatus} in ${(duration / 1000).toFixed(2)}s`, { prefix: "Backup" });
214
+ MessageFormatter.info(`Backed up ${databaseBackups.length} databases and ${bucketBackups.length} buckets (${MessageFormatter.formatBytes(totalSizeBytes)})`, { prefix: "Backup" });
215
+ return {
216
+ backupId,
217
+ manifestFileId: manifestFile.$id,
218
+ databaseBackups,
219
+ bucketBackups,
220
+ totalSizeBytes,
221
+ status: comprehensiveStatus,
222
+ errors
223
+ };
224
+ }
225
+ catch (error) {
226
+ const errorMsg = `Comprehensive backup failed: ${error instanceof Error ? error.message : String(error)}`;
227
+ MessageFormatter.error(errorMsg, error instanceof Error ? error : new Error(errorMsg), { prefix: "Backup" });
228
+ return {
229
+ backupId,
230
+ manifestFileId: '',
231
+ databaseBackups,
232
+ bucketBackups,
233
+ totalSizeBytes,
234
+ status: 'failed',
235
+ errors: [errorMsg, ...errors]
236
+ };
237
+ }
238
+ }
@@ -0,0 +1,93 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Schema for bucket backup manifest
4
+ *
5
+ * This manifest is stored alongside bucket backup ZIPs to describe
6
+ * the bucket configuration and files that were backed up.
7
+ */
8
+ export interface BucketFileMetadata {
9
+ $id: string;
10
+ name: string;
11
+ size: number;
12
+ mimeType: string;
13
+ $permissions: string[];
14
+ chunksCount: number;
15
+ signature: string;
16
+ $createdAt: string;
17
+ $updatedAt: string;
18
+ }
19
+ export interface BucketConfiguration {
20
+ $permissions: string[];
21
+ fileSecurity: boolean;
22
+ enabled: boolean;
23
+ maximumFileSize: number;
24
+ allowedFileExtensions: string[];
25
+ compression: string;
26
+ encryption: boolean;
27
+ antivirus: boolean;
28
+ }
29
+ export interface BucketManifest {
30
+ version: string;
31
+ bucketId: string;
32
+ bucketName: string;
33
+ createdAt: string;
34
+ fileCount: number;
35
+ totalSizeBytes: number;
36
+ compression: 'gzip' | 'none';
37
+ files: BucketFileMetadata[];
38
+ bucketConfiguration: BucketConfiguration;
39
+ }
40
+ export declare const BucketFileMetadataSchema: z.ZodObject<{
41
+ $id: z.ZodString;
42
+ name: z.ZodString;
43
+ size: z.ZodNumber;
44
+ mimeType: z.ZodString;
45
+ $permissions: z.ZodArray<z.ZodString>;
46
+ chunksCount: z.ZodNumber;
47
+ signature: z.ZodString;
48
+ $createdAt: z.ZodString;
49
+ $updatedAt: z.ZodString;
50
+ }, z.core.$strip>;
51
+ export declare const BucketConfigurationSchema: z.ZodObject<{
52
+ $permissions: z.ZodArray<z.ZodString>;
53
+ fileSecurity: z.ZodBoolean;
54
+ enabled: z.ZodBoolean;
55
+ maximumFileSize: z.ZodNumber;
56
+ allowedFileExtensions: z.ZodArray<z.ZodString>;
57
+ compression: z.ZodString;
58
+ encryption: z.ZodBoolean;
59
+ antivirus: z.ZodBoolean;
60
+ }, z.core.$strip>;
61
+ export declare const BucketManifestSchema: z.ZodObject<{
62
+ version: z.ZodDefault<z.ZodString>;
63
+ bucketId: z.ZodString;
64
+ bucketName: z.ZodString;
65
+ createdAt: z.ZodString;
66
+ fileCount: z.ZodNumber;
67
+ totalSizeBytes: z.ZodNumber;
68
+ compression: z.ZodEnum<{
69
+ none: "none";
70
+ gzip: "gzip";
71
+ }>;
72
+ files: z.ZodArray<z.ZodObject<{
73
+ $id: z.ZodString;
74
+ name: z.ZodString;
75
+ size: z.ZodNumber;
76
+ mimeType: z.ZodString;
77
+ $permissions: z.ZodArray<z.ZodString>;
78
+ chunksCount: z.ZodNumber;
79
+ signature: z.ZodString;
80
+ $createdAt: z.ZodString;
81
+ $updatedAt: z.ZodString;
82
+ }, z.core.$strip>>;
83
+ bucketConfiguration: z.ZodObject<{
84
+ $permissions: z.ZodArray<z.ZodString>;
85
+ fileSecurity: z.ZodBoolean;
86
+ enabled: z.ZodBoolean;
87
+ maximumFileSize: z.ZodNumber;
88
+ allowedFileExtensions: z.ZodArray<z.ZodString>;
89
+ compression: z.ZodString;
90
+ encryption: z.ZodBoolean;
91
+ antivirus: z.ZodBoolean;
92
+ }, z.core.$strip>;
93
+ }, z.core.$strip>;
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ export const BucketFileMetadataSchema = z.object({
3
+ $id: z.string(),
4
+ name: z.string(),
5
+ size: z.number(),
6
+ mimeType: z.string(),
7
+ $permissions: z.array(z.string()),
8
+ chunksCount: z.number(),
9
+ signature: z.string(),
10
+ $createdAt: z.string(),
11
+ $updatedAt: z.string()
12
+ });
13
+ export const BucketConfigurationSchema = z.object({
14
+ $permissions: z.array(z.string()),
15
+ fileSecurity: z.boolean(),
16
+ enabled: z.boolean(),
17
+ maximumFileSize: z.number(),
18
+ allowedFileExtensions: z.array(z.string()),
19
+ compression: z.string(),
20
+ encryption: z.boolean(),
21
+ antivirus: z.boolean()
22
+ });
23
+ export const BucketManifestSchema = z.object({
24
+ version: z.string().default("1.0"),
25
+ bucketId: z.string(),
26
+ bucketName: z.string(),
27
+ createdAt: z.string(),
28
+ fileCount: z.number(),
29
+ totalSizeBytes: z.number(),
30
+ compression: z.enum(['gzip', 'none']),
31
+ files: z.array(BucketFileMetadataSchema),
32
+ bucketConfiguration: BucketConfigurationSchema
33
+ });
@@ -0,0 +1,108 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Schema for comprehensive backup manifest
4
+ *
5
+ * This manifest tracks all databases and buckets included in a comprehensive backup,
6
+ * allowing for complete system restoration.
7
+ */
8
+ export interface DatabaseBackupReference {
9
+ databaseId: string;
10
+ databaseName: string;
11
+ backupFileId: string;
12
+ manifestFileId: string;
13
+ collectionCount: number;
14
+ documentCount: number;
15
+ sizeBytes: number;
16
+ status: 'completed' | 'partial' | 'failed';
17
+ error?: string;
18
+ }
19
+ export interface BucketBackupReference {
20
+ bucketId: string;
21
+ bucketName: string;
22
+ backupFileId: string;
23
+ manifestFileId: string;
24
+ fileCount: number;
25
+ sizeBytes: number;
26
+ status: 'completed' | 'partial' | 'failed';
27
+ error?: string;
28
+ }
29
+ export interface ComprehensiveManifest {
30
+ version: string;
31
+ backupId: string;
32
+ createdAt: string;
33
+ databases: DatabaseBackupReference[];
34
+ buckets: BucketBackupReference[];
35
+ totalSizeBytes: number;
36
+ status: 'completed' | 'partial' | 'failed';
37
+ errors?: string[];
38
+ }
39
+ export declare const DatabaseBackupReferenceSchema: z.ZodObject<{
40
+ databaseId: z.ZodString;
41
+ databaseName: z.ZodString;
42
+ backupFileId: z.ZodString;
43
+ manifestFileId: z.ZodString;
44
+ collectionCount: z.ZodNumber;
45
+ documentCount: z.ZodNumber;
46
+ sizeBytes: z.ZodNumber;
47
+ status: z.ZodEnum<{
48
+ completed: "completed";
49
+ failed: "failed";
50
+ partial: "partial";
51
+ }>;
52
+ error: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strip>;
54
+ export declare const BucketBackupReferenceSchema: z.ZodObject<{
55
+ bucketId: z.ZodString;
56
+ bucketName: z.ZodString;
57
+ backupFileId: z.ZodString;
58
+ manifestFileId: z.ZodString;
59
+ fileCount: z.ZodNumber;
60
+ sizeBytes: z.ZodNumber;
61
+ status: z.ZodEnum<{
62
+ completed: "completed";
63
+ failed: "failed";
64
+ partial: "partial";
65
+ }>;
66
+ error: z.ZodOptional<z.ZodString>;
67
+ }, z.core.$strip>;
68
+ export declare const ComprehensiveManifestSchema: z.ZodObject<{
69
+ version: z.ZodDefault<z.ZodString>;
70
+ backupId: z.ZodString;
71
+ createdAt: z.ZodString;
72
+ databases: z.ZodArray<z.ZodObject<{
73
+ databaseId: z.ZodString;
74
+ databaseName: z.ZodString;
75
+ backupFileId: z.ZodString;
76
+ manifestFileId: z.ZodString;
77
+ collectionCount: z.ZodNumber;
78
+ documentCount: z.ZodNumber;
79
+ sizeBytes: z.ZodNumber;
80
+ status: z.ZodEnum<{
81
+ completed: "completed";
82
+ failed: "failed";
83
+ partial: "partial";
84
+ }>;
85
+ error: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$strip>>;
87
+ buckets: z.ZodArray<z.ZodObject<{
88
+ bucketId: z.ZodString;
89
+ bucketName: z.ZodString;
90
+ backupFileId: z.ZodString;
91
+ manifestFileId: z.ZodString;
92
+ fileCount: z.ZodNumber;
93
+ sizeBytes: z.ZodNumber;
94
+ status: z.ZodEnum<{
95
+ completed: "completed";
96
+ failed: "failed";
97
+ partial: "partial";
98
+ }>;
99
+ error: z.ZodOptional<z.ZodString>;
100
+ }, z.core.$strip>>;
101
+ totalSizeBytes: z.ZodNumber;
102
+ status: z.ZodEnum<{
103
+ completed: "completed";
104
+ failed: "failed";
105
+ partial: "partial";
106
+ }>;
107
+ errors: z.ZodOptional<z.ZodArray<z.ZodString>>;
108
+ }, z.core.$strip>;
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ export const DatabaseBackupReferenceSchema = z.object({
3
+ databaseId: z.string(),
4
+ databaseName: z.string(),
5
+ backupFileId: z.string(),
6
+ manifestFileId: z.string(),
7
+ collectionCount: z.number(),
8
+ documentCount: z.number(),
9
+ sizeBytes: z.number(),
10
+ status: z.enum(['completed', 'partial', 'failed']),
11
+ error: z.string().optional()
12
+ });
13
+ export const BucketBackupReferenceSchema = z.object({
14
+ bucketId: z.string(),
15
+ bucketName: z.string(),
16
+ backupFileId: z.string(),
17
+ manifestFileId: z.string(),
18
+ fileCount: z.number(),
19
+ sizeBytes: z.number(),
20
+ status: z.enum(['completed', 'partial', 'failed']),
21
+ error: z.string().optional()
22
+ });
23
+ export const ComprehensiveManifestSchema = z.object({
24
+ version: z.string().default("1.0"),
25
+ backupId: z.string(),
26
+ createdAt: z.string(),
27
+ databases: z.array(DatabaseBackupReferenceSchema),
28
+ buckets: z.array(BucketBackupReferenceSchema),
29
+ totalSizeBytes: z.number(),
30
+ status: z.enum(['completed', 'partial', 'failed']),
31
+ errors: z.array(z.string()).optional()
32
+ });
@@ -0,0 +1,34 @@
1
+ import type { DatabaseAdapter } from 'appwrite-utils-helpers';
2
+ import { type BackupMetadata, type BackupType } from "../../shared/backupMetadataSchema.js";
3
+ /**
4
+ * Creates the centralized backup tracking table with enhanced schema
5
+ */
6
+ export declare function createCentralizedBackupTrackingTable(db: DatabaseAdapter, databaseId: string): Promise<void>;
7
+ /**
8
+ * Records backup metadata in the centralized tracking table
9
+ */
10
+ export declare function recordCentralizedBackup(db: DatabaseAdapter, trackingDatabaseId: string, metadata: Omit<BackupMetadata, '$id' | '$createdAt' | '$updatedAt'>): Promise<BackupMetadata>;
11
+ /**
12
+ * Lists all backups of a specific type, sorted by creation date (newest first)
13
+ */
14
+ export declare function listCentralizedBackups(db: DatabaseAdapter, trackingDatabaseId: string, options?: {
15
+ backupType?: BackupType;
16
+ resourceId?: string;
17
+ limit?: number;
18
+ }): Promise<BackupMetadata[]>;
19
+ /**
20
+ * Gets a specific backup by its backup file ID
21
+ */
22
+ export declare function getCentralizedBackup(db: DatabaseAdapter, trackingDatabaseId: string, backupId: string): Promise<BackupMetadata | null>;
23
+ /**
24
+ * Updates restoration status for a backup
25
+ */
26
+ export declare function updateRestorationStatus(db: DatabaseAdapter, trackingDatabaseId: string, backupRecordId: string, restorationData: {
27
+ restoredAt: string;
28
+ restorationStatus: 'completed' | 'partial' | 'failed';
29
+ restorationError?: string;
30
+ }): Promise<void>;
31
+ /**
32
+ * Gets the most recent comprehensive backup
33
+ */
34
+ export declare function getLastComprehensiveBackup(db: DatabaseAdapter, trackingDatabaseId: string): Promise<BackupMetadata | null>;