hsync-cli 1.1.5 → 1.1.7
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/dist/bin.js +47 -17
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -68316,10 +68316,12 @@ class LocalScanner {
|
|
|
68316
68316
|
excludePatterns;
|
|
68317
68317
|
respectGitignore;
|
|
68318
68318
|
ignoreRules;
|
|
68319
|
+
includeBases;
|
|
68319
68320
|
constructor(localPath, filePatterns, excludePatterns, respectGitignore = false) {
|
|
68320
68321
|
this.localPath = localPath;
|
|
68321
68322
|
this.filePatterns = filePatterns || [];
|
|
68322
68323
|
this.excludePatterns = excludePatterns || [];
|
|
68324
|
+
this.includeBases = this.filePatterns.map((p) => import_micromatch.default.scan(p).base);
|
|
68323
68325
|
this.respectGitignore = respectGitignore;
|
|
68324
68326
|
this.ignoreRules = respectGitignore ? [{ base: "", glob: "**/.git", negate: false, dirOnly: true }] : [];
|
|
68325
68327
|
}
|
|
@@ -68355,7 +68357,15 @@ class LocalScanner {
|
|
|
68355
68357
|
return results;
|
|
68356
68358
|
}
|
|
68357
68359
|
async walk(dirPath, results) {
|
|
68358
|
-
|
|
68360
|
+
let entries;
|
|
68361
|
+
try {
|
|
68362
|
+
entries = await fs2.readdir(dirPath, { withFileTypes: true });
|
|
68363
|
+
} catch (err) {
|
|
68364
|
+
if (err.code !== "EACCES" && err.code !== "EPERM")
|
|
68365
|
+
throw err;
|
|
68366
|
+
console.warn(`[LocalScanner] Skipping unreadable folder: ${dirPath}`);
|
|
68367
|
+
return;
|
|
68368
|
+
}
|
|
68359
68369
|
if (this.respectGitignore && entries.some((e) => e.isFile() && e.name === ".gitignore")) {
|
|
68360
68370
|
this.ignoreRules.push(...parseGitignore(await fs2.readFile(path3.join(dirPath, ".gitignore"), "utf8"), path3.relative(this.localPath, dirPath).split(path3.sep).join("/")));
|
|
68361
68371
|
}
|
|
@@ -68363,7 +68373,11 @@ class LocalScanner {
|
|
|
68363
68373
|
const fullPath = path3.join(dirPath, entry.name);
|
|
68364
68374
|
const relativePath = path3.relative(this.localPath, fullPath);
|
|
68365
68375
|
if (entry.isDirectory()) {
|
|
68366
|
-
|
|
68376
|
+
const dir = relativePath.split(path3.sep).join("/");
|
|
68377
|
+
if (this.includeBases.length > 0 && !this.includeBases.some((b) => b === "" || b === dir || b.startsWith(dir + "/") || dir.startsWith(b + "/"))) {
|
|
68378
|
+
continue;
|
|
68379
|
+
}
|
|
68380
|
+
if (!matchesRules(this.ignoreRules, dir, true)) {
|
|
68367
68381
|
await this.walk(fullPath, results);
|
|
68368
68382
|
}
|
|
68369
68383
|
continue;
|
|
@@ -68409,9 +68423,8 @@ class RemoteClient {
|
|
|
68409
68423
|
const response = await this.client.get(`/api/buckets/${slug}/files/tree`, {
|
|
68410
68424
|
params: { path: cleanPath }
|
|
68411
68425
|
});
|
|
68412
|
-
const
|
|
68413
|
-
if (
|
|
68414
|
-
const f = response.data.files[0];
|
|
68426
|
+
const f = response.data.files.find((file) => file.path === cleanPath && !file.isDirectory);
|
|
68427
|
+
if (cleanPath && f) {
|
|
68415
68428
|
return [
|
|
68416
68429
|
{
|
|
68417
68430
|
path: "",
|
|
@@ -68422,7 +68435,7 @@ class RemoteClient {
|
|
|
68422
68435
|
];
|
|
68423
68436
|
}
|
|
68424
68437
|
const prefix = cleanPath ? cleanPath + "/" : "";
|
|
68425
|
-
return response.data.files.filter((f) => !f.isDirectory).map((f) => ({
|
|
68438
|
+
return response.data.files.filter((f) => !f.isDirectory && f.path.startsWith(prefix)).map((f) => ({
|
|
68426
68439
|
path: prefix ? f.path.slice(prefix.length) : f.path,
|
|
68427
68440
|
hash: f.hash || "",
|
|
68428
68441
|
size: f.size,
|
|
@@ -70437,13 +70450,14 @@ async function push(localPath, remoteTarget, options) {
|
|
|
70437
70450
|
const remoteClient = new RemoteClient(serverUrl, apiKey);
|
|
70438
70451
|
const remoteFiles = await remoteClient.getTree(remote.slug, remote.remotePath);
|
|
70439
70452
|
spinner.stop();
|
|
70453
|
+
const isFileToFile = !!remote.remotePath && (await fs6.stat(resolvedLocalPath)).isFile() && (remoteFiles.length === 1 && remoteFiles[0].path === "" || remoteFiles.length === 0 && path8.posix.basename(remote.remotePath) === localFiles[0].relativePath);
|
|
70440
70454
|
console.log(source_default.cyan(`Found ${localFiles.length} local files, ${remoteFiles.length} remote files.`));
|
|
70441
70455
|
const prompter = new OverwritePrompter(forceYes);
|
|
70442
70456
|
let pushCount = 0;
|
|
70443
70457
|
let skipCount = 0;
|
|
70444
70458
|
for (const localFile of localFiles) {
|
|
70445
|
-
const remoteFile = remoteFiles.find((f) => f.path === localFile.relativePath);
|
|
70446
|
-
const destinationPath = remote.remotePath ? `${remote.remotePath}/${localFile.relativePath}` : localFile.relativePath;
|
|
70459
|
+
const remoteFile = remoteFiles.find((f) => f.path === (isFileToFile ? "" : localFile.relativePath));
|
|
70460
|
+
const destinationPath = isFileToFile ? remote.remotePath : remote.remotePath ? `${remote.remotePath}/${localFile.relativePath}` : localFile.relativePath;
|
|
70447
70461
|
let shouldUpload = false;
|
|
70448
70462
|
if (!remoteFile) {
|
|
70449
70463
|
shouldUpload = true;
|
|
@@ -70491,8 +70505,24 @@ async function pull(remoteTarget, localPath, options) {
|
|
|
70491
70505
|
const remoteClient = new RemoteClient(serverUrl, apiKey);
|
|
70492
70506
|
const remoteFiles = await remoteClient.getTree(remote.slug, remote.remotePath);
|
|
70493
70507
|
spinner.text = "Scanning local files...";
|
|
70494
|
-
|
|
70495
|
-
|
|
70508
|
+
let singleFileDest = "";
|
|
70509
|
+
let localFiles = [];
|
|
70510
|
+
if (remoteFiles.length === 1 && remoteFiles[0].path === "") {
|
|
70511
|
+
singleFileDest = resolvedLocalPath;
|
|
70512
|
+
let isDir = localPath.endsWith("/");
|
|
70513
|
+
try {
|
|
70514
|
+
isDir = isDir || (await fs6.stat(resolvedLocalPath)).isDirectory();
|
|
70515
|
+
} catch {}
|
|
70516
|
+
if (isDir) {
|
|
70517
|
+
singleFileDest = path8.join(resolvedLocalPath, path8.posix.basename(remote.remotePath));
|
|
70518
|
+
}
|
|
70519
|
+
try {
|
|
70520
|
+
localFiles = [{ ...(await scanLocalPath(singleFileDest, singleFileDest))[0], relativePath: "" }];
|
|
70521
|
+
} catch {}
|
|
70522
|
+
} else {
|
|
70523
|
+
await fs6.mkdir(resolvedLocalPath, { recursive: true });
|
|
70524
|
+
localFiles = await scanLocalPath(resolvedLocalPath, resolvedLocalPath);
|
|
70525
|
+
}
|
|
70496
70526
|
spinner.stop();
|
|
70497
70527
|
console.log(source_default.cyan(`Found ${remoteFiles.length} remote files, ${localFiles.length} local files.`));
|
|
70498
70528
|
const prompter = new OverwritePrompter(forceYes);
|
|
@@ -70500,13 +70530,13 @@ async function pull(remoteTarget, localPath, options) {
|
|
|
70500
70530
|
let skipCount = 0;
|
|
70501
70531
|
for (const remoteFile of remoteFiles) {
|
|
70502
70532
|
const localFile = localFiles.find((f) => f.relativePath === remoteFile.path);
|
|
70503
|
-
const localDestPath = path8.join(resolvedLocalPath, remoteFile.path);
|
|
70504
|
-
const sourcePath = remote.remotePath ? `${remote.remotePath}/${remoteFile.path}` : remoteFile.path;
|
|
70533
|
+
const localDestPath = singleFileDest || path8.join(resolvedLocalPath, remoteFile.path);
|
|
70534
|
+
const sourcePath = singleFileDest ? remote.remotePath : remote.remotePath ? `${remote.remotePath}/${remoteFile.path}` : remoteFile.path;
|
|
70505
70535
|
let shouldDownload = false;
|
|
70506
70536
|
if (!localFile) {
|
|
70507
70537
|
shouldDownload = true;
|
|
70508
70538
|
} else if (localFile.hash !== remoteFile.hash) {
|
|
70509
|
-
const confirm = await prompter.shouldOverwrite(remoteFile.path);
|
|
70539
|
+
const confirm = await prompter.shouldOverwrite(remoteFile.path || remote.remotePath);
|
|
70510
70540
|
if (confirm) {
|
|
70511
70541
|
shouldDownload = true;
|
|
70512
70542
|
} else {
|
|
@@ -70516,13 +70546,13 @@ async function pull(remoteTarget, localPath, options) {
|
|
|
70516
70546
|
skipCount++;
|
|
70517
70547
|
}
|
|
70518
70548
|
if (shouldDownload) {
|
|
70519
|
-
const fileSpinner = ora2(`Pulling ${remoteFile.path}...`).start();
|
|
70549
|
+
const fileSpinner = ora2(`Pulling ${remoteFile.path || remote.remotePath}...`).start();
|
|
70520
70550
|
try {
|
|
70521
70551
|
await remoteClient.downloadFile(remote.slug, sourcePath, localDestPath);
|
|
70522
|
-
fileSpinner.succeed(source_default.green(`Pulled ${remoteFile.path}`));
|
|
70552
|
+
fileSpinner.succeed(source_default.green(`Pulled ${remoteFile.path || remote.remotePath}`));
|
|
70523
70553
|
pullCount++;
|
|
70524
70554
|
} catch (downloadErr) {
|
|
70525
|
-
fileSpinner.fail(source_default.red(`Failed to pull ${remoteFile.path}: ${downloadErr.message}`));
|
|
70555
|
+
fileSpinner.fail(source_default.red(`Failed to pull ${remoteFile.path || remote.remotePath}: ${downloadErr.message}`));
|
|
70526
70556
|
}
|
|
70527
70557
|
}
|
|
70528
70558
|
}
|
|
@@ -71488,7 +71518,7 @@ Press Ctrl+C to stop the server...
|
|
|
71488
71518
|
// package.json
|
|
71489
71519
|
var package_default = {
|
|
71490
71520
|
name: "hsync-cli",
|
|
71491
|
-
version: "1.1.
|
|
71521
|
+
version: "1.1.7",
|
|
71492
71522
|
description: "hsync CLI for file sync operations",
|
|
71493
71523
|
bin: {
|
|
71494
71524
|
hsync: "./dist/bin.js"
|