@fazetitans/fscopy 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli.ts +2 -0
- package/src/orchestrator.ts +3 -2
- package/src/output/display.ts +8 -3
- package/src/transfer/count.ts +13 -2
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -6,6 +6,7 @@ process.env.METADATA_SERVER_DETECTION = 'none';
|
|
|
6
6
|
import yargs from 'yargs';
|
|
7
7
|
import { hideBin } from 'yargs/helpers';
|
|
8
8
|
|
|
9
|
+
import pkg from '../package.json';
|
|
9
10
|
import type { Config, CliArgs } from './types.js';
|
|
10
11
|
import { Output, parseSize } from './utils/output.js';
|
|
11
12
|
import { ensureCredentials } from './utils/credentials.js';
|
|
@@ -24,6 +25,7 @@ import { runTransfer } from './orchestrator.js';
|
|
|
24
25
|
|
|
25
26
|
const argv = yargs(hideBin(process.argv))
|
|
26
27
|
.scriptName('fscopy')
|
|
28
|
+
.version(pkg.version)
|
|
27
29
|
.usage('$0 [options]')
|
|
28
30
|
.option('init', {
|
|
29
31
|
type: 'string',
|
package/src/orchestrator.ts
CHANGED
|
@@ -78,7 +78,7 @@ async function handleSuccessOutput(
|
|
|
78
78
|
if (config.json) {
|
|
79
79
|
output.json(JSON.parse(formatJsonOutput(true, config, stats, duration, undefined, verifyResult)));
|
|
80
80
|
} else {
|
|
81
|
-
printSummary(stats, duration.toFixed(2), argv.log, config.dryRun);
|
|
81
|
+
printSummary(stats, duration.toFixed(2), argv.log, config.dryRun, config.verifyIntegrity);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
if (config.webhook) {
|
|
@@ -137,12 +137,13 @@ export async function runTransfer(config: Config, argv: CliArgs, output: Output)
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
const currentStats = config.resume ? stats : createEmptyStats();
|
|
140
|
-
const { progressBar } = await setupProgressTracking(sourceDb, config, currentStats, output);
|
|
141
140
|
|
|
142
141
|
if (config.clear) {
|
|
143
142
|
await clearDestinationCollections(destDb, config, currentStats, output);
|
|
144
143
|
}
|
|
145
144
|
|
|
145
|
+
const { progressBar } = await setupProgressTracking(sourceDb, config, currentStats, output);
|
|
146
|
+
|
|
146
147
|
const rateLimiter = config.rateLimit > 0 ? new RateLimiter(config.rateLimit) : null;
|
|
147
148
|
if (rateLimiter) {
|
|
148
149
|
output.info(`⏱️ Rate limiting enabled: ${config.rateLimit} docs/s\n`);
|
package/src/output/display.ts
CHANGED
|
@@ -159,7 +159,8 @@ export function printSummary(
|
|
|
159
159
|
stats: Stats,
|
|
160
160
|
duration: string,
|
|
161
161
|
logFile?: string,
|
|
162
|
-
dryRun?: boolean
|
|
162
|
+
dryRun?: boolean,
|
|
163
|
+
verifyIntegrity?: boolean
|
|
163
164
|
): void {
|
|
164
165
|
console.log('\n' + '='.repeat(60));
|
|
165
166
|
console.log('📊 TRANSFER SUMMARY');
|
|
@@ -172,8 +173,12 @@ export function printSummary(
|
|
|
172
173
|
if (stats.conflicts > 0) {
|
|
173
174
|
console.log(`Conflicts detected: ${stats.conflicts}`);
|
|
174
175
|
}
|
|
175
|
-
if (
|
|
176
|
-
|
|
176
|
+
if (verifyIntegrity) {
|
|
177
|
+
if (stats.integrityErrors > 0) {
|
|
178
|
+
console.log(`Integrity errors: ${stats.integrityErrors}`);
|
|
179
|
+
} else {
|
|
180
|
+
console.log(`Integrity verified: ✓ ${stats.documentsTransferred} documents`);
|
|
181
|
+
}
|
|
177
182
|
}
|
|
178
183
|
console.log(`Errors: ${stats.errors}`);
|
|
179
184
|
console.log(`Duration: ${duration}s`);
|
package/src/transfer/count.ts
CHANGED
|
@@ -31,6 +31,11 @@ async function countWithSubcollections(
|
|
|
31
31
|
depth: number,
|
|
32
32
|
progress?: CountProgress
|
|
33
33
|
): Promise<number> {
|
|
34
|
+
// Apply limit at root level only
|
|
35
|
+
if (depth === 0 && config.limit > 0) {
|
|
36
|
+
query = query.limit(config.limit);
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
const snapshot = await query.select().get();
|
|
35
40
|
let count = snapshot.size;
|
|
36
41
|
|
|
@@ -80,11 +85,17 @@ async function countSubcollectionsForDoc(
|
|
|
80
85
|
async function countWithoutSubcollections(
|
|
81
86
|
query: Query,
|
|
82
87
|
collectionPath: string,
|
|
88
|
+
config: Config,
|
|
83
89
|
depth: number,
|
|
84
90
|
progress?: CountProgress
|
|
85
91
|
): Promise<number> {
|
|
86
92
|
const countSnapshot = await query.count().get();
|
|
87
|
-
|
|
93
|
+
let count = countSnapshot.data().count;
|
|
94
|
+
|
|
95
|
+
// Apply limit at root level only
|
|
96
|
+
if (depth === 0 && config.limit > 0) {
|
|
97
|
+
count = Math.min(count, config.limit);
|
|
98
|
+
}
|
|
88
99
|
|
|
89
100
|
if (depth === 0 && progress?.onCollection) {
|
|
90
101
|
progress.onCollection(collectionPath, count);
|
|
@@ -106,5 +117,5 @@ export async function countDocuments(
|
|
|
106
117
|
return countWithSubcollections(sourceDb, query, collectionPath, config, depth, progress);
|
|
107
118
|
}
|
|
108
119
|
|
|
109
|
-
return countWithoutSubcollections(query, collectionPath, depth, progress);
|
|
120
|
+
return countWithoutSubcollections(query, collectionPath, config, depth, progress);
|
|
110
121
|
}
|