appwrite-utils-cli 1.9.7 → 1.11.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.
- package/CONFIG_TODO.md +1189 -1189
- package/README.md +1004 -1004
- package/SELECTION_DIALOGS.md +145 -145
- package/SERVICE_IMPLEMENTATION_REPORT.md +462 -462
- package/package.json +6 -3
- package/scripts/copy-templates.ts +23 -23
- package/src/adapters/index.ts +11 -37
- package/src/backups/operations/bucketBackup.ts +277 -277
- package/src/backups/operations/collectionBackup.ts +310 -310
- package/src/backups/operations/comprehensiveBackup.ts +342 -342
- package/src/backups/schemas/bucketManifest.ts +78 -78
- package/src/backups/schemas/comprehensiveManifest.ts +76 -76
- package/src/backups/tracking/centralizedTracking.ts +352 -352
- package/src/cli/commands/configCommands.ts +265 -201
- package/src/cli/commands/databaseCommands.ts +931 -879
- package/src/cli/commands/functionCommands.ts +333 -332
- package/src/cli/commands/importFileCommands.ts +815 -0
- package/src/cli/commands/schemaCommands.ts +141 -141
- package/src/cli/commands/storageCommands.ts +2 -3
- package/src/cli/commands/transferCommands.ts +454 -457
- package/src/collections/attributes.ts.backup +1555 -1555
- package/src/collections/{attributes.ts → columns.ts} +15 -10
- package/src/collections/indexes.ts +350 -352
- package/src/collections/methods.ts +714 -700
- package/src/collections/tableOperations.ts +29 -8
- package/src/collections/transferOperations.ts +376 -377
- package/src/collections/wipeOperations.ts +449 -346
- package/src/databases/methods.ts +49 -49
- package/src/databases/setup.ts +77 -77
- package/src/examples/yamlTerminologyExample.ts +346 -346
- package/src/functions/deployments.ts +221 -220
- package/src/functions/fnConfigDiscovery.ts +2 -2
- package/src/functions/methods.ts +284 -284
- package/src/functions/templates/count-docs-in-collection/README.md +53 -53
- package/src/functions/templates/count-docs-in-collection/src/main.ts +159 -159
- package/src/functions/templates/count-docs-in-collection/src/request.ts +8 -8
- package/src/functions/templates/hono-typescript/README.md +285 -285
- package/src/functions/templates/hono-typescript/src/adapters/request.ts +73 -73
- package/src/functions/templates/hono-typescript/src/adapters/response.ts +105 -105
- package/src/functions/templates/hono-typescript/src/app.ts +179 -179
- package/src/functions/templates/hono-typescript/src/context.ts +102 -102
- package/src/functions/templates/hono-typescript/src/{index.ts → main.ts} +53 -53
- package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +118 -118
- package/src/functions/templates/typescript-node/README.md +31 -31
- package/src/functions/templates/typescript-node/src/context.ts +102 -102
- package/src/functions/templates/typescript-node/src/{index.ts → main.ts} +29 -29
- package/src/functions/templates/uv/README.md +30 -30
- package/src/functions/templates/uv/pyproject.toml +29 -29
- package/src/functions/templates/uv/src/context.py +124 -124
- package/src/functions/templates/uv/src/{index.py → main.py} +45 -45
- package/src/init.ts +62 -62
- package/src/interactiveCLI.ts +1095 -1030
- package/src/main.ts +1517 -1670
- package/src/migrations/afterImportActions.ts +579 -580
- package/src/migrations/appwriteToX.ts +634 -630
- package/src/migrations/comprehensiveTransfer.ts +2149 -2149
- package/src/migrations/dataLoader.ts +1729 -1702
- package/src/migrations/importController.ts +440 -428
- package/src/migrations/importDataActions.ts +315 -315
- package/src/migrations/relationships.ts +333 -334
- package/src/migrations/services/DataTransformationService.ts +195 -195
- package/src/migrations/services/FileHandlerService.ts +310 -310
- package/src/migrations/services/ImportOrchestrator.ts +674 -665
- package/src/migrations/services/RateLimitManager.ts +362 -362
- package/src/migrations/services/RelationshipResolver.ts +460 -460
- package/src/migrations/services/UserMappingService.ts +344 -344
- package/src/migrations/services/ValidationService.ts +333 -333
- package/src/migrations/transfer.ts +987 -942
- package/src/migrations/yaml/YamlImportConfigLoader.ts +438 -438
- package/src/migrations/yaml/YamlImportIntegration.ts +438 -438
- package/src/migrations/yaml/generateImportSchemas.ts +1347 -1347
- package/src/schemas/authUser.ts +23 -23
- package/src/setup.ts +8 -8
- package/src/setupCommands.ts +5 -6
- package/src/setupController.ts +42 -42
- package/src/shared/backupMetadataSchema.ts +93 -93
- package/src/shared/backupTracking.ts +211 -211
- package/src/shared/confirmationDialogs.ts +326 -326
- package/src/shared/migrationHelpers.ts +232 -232
- package/src/shared/operationLogger.ts +20 -20
- package/src/shared/operationQueue.ts +326 -327
- package/src/shared/operationsTable.ts +338 -338
- package/src/shared/operationsTableSchema.ts +60 -60
- package/src/shared/progressManager.ts +277 -277
- package/src/shared/relationshipExtractor.ts +214 -214
- package/src/shared/selectionDialogs.ts +775 -722
- package/src/storage/backupCompression.ts +88 -88
- package/src/storage/methods.ts +695 -682
- package/src/storage/schemas.ts +205 -205
- package/src/tables/indexManager.ts +408 -408
- package/src/types/node-appwrite-tablesdb.d.ts +43 -43
- package/src/types.ts +9 -9
- package/src/users/methods.ts +358 -359
- package/src/utils/configMigration.ts +347 -347
- package/src/utils/index.ts +2 -2
- package/src/utils/loadConfigs.ts +457 -449
- package/src/utils/setupFiles.ts +1236 -1238
- package/src/utilsController.ts +1263 -1213
- package/tests/README.md +496 -496
- package/tests/adapters/AdapterFactory.test.ts +276 -276
- package/tests/integration/syncOperations.test.ts +462 -462
- package/tests/jest.config.js +24 -24
- package/tests/migration/configMigration.test.ts +545 -545
- package/tests/setup.ts +61 -61
- package/tests/testUtils.ts +339 -339
- package/tests/utils/loadConfigs.test.ts +349 -349
- package/tests/validation/configValidation.test.ts +411 -411
- package/tsconfig.json +44 -44
- package/.appwrite/.yaml_schemas/appwrite-config.schema.json +0 -380
- package/.appwrite/.yaml_schemas/collection.schema.json +0 -255
- package/.appwrite/collections/Categories.yaml +0 -182
- package/.appwrite/collections/ExampleCollection.yaml +0 -36
- package/.appwrite/collections/Posts.yaml +0 -227
- package/.appwrite/collections/Users.yaml +0 -149
- package/.appwrite/config.yaml +0 -109
- package/.appwrite/import/README.md +0 -148
- package/.appwrite/import/categories-import.yaml +0 -129
- package/.appwrite/import/posts-import.yaml +0 -208
- package/.appwrite/import/users-import.yaml +0 -130
- package/.appwrite/importData/categories.json +0 -194
- package/.appwrite/importData/posts.json +0 -270
- package/.appwrite/importData/users.json +0 -220
- package/.appwrite/schemas/categories.json +0 -128
- package/.appwrite/schemas/exampleCollection.json +0 -52
- package/.appwrite/schemas/posts.json +0 -173
- package/.appwrite/schemas/users.json +0 -125
- package/dist/adapters/AdapterFactory.d.ts +0 -94
- package/dist/adapters/AdapterFactory.js +0 -420
- package/dist/adapters/DatabaseAdapter.d.ts +0 -243
- package/dist/adapters/DatabaseAdapter.js +0 -50
- package/dist/adapters/LegacyAdapter.d.ts +0 -50
- package/dist/adapters/LegacyAdapter.js +0 -615
- package/dist/adapters/TablesDBAdapter.d.ts +0 -45
- package/dist/adapters/TablesDBAdapter.js +0 -611
- package/dist/adapters/index.d.ts +0 -11
- package/dist/adapters/index.js +0 -12
- package/dist/backups/operations/bucketBackup.d.ts +0 -19
- package/dist/backups/operations/bucketBackup.js +0 -197
- package/dist/backups/operations/collectionBackup.d.ts +0 -30
- package/dist/backups/operations/collectionBackup.js +0 -201
- package/dist/backups/operations/comprehensiveBackup.d.ts +0 -25
- package/dist/backups/operations/comprehensiveBackup.js +0 -238
- package/dist/backups/schemas/bucketManifest.d.ts +0 -93
- package/dist/backups/schemas/bucketManifest.js +0 -33
- package/dist/backups/schemas/comprehensiveManifest.d.ts +0 -108
- package/dist/backups/schemas/comprehensiveManifest.js +0 -32
- package/dist/backups/tracking/centralizedTracking.d.ts +0 -34
- package/dist/backups/tracking/centralizedTracking.js +0 -274
- package/dist/cli/commands/configCommands.d.ts +0 -8
- package/dist/cli/commands/configCommands.js +0 -166
- package/dist/cli/commands/databaseCommands.d.ts +0 -14
- package/dist/cli/commands/databaseCommands.js +0 -644
- package/dist/cli/commands/functionCommands.d.ts +0 -7
- package/dist/cli/commands/functionCommands.js +0 -330
- package/dist/cli/commands/schemaCommands.d.ts +0 -7
- package/dist/cli/commands/schemaCommands.js +0 -169
- package/dist/cli/commands/storageCommands.d.ts +0 -5
- package/dist/cli/commands/storageCommands.js +0 -143
- package/dist/cli/commands/transferCommands.d.ts +0 -5
- package/dist/cli/commands/transferCommands.js +0 -384
- package/dist/collections/attributes.d.ts +0 -13
- package/dist/collections/attributes.js +0 -1333
- package/dist/collections/indexes.d.ts +0 -12
- package/dist/collections/indexes.js +0 -217
- package/dist/collections/methods.d.ts +0 -19
- package/dist/collections/methods.js +0 -587
- package/dist/collections/tableOperations.d.ts +0 -86
- package/dist/collections/tableOperations.js +0 -447
- package/dist/collections/transferOperations.d.ts +0 -8
- package/dist/collections/transferOperations.js +0 -412
- package/dist/collections/wipeOperations.d.ts +0 -16
- package/dist/collections/wipeOperations.js +0 -233
- package/dist/config/ConfigManager.d.ts +0 -450
- package/dist/config/ConfigManager.js +0 -650
- package/dist/config/configMigration.d.ts +0 -87
- package/dist/config/configMigration.js +0 -390
- package/dist/config/configValidation.d.ts +0 -66
- package/dist/config/configValidation.js +0 -358
- package/dist/config/index.d.ts +0 -8
- package/dist/config/index.js +0 -7
- package/dist/config/services/ConfigDiscoveryService.d.ts +0 -122
- package/dist/config/services/ConfigDiscoveryService.js +0 -322
- package/dist/config/services/ConfigLoaderService.d.ts +0 -129
- package/dist/config/services/ConfigLoaderService.js +0 -535
- package/dist/config/services/ConfigMergeService.d.ts +0 -208
- package/dist/config/services/ConfigMergeService.js +0 -308
- package/dist/config/services/ConfigValidationService.d.ts +0 -214
- package/dist/config/services/ConfigValidationService.js +0 -310
- package/dist/config/services/SessionAuthService.d.ts +0 -225
- package/dist/config/services/SessionAuthService.js +0 -456
- package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +0 -1
- package/dist/config/services/__tests__/ConfigMergeService.test.js +0 -271
- package/dist/config/services/index.d.ts +0 -13
- package/dist/config/services/index.js +0 -10
- package/dist/config/yamlConfig.d.ts +0 -722
- package/dist/config/yamlConfig.js +0 -702
- package/dist/databases/methods.d.ts +0 -6
- package/dist/databases/methods.js +0 -35
- package/dist/databases/setup.d.ts +0 -5
- package/dist/databases/setup.js +0 -45
- package/dist/examples/yamlTerminologyExample.d.ts +0 -42
- package/dist/examples/yamlTerminologyExample.js +0 -272
- package/dist/functions/deployments.d.ts +0 -4
- package/dist/functions/deployments.js +0 -146
- package/dist/functions/fnConfigDiscovery.d.ts +0 -3
- package/dist/functions/fnConfigDiscovery.js +0 -108
- package/dist/functions/methods.d.ts +0 -16
- package/dist/functions/methods.js +0 -174
- package/dist/functions/pathResolution.d.ts +0 -37
- package/dist/functions/pathResolution.js +0 -185
- package/dist/functions/templates/count-docs-in-collection/README.md +0 -54
- package/dist/functions/templates/count-docs-in-collection/package.json +0 -25
- package/dist/functions/templates/count-docs-in-collection/src/main.ts +0 -159
- package/dist/functions/templates/count-docs-in-collection/src/request.ts +0 -9
- package/dist/functions/templates/count-docs-in-collection/tsconfig.json +0 -28
- package/dist/functions/templates/hono-typescript/README.md +0 -286
- package/dist/functions/templates/hono-typescript/package.json +0 -26
- package/dist/functions/templates/hono-typescript/src/adapters/request.ts +0 -74
- package/dist/functions/templates/hono-typescript/src/adapters/response.ts +0 -106
- package/dist/functions/templates/hono-typescript/src/app.ts +0 -180
- package/dist/functions/templates/hono-typescript/src/context.ts +0 -103
- package/dist/functions/templates/hono-typescript/src/index.ts +0 -54
- package/dist/functions/templates/hono-typescript/src/middleware/appwrite.ts +0 -119
- package/dist/functions/templates/hono-typescript/tsconfig.json +0 -20
- package/dist/functions/templates/typescript-node/README.md +0 -32
- package/dist/functions/templates/typescript-node/package.json +0 -25
- package/dist/functions/templates/typescript-node/src/context.ts +0 -103
- package/dist/functions/templates/typescript-node/src/index.ts +0 -29
- package/dist/functions/templates/typescript-node/tsconfig.json +0 -28
- package/dist/functions/templates/uv/README.md +0 -31
- package/dist/functions/templates/uv/pyproject.toml +0 -30
- package/dist/functions/templates/uv/src/__init__.py +0 -0
- package/dist/functions/templates/uv/src/context.py +0 -125
- package/dist/functions/templates/uv/src/index.py +0 -46
- package/dist/init.d.ts +0 -2
- package/dist/init.js +0 -57
- package/dist/interactiveCLI.d.ts +0 -31
- package/dist/interactiveCLI.js +0 -898
- package/dist/main.d.ts +0 -2
- package/dist/main.js +0 -1180
- package/dist/migrations/afterImportActions.d.ts +0 -17
- package/dist/migrations/afterImportActions.js +0 -306
- package/dist/migrations/appwriteToX.d.ts +0 -211
- package/dist/migrations/appwriteToX.js +0 -491
- package/dist/migrations/comprehensiveTransfer.d.ts +0 -147
- package/dist/migrations/comprehensiveTransfer.js +0 -1317
- package/dist/migrations/dataLoader.d.ts +0 -753
- package/dist/migrations/dataLoader.js +0 -1250
- package/dist/migrations/importController.d.ts +0 -23
- package/dist/migrations/importController.js +0 -268
- package/dist/migrations/importDataActions.d.ts +0 -50
- package/dist/migrations/importDataActions.js +0 -230
- package/dist/migrations/relationships.d.ts +0 -29
- package/dist/migrations/relationships.js +0 -204
- package/dist/migrations/services/DataTransformationService.d.ts +0 -55
- package/dist/migrations/services/DataTransformationService.js +0 -158
- package/dist/migrations/services/FileHandlerService.d.ts +0 -75
- package/dist/migrations/services/FileHandlerService.js +0 -236
- package/dist/migrations/services/ImportOrchestrator.d.ts +0 -97
- package/dist/migrations/services/ImportOrchestrator.js +0 -485
- package/dist/migrations/services/RateLimitManager.d.ts +0 -138
- package/dist/migrations/services/RateLimitManager.js +0 -279
- package/dist/migrations/services/RelationshipResolver.d.ts +0 -120
- package/dist/migrations/services/RelationshipResolver.js +0 -332
- package/dist/migrations/services/UserMappingService.d.ts +0 -109
- package/dist/migrations/services/UserMappingService.js +0 -277
- package/dist/migrations/services/ValidationService.d.ts +0 -74
- package/dist/migrations/services/ValidationService.js +0 -260
- package/dist/migrations/transfer.d.ts +0 -26
- package/dist/migrations/transfer.js +0 -608
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +0 -131
- package/dist/migrations/yaml/YamlImportConfigLoader.js +0 -383
- package/dist/migrations/yaml/YamlImportIntegration.d.ts +0 -93
- package/dist/migrations/yaml/YamlImportIntegration.js +0 -341
- package/dist/migrations/yaml/generateImportSchemas.d.ts +0 -30
- package/dist/migrations/yaml/generateImportSchemas.js +0 -1327
- package/dist/schemas/authUser.d.ts +0 -24
- package/dist/schemas/authUser.js +0 -17
- package/dist/setup.d.ts +0 -2
- package/dist/setup.js +0 -5
- package/dist/setupCommands.d.ts +0 -58
- package/dist/setupCommands.js +0 -490
- package/dist/setupController.d.ts +0 -9
- package/dist/setupController.js +0 -34
- package/dist/shared/attributeMapper.d.ts +0 -20
- package/dist/shared/attributeMapper.js +0 -203
- package/dist/shared/backupMetadataSchema.d.ts +0 -94
- package/dist/shared/backupMetadataSchema.js +0 -38
- package/dist/shared/backupTracking.d.ts +0 -18
- package/dist/shared/backupTracking.js +0 -176
- package/dist/shared/confirmationDialogs.d.ts +0 -75
- package/dist/shared/confirmationDialogs.js +0 -236
- package/dist/shared/errorUtils.d.ts +0 -54
- package/dist/shared/errorUtils.js +0 -95
- package/dist/shared/functionManager.d.ts +0 -48
- package/dist/shared/functionManager.js +0 -348
- package/dist/shared/jsonSchemaGenerator.d.ts +0 -50
- package/dist/shared/jsonSchemaGenerator.js +0 -290
- package/dist/shared/logging.d.ts +0 -61
- package/dist/shared/logging.js +0 -116
- package/dist/shared/messageFormatter.d.ts +0 -39
- package/dist/shared/messageFormatter.js +0 -162
- package/dist/shared/migrationHelpers.d.ts +0 -61
- package/dist/shared/migrationHelpers.js +0 -145
- package/dist/shared/operationLogger.d.ts +0 -10
- package/dist/shared/operationLogger.js +0 -12
- package/dist/shared/operationQueue.d.ts +0 -40
- package/dist/shared/operationQueue.js +0 -311
- package/dist/shared/operationsTable.d.ts +0 -26
- package/dist/shared/operationsTable.js +0 -286
- package/dist/shared/operationsTableSchema.d.ts +0 -48
- package/dist/shared/operationsTableSchema.js +0 -35
- package/dist/shared/progressManager.d.ts +0 -62
- package/dist/shared/progressManager.js +0 -215
- package/dist/shared/pydanticModelGenerator.d.ts +0 -17
- package/dist/shared/pydanticModelGenerator.js +0 -615
- package/dist/shared/relationshipExtractor.d.ts +0 -56
- package/dist/shared/relationshipExtractor.js +0 -138
- package/dist/shared/schemaGenerator.d.ts +0 -40
- package/dist/shared/schemaGenerator.js +0 -556
- package/dist/shared/selectionDialogs.d.ts +0 -214
- package/dist/shared/selectionDialogs.js +0 -544
- package/dist/storage/backupCompression.d.ts +0 -20
- package/dist/storage/backupCompression.js +0 -67
- package/dist/storage/methods.d.ts +0 -32
- package/dist/storage/methods.js +0 -472
- package/dist/storage/schemas.d.ts +0 -842
- package/dist/storage/schemas.js +0 -175
- package/dist/tables/indexManager.d.ts +0 -65
- package/dist/tables/indexManager.js +0 -294
- package/dist/types.d.ts +0 -4
- package/dist/types.js +0 -3
- package/dist/users/methods.d.ts +0 -16
- package/dist/users/methods.js +0 -277
- package/dist/utils/ClientFactory.d.ts +0 -87
- package/dist/utils/ClientFactory.js +0 -212
- package/dist/utils/configDiscovery.d.ts +0 -78
- package/dist/utils/configDiscovery.js +0 -472
- package/dist/utils/configMigration.d.ts +0 -1
- package/dist/utils/configMigration.js +0 -261
- package/dist/utils/constantsGenerator.d.ts +0 -31
- package/dist/utils/constantsGenerator.js +0 -321
- package/dist/utils/dataConverters.d.ts +0 -46
- package/dist/utils/dataConverters.js +0 -139
- package/dist/utils/directoryUtils.d.ts +0 -22
- package/dist/utils/directoryUtils.js +0 -59
- package/dist/utils/getClientFromConfig.d.ts +0 -39
- package/dist/utils/getClientFromConfig.js +0 -199
- package/dist/utils/helperFunctions.d.ts +0 -63
- package/dist/utils/helperFunctions.js +0 -156
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -2
- package/dist/utils/loadConfigs.d.ts +0 -50
- package/dist/utils/loadConfigs.js +0 -358
- package/dist/utils/pathResolvers.d.ts +0 -53
- package/dist/utils/pathResolvers.js +0 -72
- package/dist/utils/projectConfig.d.ts +0 -122
- package/dist/utils/projectConfig.js +0 -206
- package/dist/utils/retryFailedPromises.d.ts +0 -2
- package/dist/utils/retryFailedPromises.js +0 -23
- package/dist/utils/sessionAuth.d.ts +0 -48
- package/dist/utils/sessionAuth.js +0 -164
- package/dist/utils/setupFiles.d.ts +0 -4
- package/dist/utils/setupFiles.js +0 -1192
- package/dist/utils/typeGuards.d.ts +0 -35
- package/dist/utils/typeGuards.js +0 -57
- package/dist/utils/validationRules.d.ts +0 -43
- package/dist/utils/validationRules.js +0 -42
- package/dist/utils/versionDetection.d.ts +0 -58
- package/dist/utils/versionDetection.js +0 -251
- package/dist/utils/yamlConverter.d.ts +0 -100
- package/dist/utils/yamlConverter.js +0 -428
- package/dist/utils/yamlLoader.d.ts +0 -70
- package/dist/utils/yamlLoader.js +0 -267
- package/dist/utilsController.d.ts +0 -107
- package/dist/utilsController.js +0 -873
- package/src/adapters/AdapterFactory.ts +0 -529
- package/src/adapters/DatabaseAdapter.ts +0 -319
- package/src/adapters/LegacyAdapter.ts +0 -844
- package/src/adapters/TablesDBAdapter.ts +0 -823
- package/src/config/ConfigManager.ts +0 -849
- package/src/config/README.md +0 -274
- package/src/config/configMigration.ts +0 -575
- package/src/config/configValidation.ts +0 -445
- package/src/config/index.ts +0 -10
- package/src/config/services/ConfigDiscoveryService.ts +0 -410
- package/src/config/services/ConfigLoaderService.ts +0 -732
- package/src/config/services/ConfigMergeService.ts +0 -388
- package/src/config/services/ConfigValidationService.ts +0 -394
- package/src/config/services/SessionAuthService.ts +0 -565
- package/src/config/services/__tests__/ConfigMergeService.test.ts +0 -351
- package/src/config/services/index.ts +0 -29
- package/src/config/yamlConfig.ts +0 -761
- package/src/functions/pathResolution.ts +0 -227
- package/src/functions/templates/count-docs-in-collection/package.json +0 -25
- package/src/functions/templates/count-docs-in-collection/tsconfig.json +0 -28
- package/src/functions/templates/hono-typescript/package.json +0 -26
- package/src/functions/templates/hono-typescript/tsconfig.json +0 -20
- package/src/functions/templates/typescript-node/package.json +0 -25
- package/src/functions/templates/typescript-node/tsconfig.json +0 -28
- package/src/shared/attributeMapper.ts +0 -229
- package/src/shared/errorUtils.ts +0 -110
- package/src/shared/functionManager.ts +0 -537
- package/src/shared/jsonSchemaGenerator.ts +0 -383
- package/src/shared/logging.ts +0 -149
- package/src/shared/messageFormatter.ts +0 -208
- package/src/shared/pydanticModelGenerator.ts +0 -618
- package/src/shared/schemaGenerator.ts +0 -644
- package/src/utils/ClientFactory.ts +0 -240
- package/src/utils/configDiscovery.ts +0 -557
- package/src/utils/constantsGenerator.ts +0 -369
- package/src/utils/dataConverters.ts +0 -159
- package/src/utils/directoryUtils.ts +0 -61
- package/src/utils/getClientFromConfig.ts +0 -257
- package/src/utils/helperFunctions.ts +0 -228
- package/src/utils/pathResolvers.ts +0 -81
- package/src/utils/projectConfig.ts +0 -340
- package/src/utils/retryFailedPromises.ts +0 -29
- package/src/utils/sessionAuth.ts +0 -230
- package/src/utils/typeGuards.ts +0 -65
- package/src/utils/validationRules.ts +0 -88
- package/src/utils/versionDetection.ts +0 -292
- package/src/utils/yamlConverter.ts +0 -542
- package/src/utils/yamlLoader.ts +0 -371
- package/tmp-sync-test/.appwrite/collections/TestCollection.yaml +0 -7
|
@@ -1,352 +1,352 @@
|
|
|
1
|
-
import type { DatabaseAdapter } from
|
|
2
|
-
import { logger } from
|
|
3
|
-
import { tryAwaitWithRetry } from "
|
|
4
|
-
import { Query, ID } from "node-appwrite";
|
|
5
|
-
import {
|
|
6
|
-
BACKUP_TABLE_ID,
|
|
7
|
-
BACKUP_TABLE_NAME,
|
|
8
|
-
type BackupMetadata,
|
|
9
|
-
type BackupType,
|
|
10
|
-
BackupMetadataSchema
|
|
11
|
-
} from "../../shared/backupMetadataSchema.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Centralized backup tracking system
|
|
15
|
-
*
|
|
16
|
-
* All backups (databases, buckets, comprehensive) are tracked in a single
|
|
17
|
-
* database selected by the user, providing a centralized backup registry.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Checks if backup tracking table exists in database
|
|
22
|
-
*/
|
|
23
|
-
async function tableExists(
|
|
24
|
-
db: DatabaseAdapter,
|
|
25
|
-
databaseId: string
|
|
26
|
-
): Promise<boolean> {
|
|
27
|
-
try {
|
|
28
|
-
await db.getTable({ databaseId, tableId: BACKUP_TABLE_ID });
|
|
29
|
-
return true;
|
|
30
|
-
} catch (error) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Creates the centralized backup tracking table with enhanced schema
|
|
37
|
-
*/
|
|
38
|
-
export async function createCentralizedBackupTrackingTable(
|
|
39
|
-
db: DatabaseAdapter,
|
|
40
|
-
databaseId: string
|
|
41
|
-
): Promise<void> {
|
|
42
|
-
// Check if table already exists
|
|
43
|
-
const exists = await tableExists(db, databaseId);
|
|
44
|
-
|
|
45
|
-
if (exists) {
|
|
46
|
-
// Table exists - validate its schema
|
|
47
|
-
try {
|
|
48
|
-
const tableData = await db.getTable({ databaseId, tableId: BACKUP_TABLE_ID });
|
|
49
|
-
const existingAttrs = ((tableData.data as any).attributes || []);
|
|
50
|
-
|
|
51
|
-
// Expected attribute keys from our schema
|
|
52
|
-
const expectedAttrKeys = [
|
|
53
|
-
"backupType", "backupId", "manifestFileId", "format", "sizeBytes",
|
|
54
|
-
"databaseId", "bucketId", "comprehensiveBackupId",
|
|
55
|
-
"collections", "documents", "fileCount",
|
|
56
|
-
"status", "error",
|
|
57
|
-
"restoredAt", "restorationStatus", "restorationError"
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
// Existing attribute keys
|
|
61
|
-
const existingAttrKeys = new Set(existingAttrs.map((a: any) => a.key));
|
|
62
|
-
|
|
63
|
-
// Check if they match
|
|
64
|
-
const hasAllAttributes = expectedAttrKeys.every(key => existingAttrKeys.has(key));
|
|
65
|
-
|
|
66
|
-
// Check if any have wrong sizes (old 10000 vs new 1000)
|
|
67
|
-
const hasWrongSizes = existingAttrs.some((a: any) =>
|
|
68
|
-
(a.key === 'error' || a.key === 'restorationError') && a.size === 10000
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
if (!hasAllAttributes || hasWrongSizes) {
|
|
72
|
-
logger.warn("Backup table exists but has incorrect schema - recreating", {
|
|
73
|
-
tableId: BACKUP_TABLE_ID,
|
|
74
|
-
hasAllAttributes,
|
|
75
|
-
hasWrongSizes,
|
|
76
|
-
existingCount: existingAttrKeys.size,
|
|
77
|
-
expectedCount: expectedAttrKeys.length
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Delete the old table
|
|
81
|
-
await db.deleteTable({ databaseId, tableId: BACKUP_TABLE_ID });
|
|
82
|
-
|
|
83
|
-
logger.info("Old backup table deleted, will recreate with correct schema");
|
|
84
|
-
} else {
|
|
85
|
-
logger.debug("Backup table exists with correct schema", {
|
|
86
|
-
tableId: BACKUP_TABLE_ID,
|
|
87
|
-
attributeCount: existingAttrKeys.size
|
|
88
|
-
});
|
|
89
|
-
return; // Table is good, no need to recreate
|
|
90
|
-
}
|
|
91
|
-
} catch (error) {
|
|
92
|
-
// Error checking table - continue to create
|
|
93
|
-
logger.debug("Error checking existing table, will attempt to create", {
|
|
94
|
-
error: error instanceof Error ? error.message : String(error)
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Create table (either first time or after deletion)
|
|
100
|
-
logger.info("Creating centralized backup tracking table", {
|
|
101
|
-
databaseId,
|
|
102
|
-
tableId: BACKUP_TABLE_ID
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
await tryAwaitWithRetry(async () => {
|
|
106
|
-
await db.createTable({
|
|
107
|
-
databaseId,
|
|
108
|
-
id: BACKUP_TABLE_ID,
|
|
109
|
-
name: BACKUP_TABLE_NAME,
|
|
110
|
-
permissions: [],
|
|
111
|
-
documentSecurity: false,
|
|
112
|
-
enabled: true
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Define all attributes for the enhanced schema
|
|
117
|
-
const attributes = [
|
|
118
|
-
// Core backup info
|
|
119
|
-
{ key: "backupType", type: "enum" as const, elements: ["database", "bucket", "comprehensive"], required: true },
|
|
120
|
-
{ key: "backupId", type: "string" as const, size: 50, required: true },
|
|
121
|
-
{ key: "manifestFileId", type: "string" as const, size: 50, required: false },
|
|
122
|
-
{ key: "format", type: "enum" as const, elements: ["json", "zip"], required: true },
|
|
123
|
-
{ key: "sizeBytes", type: "integer" as const, required: true },
|
|
124
|
-
|
|
125
|
-
// Resource identification (optional, at least one present based on type)
|
|
126
|
-
{ key: "databaseId", type: "string" as const, size: 50, required: false },
|
|
127
|
-
{ key: "bucketId", type: "string" as const, size: 50, required: false },
|
|
128
|
-
{ key: "comprehensiveBackupId", type: "string" as const, size: 50, required: false },
|
|
129
|
-
|
|
130
|
-
// Database-specific metrics
|
|
131
|
-
{ key: "collections", type: "integer" as const, required: false },
|
|
132
|
-
{ key: "documents", type: "integer" as const, required: false },
|
|
133
|
-
|
|
134
|
-
// Bucket-specific metrics
|
|
135
|
-
{ key: "fileCount", type: "integer" as const, required: false },
|
|
136
|
-
|
|
137
|
-
// Status tracking
|
|
138
|
-
{ key: "status", type: "enum" as const, elements: ["completed", "partial", "failed"], required: true },
|
|
139
|
-
{ key: "error", type: "string" as const, size: 1000, required: false },
|
|
140
|
-
|
|
141
|
-
// Restoration tracking
|
|
142
|
-
{ key: "restoredAt", type: "string" as const, size: 50, required: false },
|
|
143
|
-
{ key: "restorationStatus", type: "enum" as const, elements: ["completed", "partial", "failed", "not_restored"], required: false },
|
|
144
|
-
{ key: "restorationError", type: "string" as const, size: 1000, required: false }
|
|
145
|
-
];
|
|
146
|
-
|
|
147
|
-
// Create each attribute with retry logic
|
|
148
|
-
// No need to check for existing attributes - table is freshly created or validated above
|
|
149
|
-
for (const attr of attributes) {
|
|
150
|
-
await tryAwaitWithRetry(async () => {
|
|
151
|
-
await db.createAttribute({
|
|
152
|
-
databaseId,
|
|
153
|
-
tableId: BACKUP_TABLE_ID,
|
|
154
|
-
...attr
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
logger.info("Centralized backup tracking table created successfully", {
|
|
160
|
-
databaseId,
|
|
161
|
-
tableId: BACKUP_TABLE_ID,
|
|
162
|
-
attributeCount: attributes.length
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Records backup metadata in the centralized tracking table
|
|
168
|
-
*/
|
|
169
|
-
export async function recordCentralizedBackup(
|
|
170
|
-
db: DatabaseAdapter,
|
|
171
|
-
trackingDatabaseId: string,
|
|
172
|
-
metadata: Omit<BackupMetadata, '$id' | '$createdAt' | '$updatedAt'>
|
|
173
|
-
): Promise<BackupMetadata> {
|
|
174
|
-
// Ensure tracking table exists with correct schema
|
|
175
|
-
await createCentralizedBackupTrackingTable(db, trackingDatabaseId);
|
|
176
|
-
|
|
177
|
-
// Create backup record with all fields
|
|
178
|
-
// Table is guaranteed to have all attributes after createCentralizedBackupTrackingTable
|
|
179
|
-
const result = await db.createRow({
|
|
180
|
-
databaseId: trackingDatabaseId,
|
|
181
|
-
tableId: BACKUP_TABLE_ID,
|
|
182
|
-
id: ID.unique(),
|
|
183
|
-
data: {
|
|
184
|
-
// Core fields
|
|
185
|
-
backupType: metadata.backupType,
|
|
186
|
-
backupId: metadata.backupId,
|
|
187
|
-
manifestFileId: metadata.manifestFileId || null,
|
|
188
|
-
format: metadata.format,
|
|
189
|
-
sizeBytes: metadata.sizeBytes,
|
|
190
|
-
|
|
191
|
-
// Resource identification
|
|
192
|
-
databaseId: metadata.databaseId || null,
|
|
193
|
-
bucketId: metadata.bucketId || null,
|
|
194
|
-
comprehensiveBackupId: metadata.comprehensiveBackupId || null,
|
|
195
|
-
|
|
196
|
-
// Metrics
|
|
197
|
-
collections: metadata.collections || null,
|
|
198
|
-
documents: metadata.documents || null,
|
|
199
|
-
fileCount: metadata.fileCount || null,
|
|
200
|
-
|
|
201
|
-
// Status
|
|
202
|
-
status: metadata.status,
|
|
203
|
-
error: metadata.error || null,
|
|
204
|
-
|
|
205
|
-
// Restoration
|
|
206
|
-
restoredAt: metadata.restoredAt || null,
|
|
207
|
-
restorationStatus: metadata.restorationStatus || 'not_restored',
|
|
208
|
-
restorationError: metadata.restorationError || null
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
logger.info("Recorded centralized backup metadata", {
|
|
213
|
-
backupType: metadata.backupType,
|
|
214
|
-
backupId: metadata.backupId,
|
|
215
|
-
trackingDatabaseId
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return result.data as BackupMetadata;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Lists all backups of a specific type, sorted by creation date (newest first)
|
|
223
|
-
*/
|
|
224
|
-
export async function listCentralizedBackups(
|
|
225
|
-
db: DatabaseAdapter,
|
|
226
|
-
trackingDatabaseId: string,
|
|
227
|
-
options?: {
|
|
228
|
-
backupType?: BackupType;
|
|
229
|
-
resourceId?: string; // databaseId or bucketId
|
|
230
|
-
limit?: number;
|
|
231
|
-
}
|
|
232
|
-
): Promise<BackupMetadata[]> {
|
|
233
|
-
try {
|
|
234
|
-
const queries: string[] = [
|
|
235
|
-
Query.orderDesc("$createdAt"),
|
|
236
|
-
Query.limit(options?.limit || 100)
|
|
237
|
-
];
|
|
238
|
-
|
|
239
|
-
// Filter by backup type if specified
|
|
240
|
-
if (options?.backupType) {
|
|
241
|
-
queries.push(Query.equal("backupType", options.backupType));
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Filter by resource ID if specified
|
|
245
|
-
if (options?.resourceId) {
|
|
246
|
-
if (options.backupType === 'database') {
|
|
247
|
-
queries.push(Query.equal("databaseId", options.resourceId));
|
|
248
|
-
} else if (options.backupType === 'bucket') {
|
|
249
|
-
queries.push(Query.equal("bucketId", options.resourceId));
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const result = await db.listRows({
|
|
254
|
-
databaseId: trackingDatabaseId,
|
|
255
|
-
tableId: BACKUP_TABLE_ID,
|
|
256
|
-
queries
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
return (result.rows || []) as BackupMetadata[];
|
|
260
|
-
} catch (error) {
|
|
261
|
-
logger.debug("No centralized backup tracking table found", { trackingDatabaseId });
|
|
262
|
-
return [];
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Gets a specific backup by its backup file ID
|
|
268
|
-
*/
|
|
269
|
-
export async function getCentralizedBackup(
|
|
270
|
-
db: DatabaseAdapter,
|
|
271
|
-
trackingDatabaseId: string,
|
|
272
|
-
backupId: string
|
|
273
|
-
): Promise<BackupMetadata | null> {
|
|
274
|
-
try {
|
|
275
|
-
const result = await db.listRows({
|
|
276
|
-
databaseId: trackingDatabaseId,
|
|
277
|
-
tableId: BACKUP_TABLE_ID,
|
|
278
|
-
queries: [
|
|
279
|
-
Query.equal("backupId", backupId),
|
|
280
|
-
Query.limit(1)
|
|
281
|
-
]
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
if (result.rows && result.rows.length > 0) {
|
|
285
|
-
return result.rows[0] as BackupMetadata;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return null;
|
|
289
|
-
} catch (error) {
|
|
290
|
-
logger.debug("Backup not found", { backupId, trackingDatabaseId });
|
|
291
|
-
return null;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Updates restoration status for a backup
|
|
297
|
-
*/
|
|
298
|
-
export async function updateRestorationStatus(
|
|
299
|
-
db: DatabaseAdapter,
|
|
300
|
-
trackingDatabaseId: string,
|
|
301
|
-
backupRecordId: string,
|
|
302
|
-
restorationData: {
|
|
303
|
-
restoredAt: string;
|
|
304
|
-
restorationStatus: 'completed' | 'partial' | 'failed';
|
|
305
|
-
restorationError?: string;
|
|
306
|
-
}
|
|
307
|
-
): Promise<void> {
|
|
308
|
-
await db.updateRow({
|
|
309
|
-
databaseId: trackingDatabaseId,
|
|
310
|
-
tableId: BACKUP_TABLE_ID,
|
|
311
|
-
id: backupRecordId,
|
|
312
|
-
data: {
|
|
313
|
-
restoredAt: restorationData.restoredAt,
|
|
314
|
-
restorationStatus: restorationData.restorationStatus,
|
|
315
|
-
restorationError: restorationData.restorationError || null
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
logger.info("Updated restoration status", {
|
|
320
|
-
backupRecordId,
|
|
321
|
-
restorationStatus: restorationData.restorationStatus
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Gets the most recent comprehensive backup
|
|
327
|
-
*/
|
|
328
|
-
export async function getLastComprehensiveBackup(
|
|
329
|
-
db: DatabaseAdapter,
|
|
330
|
-
trackingDatabaseId: string
|
|
331
|
-
): Promise<BackupMetadata | null> {
|
|
332
|
-
try {
|
|
333
|
-
const result = await db.listRows({
|
|
334
|
-
databaseId: trackingDatabaseId,
|
|
335
|
-
tableId: BACKUP_TABLE_ID,
|
|
336
|
-
queries: [
|
|
337
|
-
Query.equal("backupType", "comprehensive"),
|
|
338
|
-
Query.orderDesc("$createdAt"),
|
|
339
|
-
Query.limit(1)
|
|
340
|
-
]
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
if (result.rows && result.rows.length > 0) {
|
|
344
|
-
return result.rows[0] as BackupMetadata;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return null;
|
|
348
|
-
} catch (error) {
|
|
349
|
-
logger.debug("No comprehensive backup found", { trackingDatabaseId });
|
|
350
|
-
return null;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
1
|
+
import type { DatabaseAdapter } from 'appwrite-utils-helpers';
|
|
2
|
+
import { logger } from 'appwrite-utils-helpers';
|
|
3
|
+
import { tryAwaitWithRetry } from "appwrite-utils-helpers";
|
|
4
|
+
import { Query, ID } from "node-appwrite";
|
|
5
|
+
import {
|
|
6
|
+
BACKUP_TABLE_ID,
|
|
7
|
+
BACKUP_TABLE_NAME,
|
|
8
|
+
type BackupMetadata,
|
|
9
|
+
type BackupType,
|
|
10
|
+
BackupMetadataSchema
|
|
11
|
+
} from "../../shared/backupMetadataSchema.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Centralized backup tracking system
|
|
15
|
+
*
|
|
16
|
+
* All backups (databases, buckets, comprehensive) are tracked in a single
|
|
17
|
+
* database selected by the user, providing a centralized backup registry.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Checks if backup tracking table exists in database
|
|
22
|
+
*/
|
|
23
|
+
async function tableExists(
|
|
24
|
+
db: DatabaseAdapter,
|
|
25
|
+
databaseId: string
|
|
26
|
+
): Promise<boolean> {
|
|
27
|
+
try {
|
|
28
|
+
await db.getTable({ databaseId, tableId: BACKUP_TABLE_ID });
|
|
29
|
+
return true;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Creates the centralized backup tracking table with enhanced schema
|
|
37
|
+
*/
|
|
38
|
+
export async function createCentralizedBackupTrackingTable(
|
|
39
|
+
db: DatabaseAdapter,
|
|
40
|
+
databaseId: string
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
// Check if table already exists
|
|
43
|
+
const exists = await tableExists(db, databaseId);
|
|
44
|
+
|
|
45
|
+
if (exists) {
|
|
46
|
+
// Table exists - validate its schema
|
|
47
|
+
try {
|
|
48
|
+
const tableData = await db.getTable({ databaseId, tableId: BACKUP_TABLE_ID });
|
|
49
|
+
const existingAttrs = ((tableData.data as any).attributes || []);
|
|
50
|
+
|
|
51
|
+
// Expected attribute keys from our schema
|
|
52
|
+
const expectedAttrKeys = [
|
|
53
|
+
"backupType", "backupId", "manifestFileId", "format", "sizeBytes",
|
|
54
|
+
"databaseId", "bucketId", "comprehensiveBackupId",
|
|
55
|
+
"collections", "documents", "fileCount",
|
|
56
|
+
"status", "error",
|
|
57
|
+
"restoredAt", "restorationStatus", "restorationError"
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
// Existing attribute keys
|
|
61
|
+
const existingAttrKeys = new Set(existingAttrs.map((a: any) => a.key));
|
|
62
|
+
|
|
63
|
+
// Check if they match
|
|
64
|
+
const hasAllAttributes = expectedAttrKeys.every(key => existingAttrKeys.has(key));
|
|
65
|
+
|
|
66
|
+
// Check if any have wrong sizes (old 10000 vs new 1000)
|
|
67
|
+
const hasWrongSizes = existingAttrs.some((a: any) =>
|
|
68
|
+
(a.key === 'error' || a.key === 'restorationError') && a.size === 10000
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!hasAllAttributes || hasWrongSizes) {
|
|
72
|
+
logger.warn("Backup table exists but has incorrect schema - recreating", {
|
|
73
|
+
tableId: BACKUP_TABLE_ID,
|
|
74
|
+
hasAllAttributes,
|
|
75
|
+
hasWrongSizes,
|
|
76
|
+
existingCount: existingAttrKeys.size,
|
|
77
|
+
expectedCount: expectedAttrKeys.length
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Delete the old table
|
|
81
|
+
await db.deleteTable({ databaseId, tableId: BACKUP_TABLE_ID });
|
|
82
|
+
|
|
83
|
+
logger.info("Old backup table deleted, will recreate with correct schema");
|
|
84
|
+
} else {
|
|
85
|
+
logger.debug("Backup table exists with correct schema", {
|
|
86
|
+
tableId: BACKUP_TABLE_ID,
|
|
87
|
+
attributeCount: existingAttrKeys.size
|
|
88
|
+
});
|
|
89
|
+
return; // Table is good, no need to recreate
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
// Error checking table - continue to create
|
|
93
|
+
logger.debug("Error checking existing table, will attempt to create", {
|
|
94
|
+
error: error instanceof Error ? error.message : String(error)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Create table (either first time or after deletion)
|
|
100
|
+
logger.info("Creating centralized backup tracking table", {
|
|
101
|
+
databaseId,
|
|
102
|
+
tableId: BACKUP_TABLE_ID
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await tryAwaitWithRetry(async () => {
|
|
106
|
+
await db.createTable({
|
|
107
|
+
databaseId,
|
|
108
|
+
id: BACKUP_TABLE_ID,
|
|
109
|
+
name: BACKUP_TABLE_NAME,
|
|
110
|
+
permissions: [],
|
|
111
|
+
documentSecurity: false,
|
|
112
|
+
enabled: true
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Define all attributes for the enhanced schema
|
|
117
|
+
const attributes = [
|
|
118
|
+
// Core backup info
|
|
119
|
+
{ key: "backupType", type: "enum" as const, elements: ["database", "bucket", "comprehensive"], required: true },
|
|
120
|
+
{ key: "backupId", type: "string" as const, size: 50, required: true },
|
|
121
|
+
{ key: "manifestFileId", type: "string" as const, size: 50, required: false },
|
|
122
|
+
{ key: "format", type: "enum" as const, elements: ["json", "zip"], required: true },
|
|
123
|
+
{ key: "sizeBytes", type: "integer" as const, required: true },
|
|
124
|
+
|
|
125
|
+
// Resource identification (optional, at least one present based on type)
|
|
126
|
+
{ key: "databaseId", type: "string" as const, size: 50, required: false },
|
|
127
|
+
{ key: "bucketId", type: "string" as const, size: 50, required: false },
|
|
128
|
+
{ key: "comprehensiveBackupId", type: "string" as const, size: 50, required: false },
|
|
129
|
+
|
|
130
|
+
// Database-specific metrics
|
|
131
|
+
{ key: "collections", type: "integer" as const, required: false },
|
|
132
|
+
{ key: "documents", type: "integer" as const, required: false },
|
|
133
|
+
|
|
134
|
+
// Bucket-specific metrics
|
|
135
|
+
{ key: "fileCount", type: "integer" as const, required: false },
|
|
136
|
+
|
|
137
|
+
// Status tracking
|
|
138
|
+
{ key: "status", type: "enum" as const, elements: ["completed", "partial", "failed"], required: true },
|
|
139
|
+
{ key: "error", type: "string" as const, size: 1000, required: false },
|
|
140
|
+
|
|
141
|
+
// Restoration tracking
|
|
142
|
+
{ key: "restoredAt", type: "string" as const, size: 50, required: false },
|
|
143
|
+
{ key: "restorationStatus", type: "enum" as const, elements: ["completed", "partial", "failed", "not_restored"], required: false },
|
|
144
|
+
{ key: "restorationError", type: "string" as const, size: 1000, required: false }
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
// Create each attribute with retry logic
|
|
148
|
+
// No need to check for existing attributes - table is freshly created or validated above
|
|
149
|
+
for (const attr of attributes) {
|
|
150
|
+
await tryAwaitWithRetry(async () => {
|
|
151
|
+
await db.createAttribute({
|
|
152
|
+
databaseId,
|
|
153
|
+
tableId: BACKUP_TABLE_ID,
|
|
154
|
+
...attr
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
logger.info("Centralized backup tracking table created successfully", {
|
|
160
|
+
databaseId,
|
|
161
|
+
tableId: BACKUP_TABLE_ID,
|
|
162
|
+
attributeCount: attributes.length
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Records backup metadata in the centralized tracking table
|
|
168
|
+
*/
|
|
169
|
+
export async function recordCentralizedBackup(
|
|
170
|
+
db: DatabaseAdapter,
|
|
171
|
+
trackingDatabaseId: string,
|
|
172
|
+
metadata: Omit<BackupMetadata, '$id' | '$createdAt' | '$updatedAt'>
|
|
173
|
+
): Promise<BackupMetadata> {
|
|
174
|
+
// Ensure tracking table exists with correct schema
|
|
175
|
+
await createCentralizedBackupTrackingTable(db, trackingDatabaseId);
|
|
176
|
+
|
|
177
|
+
// Create backup record with all fields
|
|
178
|
+
// Table is guaranteed to have all attributes after createCentralizedBackupTrackingTable
|
|
179
|
+
const result = await db.createRow({
|
|
180
|
+
databaseId: trackingDatabaseId,
|
|
181
|
+
tableId: BACKUP_TABLE_ID,
|
|
182
|
+
id: ID.unique(),
|
|
183
|
+
data: {
|
|
184
|
+
// Core fields
|
|
185
|
+
backupType: metadata.backupType,
|
|
186
|
+
backupId: metadata.backupId,
|
|
187
|
+
manifestFileId: metadata.manifestFileId || null,
|
|
188
|
+
format: metadata.format,
|
|
189
|
+
sizeBytes: metadata.sizeBytes,
|
|
190
|
+
|
|
191
|
+
// Resource identification
|
|
192
|
+
databaseId: metadata.databaseId || null,
|
|
193
|
+
bucketId: metadata.bucketId || null,
|
|
194
|
+
comprehensiveBackupId: metadata.comprehensiveBackupId || null,
|
|
195
|
+
|
|
196
|
+
// Metrics
|
|
197
|
+
collections: metadata.collections || null,
|
|
198
|
+
documents: metadata.documents || null,
|
|
199
|
+
fileCount: metadata.fileCount || null,
|
|
200
|
+
|
|
201
|
+
// Status
|
|
202
|
+
status: metadata.status,
|
|
203
|
+
error: metadata.error || null,
|
|
204
|
+
|
|
205
|
+
// Restoration
|
|
206
|
+
restoredAt: metadata.restoredAt || null,
|
|
207
|
+
restorationStatus: metadata.restorationStatus || 'not_restored',
|
|
208
|
+
restorationError: metadata.restorationError || null
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
logger.info("Recorded centralized backup metadata", {
|
|
213
|
+
backupType: metadata.backupType,
|
|
214
|
+
backupId: metadata.backupId,
|
|
215
|
+
trackingDatabaseId
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
return result.data as BackupMetadata;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Lists all backups of a specific type, sorted by creation date (newest first)
|
|
223
|
+
*/
|
|
224
|
+
export async function listCentralizedBackups(
|
|
225
|
+
db: DatabaseAdapter,
|
|
226
|
+
trackingDatabaseId: string,
|
|
227
|
+
options?: {
|
|
228
|
+
backupType?: BackupType;
|
|
229
|
+
resourceId?: string; // databaseId or bucketId
|
|
230
|
+
limit?: number;
|
|
231
|
+
}
|
|
232
|
+
): Promise<BackupMetadata[]> {
|
|
233
|
+
try {
|
|
234
|
+
const queries: string[] = [
|
|
235
|
+
Query.orderDesc("$createdAt"),
|
|
236
|
+
Query.limit(options?.limit || 100)
|
|
237
|
+
];
|
|
238
|
+
|
|
239
|
+
// Filter by backup type if specified
|
|
240
|
+
if (options?.backupType) {
|
|
241
|
+
queries.push(Query.equal("backupType", options.backupType));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Filter by resource ID if specified
|
|
245
|
+
if (options?.resourceId) {
|
|
246
|
+
if (options.backupType === 'database') {
|
|
247
|
+
queries.push(Query.equal("databaseId", options.resourceId));
|
|
248
|
+
} else if (options.backupType === 'bucket') {
|
|
249
|
+
queries.push(Query.equal("bucketId", options.resourceId));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const result = await db.listRows({
|
|
254
|
+
databaseId: trackingDatabaseId,
|
|
255
|
+
tableId: BACKUP_TABLE_ID,
|
|
256
|
+
queries
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
return (result.rows || []) as BackupMetadata[];
|
|
260
|
+
} catch (error) {
|
|
261
|
+
logger.debug("No centralized backup tracking table found", { trackingDatabaseId });
|
|
262
|
+
return [];
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Gets a specific backup by its backup file ID
|
|
268
|
+
*/
|
|
269
|
+
export async function getCentralizedBackup(
|
|
270
|
+
db: DatabaseAdapter,
|
|
271
|
+
trackingDatabaseId: string,
|
|
272
|
+
backupId: string
|
|
273
|
+
): Promise<BackupMetadata | null> {
|
|
274
|
+
try {
|
|
275
|
+
const result = await db.listRows({
|
|
276
|
+
databaseId: trackingDatabaseId,
|
|
277
|
+
tableId: BACKUP_TABLE_ID,
|
|
278
|
+
queries: [
|
|
279
|
+
Query.equal("backupId", backupId),
|
|
280
|
+
Query.limit(1)
|
|
281
|
+
]
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
if (result.rows && result.rows.length > 0) {
|
|
285
|
+
return result.rows[0] as BackupMetadata;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return null;
|
|
289
|
+
} catch (error) {
|
|
290
|
+
logger.debug("Backup not found", { backupId, trackingDatabaseId });
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Updates restoration status for a backup
|
|
297
|
+
*/
|
|
298
|
+
export async function updateRestorationStatus(
|
|
299
|
+
db: DatabaseAdapter,
|
|
300
|
+
trackingDatabaseId: string,
|
|
301
|
+
backupRecordId: string,
|
|
302
|
+
restorationData: {
|
|
303
|
+
restoredAt: string;
|
|
304
|
+
restorationStatus: 'completed' | 'partial' | 'failed';
|
|
305
|
+
restorationError?: string;
|
|
306
|
+
}
|
|
307
|
+
): Promise<void> {
|
|
308
|
+
await db.updateRow({
|
|
309
|
+
databaseId: trackingDatabaseId,
|
|
310
|
+
tableId: BACKUP_TABLE_ID,
|
|
311
|
+
id: backupRecordId,
|
|
312
|
+
data: {
|
|
313
|
+
restoredAt: restorationData.restoredAt,
|
|
314
|
+
restorationStatus: restorationData.restorationStatus,
|
|
315
|
+
restorationError: restorationData.restorationError || null
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
logger.info("Updated restoration status", {
|
|
320
|
+
backupRecordId,
|
|
321
|
+
restorationStatus: restorationData.restorationStatus
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Gets the most recent comprehensive backup
|
|
327
|
+
*/
|
|
328
|
+
export async function getLastComprehensiveBackup(
|
|
329
|
+
db: DatabaseAdapter,
|
|
330
|
+
trackingDatabaseId: string
|
|
331
|
+
): Promise<BackupMetadata | null> {
|
|
332
|
+
try {
|
|
333
|
+
const result = await db.listRows({
|
|
334
|
+
databaseId: trackingDatabaseId,
|
|
335
|
+
tableId: BACKUP_TABLE_ID,
|
|
336
|
+
queries: [
|
|
337
|
+
Query.equal("backupType", "comprehensive"),
|
|
338
|
+
Query.orderDesc("$createdAt"),
|
|
339
|
+
Query.limit(1)
|
|
340
|
+
]
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
if (result.rows && result.rows.length > 0) {
|
|
344
|
+
return result.rows[0] as BackupMetadata;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return null;
|
|
348
|
+
} catch (error) {
|
|
349
|
+
logger.debug("No comprehensive backup found", { trackingDatabaseId });
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
}
|