appwrite-utils-cli 1.0.7 → 1.0.9
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/README.md +116 -0
- package/dist/interactiveCLI.d.ts +1 -0
- package/dist/interactiveCLI.js +171 -4
- package/dist/migrations/comprehensiveTransfer.d.ts +66 -0
- package/dist/migrations/comprehensiveTransfer.js +366 -0
- package/dist/migrations/transfer.js +82 -13
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +4 -4
- package/package.json +1 -1
- package/src/interactiveCLI.ts +182 -4
- package/src/migrations/comprehensiveTransfer.ts +505 -0
- package/src/migrations/transfer.ts +180 -22
package/README.md
CHANGED
@@ -327,6 +327,122 @@ This updated CLI ensures that developers have robust tools at their fingertips t
|
|
327
327
|
|
328
328
|
## Changelog
|
329
329
|
|
330
|
+
### 1.0.9 - Enhanced User Transfer with Password Preservation
|
331
|
+
|
332
|
+
**🔐 Complete Password Hash Preservation During User Transfers**
|
333
|
+
|
334
|
+
#### Password Hash Support
|
335
|
+
- **Universal Hash Support**: Support for all Appwrite password hash types:
|
336
|
+
- **Argon2**: Modern default hashing (preserved)
|
337
|
+
- **Bcrypt**: Industry standard (preserved)
|
338
|
+
- **Scrypt**: Memory-hard function with custom parameters (preserved)
|
339
|
+
- **Scrypt Modified**: Firebase-style with salt/separator/signer (preserved)
|
340
|
+
- **MD5**: Legacy support (preserved)
|
341
|
+
- **SHA variants**: SHA1, SHA256, SHA512 (preserved)
|
342
|
+
- **PHPass**: WordPress-style hashing (preserved)
|
343
|
+
- **Dynamic Hash Detection**: Automatically detects and uses correct hash creation method
|
344
|
+
- **Parameter Preservation**: Maintains hash-specific parameters (salt, iterations, memory cost, etc.)
|
345
|
+
|
346
|
+
#### Enhanced User Transfer Logic
|
347
|
+
- **Smart Password Recreation**: Uses appropriate `create*User` method based on detected hash type
|
348
|
+
- **Fallback Mechanism**: Graceful fallback to temporary passwords if hash recreation fails
|
349
|
+
- **Hash Options Support**: Preserves algorithm-specific configuration from `hashOptions`
|
350
|
+
- **Detailed Logging**: Clear success/failure messages with hash type information
|
351
|
+
|
352
|
+
#### User Experience Improvements
|
353
|
+
- **Accurate Information**: Updated CLI messaging to reflect actual password preservation capabilities
|
354
|
+
- **Clear Expectations**: Distinguishes between users who keep passwords vs. those who need reset
|
355
|
+
- **Success Feedback**: Detailed reporting of password preservation success rate
|
356
|
+
- **Risk Assessment**: Proper warnings only for users who will lose passwords
|
357
|
+
|
358
|
+
#### Technical Implementation
|
359
|
+
- **Hash Type Detection**: `user.hash` field determines creation method
|
360
|
+
- **Configuration Parsing**: `user.hashOptions` provides algorithm parameters
|
361
|
+
- **Error Resilience**: Comprehensive try-catch with fallback to temporary passwords
|
362
|
+
- **Type Safety**: Proper handling of hash option types and parameters
|
363
|
+
|
364
|
+
#### Migration Benefits
|
365
|
+
- **Seamless Login**: Users with preserved hashes can immediately log in with original passwords
|
366
|
+
- **Reduced Support**: Dramatically fewer password reset requests after migration
|
367
|
+
- **Complete Fidelity**: Maintains original security posture and hash strength
|
368
|
+
- **Production Ready**: Safe for live user base migrations
|
369
|
+
|
370
|
+
#### Usage Examples
|
371
|
+
```bash
|
372
|
+
# Users will now preserve passwords during comprehensive transfer
|
373
|
+
npx appwrite-utils-cli@latest appwrite-migrate --it
|
374
|
+
# Select: 🚀 Comprehensive transfer (users → databases → buckets → functions)
|
375
|
+
|
376
|
+
# Example output:
|
377
|
+
# ✅ User 123 created with preserved argon2 password
|
378
|
+
# ✅ User 456 created with preserved bcrypt password
|
379
|
+
# ⚠️ User 789 created with temporary password - password reset required
|
380
|
+
```
|
381
|
+
|
382
|
+
**Breaking Change**: None - fully backward compatible with enhanced capabilities.
|
383
|
+
|
384
|
+
### 1.0.8 - Comprehensive Transfer System with Enhanced Rate Limiting
|
385
|
+
|
386
|
+
**🚀 Complete Cross-Instance Transfer Solution**
|
387
|
+
|
388
|
+
#### Comprehensive Transfer System
|
389
|
+
- **New CLI Option**: `🚀 Comprehensive transfer (users → databases → buckets → functions)` in interactive mode
|
390
|
+
- **Orchestrated Transfer Flow**: Proper execution order (users → databases → buckets → functions) for dependency management
|
391
|
+
- **Cross-Instance Support**: Transfer entire Appwrite configurations between different instances/projects
|
392
|
+
- **Selective Transfer**: Choose which components to transfer (users, databases, buckets, functions)
|
393
|
+
- **Dry Run Mode**: Test transfers without making actual changes
|
394
|
+
|
395
|
+
#### Enhanced Rate Limiting Strategy
|
396
|
+
- **Configurable Limits**: 5 to 100 concurrent operations in steps of 5
|
397
|
+
- **Differentiated Rates**: Smart rate limiting based on operation type:
|
398
|
+
- **General Operations**: Full rate (databases, functions)
|
399
|
+
- **User Operations**: Half rate (more sensitive operations)
|
400
|
+
- **File Operations**: Quarter rate (most bandwidth intensive)
|
401
|
+
- **Visual Feedback**: Real-time rate limit display during transfers
|
402
|
+
- **Intelligent Scaling**: Automatic calculation of optimal rates for different operations
|
403
|
+
|
404
|
+
#### File Transfer Enhancements
|
405
|
+
- **File Validation**: Comprehensive integrity checking (empty files, size limits)
|
406
|
+
- **Retry Logic**: Exponential backoff for failed file transfers
|
407
|
+
- **Error Handling**: Graceful handling of corrupt/invalid files
|
408
|
+
- **Progress Tracking**: Real-time progress for large file transfers
|
409
|
+
|
410
|
+
#### Function Transfer Integration
|
411
|
+
- **Automated Function Migration**: Download from source, redeploy to target
|
412
|
+
- **Temporary Management**: Automatic cleanup of downloaded function code
|
413
|
+
- **Existing Code Integration**: Leverages existing deployment infrastructure
|
414
|
+
- **Configuration Preservation**: Maintains function settings and variables
|
415
|
+
|
416
|
+
#### User Experience Improvements
|
417
|
+
- **Password Reset Warnings**: Clear notifications about Appwrite password limitations
|
418
|
+
- **Interactive Configuration**: Step-by-step prompts for source/target setup
|
419
|
+
- **Comprehensive Reporting**: Detailed transfer summaries with statistics
|
420
|
+
- **Smart Confirmations**: Risk-based confirmations for destructive operations
|
421
|
+
|
422
|
+
#### Technical Implementation
|
423
|
+
- **Rate Limiting**: Uses p-limit for concurrent operation control
|
424
|
+
- **Error Resilience**: Robust error handling with detailed user feedback
|
425
|
+
- **Memory Management**: Efficient processing of large datasets
|
426
|
+
- **Progress Tracking**: Real-time progress bars with ETA calculations
|
427
|
+
|
428
|
+
#### Usage Examples
|
429
|
+
```bash
|
430
|
+
# Interactive mode - select comprehensive transfer
|
431
|
+
npx appwrite-utils-cli@latest appwrite-migrate --it
|
432
|
+
|
433
|
+
# Example rate limiting at 20 concurrent:
|
434
|
+
# - General operations: 20 concurrent
|
435
|
+
# - User operations: 10 concurrent
|
436
|
+
# - File operations: 5 concurrent
|
437
|
+
```
|
438
|
+
|
439
|
+
**Benefits**:
|
440
|
+
- Complete Appwrite instance migration capability
|
441
|
+
- Intelligent rate limiting prevents API throttling
|
442
|
+
- Enhanced file transfer reliability
|
443
|
+
- Comprehensive progress tracking and reporting
|
444
|
+
- Maintains data integrity across transfers
|
445
|
+
|
330
446
|
### 1.0.7 - Forgot to remove debug logs
|
331
447
|
|
332
448
|
### 1.0.6 - Cross-Language Constants Generation
|
package/dist/interactiveCLI.d.ts
CHANGED
package/dist/interactiveCLI.js
CHANGED
@@ -6,6 +6,7 @@ import { fetchAllCollections } from "./collections/methods.js";
|
|
6
6
|
import { listBuckets, createBucket } from "./storage/methods.js";
|
7
7
|
import { Databases, Storage, Client, Compression, Query, Functions, } from "node-appwrite";
|
8
8
|
import { getClient } from "./utils/getClientFromConfig.js";
|
9
|
+
import { ComprehensiveTransfer } from "./migrations/comprehensiveTransfer.js";
|
9
10
|
import { AppwriteFunctionSchema, parseAttribute, PermissionToAppwritePermission, RuntimeSchema, permissionSchema, } from "appwrite-utils";
|
10
11
|
import { ulid } from "ulidx";
|
11
12
|
import chalk from "chalk";
|
@@ -33,6 +34,7 @@ var CHOICES;
|
|
33
34
|
CHOICES["SYNC_DB"] = "\u2B06\uFE0F Push local config to Appwrite";
|
34
35
|
CHOICES["SYNCHRONIZE_CONFIGURATIONS"] = "\uD83D\uDD04 Synchronize configurations - Pull from Appwrite and write to local config";
|
35
36
|
CHOICES["TRANSFER_DATA"] = "\uD83D\uDCE6 Transfer data";
|
37
|
+
CHOICES["COMPREHENSIVE_TRANSFER"] = "\uD83D\uDE80 Comprehensive transfer (users \u2192 databases \u2192 buckets \u2192 functions)";
|
36
38
|
CHOICES["BACKUP_DATABASE"] = "\uD83D\uDCBE Backup database";
|
37
39
|
CHOICES["WIPE_DATABASE"] = "\uD83E\uDDF9 Wipe database";
|
38
40
|
CHOICES["WIPE_COLLECTIONS"] = "\uD83E\uDDF9 Wipe collections";
|
@@ -109,6 +111,9 @@ export class InteractiveCLI {
|
|
109
111
|
await this.initControllerIfNeeded();
|
110
112
|
await this.transferData();
|
111
113
|
break;
|
114
|
+
case CHOICES.COMPREHENSIVE_TRANSFER:
|
115
|
+
await this.comprehensiveTransfer();
|
116
|
+
break;
|
112
117
|
case CHOICES.BACKUP_DATABASE:
|
113
118
|
await this.initControllerIfNeeded();
|
114
119
|
await this.backupDatabase();
|
@@ -1396,13 +1401,13 @@ export class InteractiveCLI {
|
|
1396
1401
|
}));
|
1397
1402
|
}
|
1398
1403
|
async reloadConfig() {
|
1399
|
-
|
1404
|
+
MessageFormatter.progress("Reloading configuration files...", { prefix: "Config" });
|
1400
1405
|
try {
|
1401
1406
|
await this.controller.reloadConfig();
|
1402
|
-
|
1407
|
+
MessageFormatter.success("Configuration files reloaded successfully", { prefix: "Config" });
|
1403
1408
|
}
|
1404
1409
|
catch (error) {
|
1405
|
-
|
1410
|
+
MessageFormatter.error("Failed to reload configuration files", error instanceof Error ? error : new Error(String(error)), { prefix: "Config" });
|
1406
1411
|
}
|
1407
1412
|
}
|
1408
1413
|
async updateFunctionSpec() {
|
@@ -1452,7 +1457,6 @@ export class InteractiveCLI {
|
|
1452
1457
|
try {
|
1453
1458
|
// Check for YAML config first
|
1454
1459
|
const yamlConfigPath = findYamlConfig(this.currentDir);
|
1455
|
-
console.log(`DEBUG: YAML config search from ${this.currentDir}, found: ${yamlConfigPath}`);
|
1456
1460
|
if (yamlConfigPath) {
|
1457
1461
|
this.isUsingTypeScriptConfig = false;
|
1458
1462
|
MessageFormatter.info("Using YAML configuration", { prefix: "Config" });
|
@@ -1509,4 +1513,167 @@ export class InteractiveCLI {
|
|
1509
1513
|
MessageFormatter.error("Migration failed", error instanceof Error ? error : new Error(String(error)), { prefix: "Migration" });
|
1510
1514
|
}
|
1511
1515
|
}
|
1516
|
+
async comprehensiveTransfer() {
|
1517
|
+
MessageFormatter.info("Starting comprehensive transfer configuration...", { prefix: "Transfer" });
|
1518
|
+
try {
|
1519
|
+
// Get source configuration
|
1520
|
+
const sourceConfig = await inquirer.prompt([
|
1521
|
+
{
|
1522
|
+
type: "input",
|
1523
|
+
name: "sourceEndpoint",
|
1524
|
+
message: "Enter the source Appwrite endpoint:",
|
1525
|
+
validate: (input) => input.trim() !== "" || "Endpoint cannot be empty",
|
1526
|
+
},
|
1527
|
+
{
|
1528
|
+
type: "input",
|
1529
|
+
name: "sourceProject",
|
1530
|
+
message: "Enter the source project ID:",
|
1531
|
+
validate: (input) => input.trim() !== "" || "Project ID cannot be empty",
|
1532
|
+
},
|
1533
|
+
{
|
1534
|
+
type: "password",
|
1535
|
+
name: "sourceKey",
|
1536
|
+
message: "Enter the source API key:",
|
1537
|
+
validate: (input) => input.trim() !== "" || "API key cannot be empty",
|
1538
|
+
},
|
1539
|
+
]);
|
1540
|
+
// Get target configuration
|
1541
|
+
const targetConfig = await inquirer.prompt([
|
1542
|
+
{
|
1543
|
+
type: "input",
|
1544
|
+
name: "targetEndpoint",
|
1545
|
+
message: "Enter the target Appwrite endpoint:",
|
1546
|
+
validate: (input) => input.trim() !== "" || "Endpoint cannot be empty",
|
1547
|
+
},
|
1548
|
+
{
|
1549
|
+
type: "input",
|
1550
|
+
name: "targetProject",
|
1551
|
+
message: "Enter the target project ID:",
|
1552
|
+
validate: (input) => input.trim() !== "" || "Project ID cannot be empty",
|
1553
|
+
},
|
1554
|
+
{
|
1555
|
+
type: "password",
|
1556
|
+
name: "targetKey",
|
1557
|
+
message: "Enter the target API key:",
|
1558
|
+
validate: (input) => input.trim() !== "" || "API key cannot be empty",
|
1559
|
+
},
|
1560
|
+
]);
|
1561
|
+
// Get transfer options
|
1562
|
+
const transferOptions = await inquirer.prompt([
|
1563
|
+
{
|
1564
|
+
type: "checkbox",
|
1565
|
+
name: "transferTypes",
|
1566
|
+
message: "Select what to transfer:",
|
1567
|
+
choices: [
|
1568
|
+
{ name: "👥 Users", value: "users", checked: true },
|
1569
|
+
{ name: "🗄️ Databases", value: "databases", checked: true },
|
1570
|
+
{ name: "📦 Storage Buckets", value: "buckets", checked: true },
|
1571
|
+
{ name: "⚡ Functions", value: "functions", checked: true },
|
1572
|
+
],
|
1573
|
+
validate: (input) => input.length > 0 || "Select at least one transfer type",
|
1574
|
+
},
|
1575
|
+
{
|
1576
|
+
type: "list",
|
1577
|
+
name: "concurrencyLimit",
|
1578
|
+
message: "Select concurrency limit:",
|
1579
|
+
choices: [
|
1580
|
+
{ name: "5 (Conservative) - Users: 2, Files: 1", value: 5 },
|
1581
|
+
{ name: "10 (Balanced) - Users: 5, Files: 2", value: 10 },
|
1582
|
+
{ name: "15 - Users: 7, Files: 3", value: 15 },
|
1583
|
+
{ name: "20 - Users: 10, Files: 5", value: 20 },
|
1584
|
+
{ name: "25 - Users: 12, Files: 6", value: 25 },
|
1585
|
+
{ name: "30 - Users: 15, Files: 7", value: 30 },
|
1586
|
+
{ name: "35 - Users: 17, Files: 8", value: 35 },
|
1587
|
+
{ name: "40 - Users: 20, Files: 10", value: 40 },
|
1588
|
+
{ name: "45 - Users: 22, Files: 11", value: 45 },
|
1589
|
+
{ name: "50 - Users: 25, Files: 12", value: 50 },
|
1590
|
+
{ name: "55 - Users: 27, Files: 13", value: 55 },
|
1591
|
+
{ name: "60 - Users: 30, Files: 15", value: 60 },
|
1592
|
+
{ name: "65 - Users: 32, Files: 16", value: 65 },
|
1593
|
+
{ name: "70 - Users: 35, Files: 17", value: 70 },
|
1594
|
+
{ name: "75 - Users: 37, Files: 18", value: 75 },
|
1595
|
+
{ name: "80 - Users: 40, Files: 20", value: 80 },
|
1596
|
+
{ name: "85 - Users: 42, Files: 21", value: 85 },
|
1597
|
+
{ name: "90 - Users: 45, Files: 22", value: 90 },
|
1598
|
+
{ name: "95 - Users: 47, Files: 23", value: 95 },
|
1599
|
+
{ name: "100 (Aggressive) - Users: 50, Files: 25", value: 100 },
|
1600
|
+
],
|
1601
|
+
default: 10,
|
1602
|
+
},
|
1603
|
+
{
|
1604
|
+
type: "confirm",
|
1605
|
+
name: "dryRun",
|
1606
|
+
message: "Run in dry-run mode (no actual changes)?",
|
1607
|
+
default: false,
|
1608
|
+
},
|
1609
|
+
]);
|
1610
|
+
// Confirmation
|
1611
|
+
const { confirmed } = await inquirer.prompt([
|
1612
|
+
{
|
1613
|
+
type: "confirm",
|
1614
|
+
name: "confirmed",
|
1615
|
+
message: `Are you sure you want to ${transferOptions.dryRun ? "dry-run" : "perform"} comprehensive transfer from ${sourceConfig.sourceEndpoint} to ${targetConfig.targetEndpoint}?`,
|
1616
|
+
default: false,
|
1617
|
+
},
|
1618
|
+
]);
|
1619
|
+
if (!confirmed) {
|
1620
|
+
MessageFormatter.info("Transfer cancelled by user", { prefix: "Transfer" });
|
1621
|
+
return;
|
1622
|
+
}
|
1623
|
+
// Password preservation information
|
1624
|
+
if (transferOptions.transferTypes.includes("users") && !transferOptions.dryRun) {
|
1625
|
+
MessageFormatter.info("User Password Transfer Information:", { prefix: "Transfer" });
|
1626
|
+
MessageFormatter.info("✅ Users with hashed passwords (Argon2, Bcrypt, Scrypt, MD5, SHA, PHPass) will preserve their passwords", { prefix: "Transfer" });
|
1627
|
+
MessageFormatter.info("⚠️ Users without hash information will receive temporary passwords and need to reset", { prefix: "Transfer" });
|
1628
|
+
MessageFormatter.info("🔒 All user data (preferences, labels, verification status) will be preserved", { prefix: "Transfer" });
|
1629
|
+
const { continueWithUsers } = await inquirer.prompt([
|
1630
|
+
{
|
1631
|
+
type: "confirm",
|
1632
|
+
name: "continueWithUsers",
|
1633
|
+
message: "Continue with user transfer?",
|
1634
|
+
default: true,
|
1635
|
+
},
|
1636
|
+
]);
|
1637
|
+
if (!continueWithUsers) {
|
1638
|
+
// Remove users from transfer types
|
1639
|
+
transferOptions.transferTypes = transferOptions.transferTypes.filter((type) => type !== "users");
|
1640
|
+
if (transferOptions.transferTypes.length === 0) {
|
1641
|
+
MessageFormatter.info("No transfer types selected, cancelling", { prefix: "Transfer" });
|
1642
|
+
return;
|
1643
|
+
}
|
1644
|
+
}
|
1645
|
+
}
|
1646
|
+
// Execute comprehensive transfer
|
1647
|
+
const comprehensiveTransferOptions = {
|
1648
|
+
sourceEndpoint: sourceConfig.sourceEndpoint,
|
1649
|
+
sourceProject: sourceConfig.sourceProject,
|
1650
|
+
sourceKey: sourceConfig.sourceKey,
|
1651
|
+
targetEndpoint: targetConfig.targetEndpoint,
|
1652
|
+
targetProject: targetConfig.targetProject,
|
1653
|
+
targetKey: targetConfig.targetKey,
|
1654
|
+
transferUsers: transferOptions.transferTypes.includes("users"),
|
1655
|
+
transferDatabases: transferOptions.transferTypes.includes("databases"),
|
1656
|
+
transferBuckets: transferOptions.transferTypes.includes("buckets"),
|
1657
|
+
transferFunctions: transferOptions.transferTypes.includes("functions"),
|
1658
|
+
concurrencyLimit: transferOptions.concurrencyLimit,
|
1659
|
+
dryRun: transferOptions.dryRun,
|
1660
|
+
};
|
1661
|
+
const transfer = new ComprehensiveTransfer(comprehensiveTransferOptions);
|
1662
|
+
const results = await transfer.execute();
|
1663
|
+
// Display results
|
1664
|
+
if (transferOptions.dryRun) {
|
1665
|
+
MessageFormatter.success("Dry run completed successfully!", { prefix: "Transfer" });
|
1666
|
+
}
|
1667
|
+
else {
|
1668
|
+
MessageFormatter.success("Comprehensive transfer completed!", { prefix: "Transfer" });
|
1669
|
+
if (transferOptions.transferTypes.includes("users") && results.users.transferred > 0) {
|
1670
|
+
MessageFormatter.info("Users with preserved password hashes can log in with their original passwords", { prefix: "Transfer" });
|
1671
|
+
MessageFormatter.info("Users with temporary passwords will need to reset their passwords", { prefix: "Transfer" });
|
1672
|
+
}
|
1673
|
+
}
|
1674
|
+
}
|
1675
|
+
catch (error) {
|
1676
|
+
MessageFormatter.error("Comprehensive transfer failed", error instanceof Error ? error : new Error(String(error)), { prefix: "Transfer" });
|
1677
|
+
}
|
1678
|
+
}
|
1512
1679
|
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
export interface ComprehensiveTransferOptions {
|
2
|
+
sourceEndpoint: string;
|
3
|
+
sourceProject: string;
|
4
|
+
sourceKey: string;
|
5
|
+
targetEndpoint: string;
|
6
|
+
targetProject: string;
|
7
|
+
targetKey: string;
|
8
|
+
transferUsers?: boolean;
|
9
|
+
transferDatabases?: boolean;
|
10
|
+
transferBuckets?: boolean;
|
11
|
+
transferFunctions?: boolean;
|
12
|
+
concurrencyLimit?: number;
|
13
|
+
dryRun?: boolean;
|
14
|
+
}
|
15
|
+
export interface TransferResults {
|
16
|
+
users: {
|
17
|
+
transferred: number;
|
18
|
+
skipped: number;
|
19
|
+
failed: number;
|
20
|
+
};
|
21
|
+
databases: {
|
22
|
+
transferred: number;
|
23
|
+
skipped: number;
|
24
|
+
failed: number;
|
25
|
+
};
|
26
|
+
buckets: {
|
27
|
+
transferred: number;
|
28
|
+
skipped: number;
|
29
|
+
failed: number;
|
30
|
+
};
|
31
|
+
functions: {
|
32
|
+
transferred: number;
|
33
|
+
skipped: number;
|
34
|
+
failed: number;
|
35
|
+
};
|
36
|
+
totalTime: number;
|
37
|
+
}
|
38
|
+
export declare class ComprehensiveTransfer {
|
39
|
+
private options;
|
40
|
+
private sourceClient;
|
41
|
+
private targetClient;
|
42
|
+
private sourceUsers;
|
43
|
+
private targetUsers;
|
44
|
+
private sourceDatabases;
|
45
|
+
private targetDatabases;
|
46
|
+
private sourceStorage;
|
47
|
+
private targetStorage;
|
48
|
+
private sourceFunctions;
|
49
|
+
private targetFunctions;
|
50
|
+
private limit;
|
51
|
+
private userLimit;
|
52
|
+
private fileLimit;
|
53
|
+
private results;
|
54
|
+
private startTime;
|
55
|
+
private tempDir;
|
56
|
+
constructor(options: ComprehensiveTransferOptions);
|
57
|
+
execute(): Promise<TransferResults>;
|
58
|
+
private transferAllUsers;
|
59
|
+
private transferAllDatabases;
|
60
|
+
private transferAllBuckets;
|
61
|
+
private transferBucketFiles;
|
62
|
+
private validateAndDownloadFile;
|
63
|
+
private transferAllFunctions;
|
64
|
+
private downloadFunction;
|
65
|
+
private printSummary;
|
66
|
+
}
|