pinme 1.1.2 → 1.1.3-alpha.3
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/index.js +471 -648
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -99,7 +99,7 @@ var require_main = __commonJS({
|
|
|
99
99
|
var fs6 = require("fs");
|
|
100
100
|
var path6 = require("path");
|
|
101
101
|
var os3 = require("os");
|
|
102
|
-
var
|
|
102
|
+
var crypto2 = require("crypto");
|
|
103
103
|
var packageJson = require_package();
|
|
104
104
|
var version2 = packageJson.version;
|
|
105
105
|
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
@@ -295,7 +295,7 @@ var require_main = __commonJS({
|
|
|
295
295
|
const authTag = ciphertext.subarray(-16);
|
|
296
296
|
ciphertext = ciphertext.subarray(12, -16);
|
|
297
297
|
try {
|
|
298
|
-
const aesgcm =
|
|
298
|
+
const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
|
|
299
299
|
aesgcm.setAuthTag(authTag);
|
|
300
300
|
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
301
301
|
} catch (error) {
|
|
@@ -1481,15 +1481,15 @@ var require_follow_redirects = __commonJS({
|
|
|
1481
1481
|
// bin/index.ts
|
|
1482
1482
|
var import_dotenv = __toESM(require_main());
|
|
1483
1483
|
var import_commander = require("commander");
|
|
1484
|
-
var
|
|
1484
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
1485
1485
|
var import_figlet3 = __toESM(require("figlet"));
|
|
1486
1486
|
|
|
1487
1487
|
// package.json
|
|
1488
|
-
var version = "1.1.
|
|
1488
|
+
var version = "1.1.3-alpha.3";
|
|
1489
1489
|
|
|
1490
1490
|
// bin/upload.ts
|
|
1491
1491
|
var import_path5 = __toESM(require("path"));
|
|
1492
|
-
var
|
|
1492
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
1493
1493
|
var import_inquirer = __toESM(require("inquirer"));
|
|
1494
1494
|
var import_figlet = __toESM(require("figlet"));
|
|
1495
1495
|
|
|
@@ -4360,12 +4360,12 @@ var {
|
|
|
4360
4360
|
mergeConfig: mergeConfig2
|
|
4361
4361
|
} = axios_default;
|
|
4362
4362
|
|
|
4363
|
-
// bin/utils/
|
|
4363
|
+
// bin/utils/uploadToIpfs2.ts
|
|
4364
4364
|
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
4365
4365
|
var import_path4 = __toESM(require("path"));
|
|
4366
4366
|
var import_form_data2 = __toESM(require("form-data"));
|
|
4367
4367
|
var import_ora = __toESM(require("ora"));
|
|
4368
|
-
var
|
|
4368
|
+
var crypto = __toESM(require("crypto"));
|
|
4369
4369
|
|
|
4370
4370
|
// bin/utils/uploadLimits.ts
|
|
4371
4371
|
var import_fs = __toESM(require("fs"));
|
|
@@ -4520,653 +4520,473 @@ function getDeviceId() {
|
|
|
4520
4520
|
return deviceId;
|
|
4521
4521
|
}
|
|
4522
4522
|
|
|
4523
|
-
// bin/utils/
|
|
4524
|
-
var
|
|
4525
|
-
var
|
|
4526
|
-
var
|
|
4527
|
-
var
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
if (code === 200) {
|
|
4547
|
-
consecutiveErrors = 0;
|
|
4548
|
-
stopProgressUpdates = false;
|
|
4549
|
-
if (data.is_ready) {
|
|
4550
|
-
smartProgress.complete(traceId);
|
|
4551
|
-
return data;
|
|
4552
|
-
} else {
|
|
4553
|
-
smartProgress.updateDisplay();
|
|
4554
|
-
}
|
|
4555
|
-
} else {
|
|
4556
|
-
console.log(import_chalk2.default.yellow(`Warning: ${msg}`));
|
|
4557
|
-
}
|
|
4558
|
-
} catch (error) {
|
|
4559
|
-
consecutiveErrors++;
|
|
4560
|
-
console.log(import_chalk2.default.yellow(`Polling error: ${error.message}`));
|
|
4561
|
-
if (stopProgressUpdates) {
|
|
4562
|
-
smartProgress.updateTimeOnly();
|
|
4563
|
-
}
|
|
4564
|
-
}
|
|
4565
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
4523
|
+
// bin/utils/uploadToIpfs2.ts
|
|
4524
|
+
var IPFS_API_URL = "https://pinme.dev/api/v3";
|
|
4525
|
+
var MAX_RETRIES = parseInt(process.env.MAX_RETRIES || "2");
|
|
4526
|
+
var RETRY_DELAY = parseInt(process.env.RETRY_DELAY_MS || "1000");
|
|
4527
|
+
var TIMEOUT = parseInt(process.env.TIMEOUT_MS || "600000");
|
|
4528
|
+
var MAX_POLL_TIME = parseInt("5") * 60 * 1e3;
|
|
4529
|
+
var POLL_INTERVAL = parseInt(process.env.POLL_INTERVAL_SECONDS || "2") * 1e3;
|
|
4530
|
+
var PROGRESS_UPDATE_INTERVAL = 200;
|
|
4531
|
+
var EXPECTED_UPLOAD_TIME = 6e4;
|
|
4532
|
+
var MAX_PROGRESS = 0.95;
|
|
4533
|
+
var StepProgressBar = class {
|
|
4534
|
+
spinner;
|
|
4535
|
+
fileName;
|
|
4536
|
+
startTime;
|
|
4537
|
+
currentStep = 0;
|
|
4538
|
+
stepStartTime = 0;
|
|
4539
|
+
progressInterval = null;
|
|
4540
|
+
constructor(fileName, isDirectory = false) {
|
|
4541
|
+
this.fileName = fileName;
|
|
4542
|
+
this.spinner = (0, import_ora.default)(`Preparing to upload ${fileName}...`).start();
|
|
4543
|
+
this.startTime = Date.now();
|
|
4544
|
+
this.stepStartTime = Date.now();
|
|
4545
|
+
this.startProgress();
|
|
4566
4546
|
}
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
traceId
|
|
4571
|
-
);
|
|
4572
|
-
return null;
|
|
4573
|
-
}
|
|
4574
|
-
function diagnoseDirectoryUploadError(directoryName, resData, expectedName) {
|
|
4575
|
-
const issues = [];
|
|
4576
|
-
if (directoryName.length > 100) {
|
|
4577
|
-
issues.push(
|
|
4578
|
-
`Directory name too long (${directoryName.length} characters, recommended under 100 characters)`
|
|
4579
|
-
);
|
|
4547
|
+
startStep(stepIndex, stepName) {
|
|
4548
|
+
this.currentStep = stepIndex;
|
|
4549
|
+
this.stepStartTime = Date.now();
|
|
4580
4550
|
}
|
|
4581
|
-
|
|
4582
|
-
issues.push(`Name returned by IPFS: ${availableName}`);
|
|
4583
|
-
issues.push(`Expected directory name: ${expectedName}`);
|
|
4584
|
-
const encodedName = encodeURIComponent(directoryName);
|
|
4585
|
-
if (encodedName !== directoryName) {
|
|
4586
|
-
issues.push(`Directory name after encoding: ${encodedName}`);
|
|
4551
|
+
updateProgress(progress, total) {
|
|
4587
4552
|
}
|
|
4588
|
-
|
|
4589
|
-
}
|
|
4590
|
-
function handleMultipartError(error, context) {
|
|
4591
|
-
if (error.message && error.message.includes("multipart: NextPart: EOF")) {
|
|
4592
|
-
return `Multipart form data error: ${context}. This usually indicates:
|
|
4593
|
-
- Empty directory or no valid files
|
|
4594
|
-
- File access permissions issue
|
|
4595
|
-
- Network interruption during upload
|
|
4596
|
-
- Server-side multipart parsing error`;
|
|
4597
|
-
}
|
|
4598
|
-
if (error.message && error.message.includes("ENOENT")) {
|
|
4599
|
-
return `File not found error: ${context}. Please check:
|
|
4600
|
-
- File path is correct
|
|
4601
|
-
- File exists and is accessible
|
|
4602
|
-
- No permission issues`;
|
|
4603
|
-
}
|
|
4604
|
-
if (error.message && error.message.includes("EACCES")) {
|
|
4605
|
-
return `Permission denied error: ${context}. Please check:
|
|
4606
|
-
- File read permissions
|
|
4607
|
-
- Directory access permissions
|
|
4608
|
-
- User has sufficient privileges`;
|
|
4609
|
-
}
|
|
4610
|
-
return `Upload error: ${error.message}`;
|
|
4611
|
-
}
|
|
4612
|
-
var ERROR_CODES = {
|
|
4613
|
-
"30001": `File too large, single file max size: ${"500"}MB,single folder max size: ${"500"}MB`,
|
|
4614
|
-
"30002": `Max storage quorum ${Number("1000") / 1e3} GB reached`
|
|
4615
|
-
};
|
|
4616
|
-
function loadFilesToArrRecursively(directoryPath, dist, basePath) {
|
|
4617
|
-
const filesArr = [];
|
|
4618
|
-
const sep = import_path4.default.sep;
|
|
4619
|
-
if (!basePath) {
|
|
4620
|
-
const parentDir = import_path4.default.dirname(directoryPath);
|
|
4621
|
-
basePath = parentDir.endsWith(sep) ? parentDir : parentDir + sep;
|
|
4622
|
-
}
|
|
4623
|
-
if (import_fs_extra3.default.statSync(directoryPath).isDirectory()) {
|
|
4624
|
-
const files = import_fs_extra3.default.readdirSync(directoryPath);
|
|
4625
|
-
files.forEach((file) => {
|
|
4626
|
-
const filePath = import_path4.default.join(directoryPath, file);
|
|
4627
|
-
if (import_fs_extra3.default.statSync(filePath).isFile()) {
|
|
4628
|
-
const sizeCheck = checkFileSizeLimit(filePath);
|
|
4629
|
-
if (sizeCheck.exceeds) {
|
|
4630
|
-
throw new Error(
|
|
4631
|
-
`File ${file} exceeds size limit of ${formatSize(
|
|
4632
|
-
sizeCheck.limit
|
|
4633
|
-
)} (size: ${formatSize(sizeCheck.size)})`
|
|
4634
|
-
);
|
|
4635
|
-
}
|
|
4636
|
-
const relativePath = filePath.replace(basePath, "");
|
|
4637
|
-
const encodedPath = relativePath.replaceAll(sep, "%2F");
|
|
4638
|
-
filesArr.push({
|
|
4639
|
-
name: encodedPath,
|
|
4640
|
-
path: filePath
|
|
4641
|
-
});
|
|
4642
|
-
} else if (import_fs_extra3.default.statSync(filePath).isDirectory()) {
|
|
4643
|
-
const recursiveFiles = loadFilesToArrRecursively(
|
|
4644
|
-
filePath,
|
|
4645
|
-
dist,
|
|
4646
|
-
basePath
|
|
4647
|
-
);
|
|
4648
|
-
filesArr.push(...recursiveFiles);
|
|
4649
|
-
}
|
|
4650
|
-
});
|
|
4651
|
-
} else {
|
|
4652
|
-
console.error("Error: path must be a directory");
|
|
4553
|
+
completeStep() {
|
|
4653
4554
|
}
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
let count = 0;
|
|
4658
|
-
const files = import_fs_extra3.default.readdirSync(directoryPath);
|
|
4659
|
-
for (const file of files) {
|
|
4660
|
-
const filePath = import_path4.default.join(directoryPath, file);
|
|
4661
|
-
const stats = import_fs_extra3.default.statSync(filePath);
|
|
4662
|
-
if (stats.isFile()) {
|
|
4663
|
-
count++;
|
|
4664
|
-
} else if (stats.isDirectory()) {
|
|
4665
|
-
count += countFilesInDirectory(filePath);
|
|
4666
|
-
}
|
|
4555
|
+
failStep(error) {
|
|
4556
|
+
this.stopProgress();
|
|
4557
|
+
this.spinner.fail(`Upload failed: ${error}`);
|
|
4667
4558
|
}
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
throw new Error(
|
|
4674
|
-
`Directory ${directoryPath} exceeds size limit of ${formatSize(
|
|
4675
|
-
sizeCheck.limit
|
|
4676
|
-
)} (size: ${formatSize(sizeCheck.size)})`
|
|
4677
|
-
);
|
|
4559
|
+
complete() {
|
|
4560
|
+
this.stopProgress();
|
|
4561
|
+
const totalTime = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
4562
|
+
const progressBar = this.createProgressBar(1);
|
|
4563
|
+
this.spinner.succeed(`Upload completed ${progressBar} 100% (${totalTime}s)`);
|
|
4678
4564
|
}
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
const files = loadFilesToArrRecursively(directoryPath, dist);
|
|
4684
|
-
const totalFiles = files.length;
|
|
4685
|
-
if (totalFiles === 0) {
|
|
4686
|
-
throw new Error(
|
|
4687
|
-
`Directory ${directoryPath} is empty or contains no valid files`
|
|
4688
|
-
);
|
|
4565
|
+
fail(error) {
|
|
4566
|
+
this.stopProgress();
|
|
4567
|
+
const totalTime = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
4568
|
+
this.spinner.fail(`Upload failed: ${error} (${totalTime}s)`);
|
|
4689
4569
|
}
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4570
|
+
startProgress() {
|
|
4571
|
+
this.progressInterval = setInterval(() => {
|
|
4572
|
+
const elapsed = Date.now() - this.startTime;
|
|
4573
|
+
const progress = this.calculateProgress(elapsed);
|
|
4574
|
+
const duration = this.formatDuration(Math.floor(elapsed / 1e3));
|
|
4575
|
+
const progressBar = this.createProgressBar(progress);
|
|
4576
|
+
this.spinner.text = `Uploading ${this.fileName}... ${progressBar} ${Math.round(progress * 100)}% (${duration})`;
|
|
4577
|
+
}, PROGRESS_UPDATE_INTERVAL);
|
|
4578
|
+
}
|
|
4579
|
+
stopProgress() {
|
|
4580
|
+
if (this.progressInterval) {
|
|
4581
|
+
clearInterval(this.progressInterval);
|
|
4582
|
+
this.progressInterval = null;
|
|
4693
4583
|
}
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4584
|
+
}
|
|
4585
|
+
calculateProgress(elapsed) {
|
|
4586
|
+
return Math.min(elapsed / EXPECTED_UPLOAD_TIME * MAX_PROGRESS, MAX_PROGRESS);
|
|
4587
|
+
}
|
|
4588
|
+
createProgressBar(progress, width = 20) {
|
|
4589
|
+
const percentage = Math.min(progress, 1);
|
|
4590
|
+
const filledWidth = Math.round(width * percentage);
|
|
4591
|
+
const emptyWidth = width - filledWidth;
|
|
4592
|
+
return `[${"\u2588".repeat(filledWidth)}${"\u2591".repeat(emptyWidth)}]`;
|
|
4593
|
+
}
|
|
4594
|
+
formatDuration(seconds) {
|
|
4595
|
+
if (seconds < 60) {
|
|
4596
|
+
return `${seconds}s`;
|
|
4597
|
+
} else if (seconds < 3600) {
|
|
4598
|
+
const minutes = Math.floor(seconds / 60);
|
|
4599
|
+
const remainingSeconds = seconds % 60;
|
|
4600
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
4601
|
+
} else {
|
|
4602
|
+
const hours = Math.floor(seconds / 3600);
|
|
4603
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
4604
|
+
const remainingSeconds = seconds % 60;
|
|
4605
|
+
return `${hours}h ${minutes}m ${remainingSeconds}s`;
|
|
4697
4606
|
}
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4607
|
+
}
|
|
4608
|
+
};
|
|
4609
|
+
async function calculateMD5(filePath) {
|
|
4610
|
+
return new Promise((resolve, reject) => {
|
|
4611
|
+
const hash = crypto.createHash("md5");
|
|
4612
|
+
const stream4 = import_fs_extra3.default.createReadStream(filePath);
|
|
4613
|
+
stream4.on("data", hash.update.bind(hash));
|
|
4614
|
+
stream4.on("end", () => resolve(hash.digest("hex")));
|
|
4615
|
+
stream4.on("error", reject);
|
|
4701
4616
|
});
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4617
|
+
}
|
|
4618
|
+
async function compressDirectory(sourcePath) {
|
|
4619
|
+
return new Promise((resolve, reject) => {
|
|
4620
|
+
const tempDir = import_path4.default.join(process.cwd(), "temp");
|
|
4621
|
+
if (!import_fs_extra3.default.existsSync(tempDir)) {
|
|
4622
|
+
import_fs_extra3.default.mkdirSync(tempDir, { recursive: true });
|
|
4623
|
+
}
|
|
4624
|
+
const outputPath = import_path4.default.join(
|
|
4625
|
+
tempDir,
|
|
4626
|
+
`${import_path4.default.basename(sourcePath)}_${Date.now()}.zip`
|
|
4627
|
+
);
|
|
4628
|
+
const output = import_fs_extra3.default.createWriteStream(outputPath);
|
|
4629
|
+
const zlib2 = require("zlib");
|
|
4630
|
+
const gzip = zlib2.createGzip({ level: 9 });
|
|
4631
|
+
output.on("close", () => resolve(outputPath));
|
|
4632
|
+
gzip.on("error", reject);
|
|
4633
|
+
gzip.pipe(output);
|
|
4634
|
+
const stats = import_fs_extra3.default.statSync(sourcePath);
|
|
4635
|
+
if (stats.isDirectory()) {
|
|
4636
|
+
const archive = require("archiver");
|
|
4637
|
+
const archiveStream = archive("zip", { zlib: { level: 9 } });
|
|
4638
|
+
archiveStream.on("error", reject);
|
|
4639
|
+
archiveStream.pipe(output);
|
|
4640
|
+
archiveStream.directory(sourcePath, false);
|
|
4641
|
+
archiveStream.finalize();
|
|
4642
|
+
} else {
|
|
4643
|
+
const fileStream = import_fs_extra3.default.createReadStream(sourcePath);
|
|
4644
|
+
fileStream.pipe(gzip);
|
|
4710
4645
|
}
|
|
4711
4646
|
});
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
);
|
|
4718
|
-
const timeInterval = setInterval(() => {
|
|
4719
|
-
smartProgress.updateTime();
|
|
4720
|
-
}, 1e3);
|
|
4721
|
-
const progressInterval = setInterval(() => {
|
|
4722
|
-
smartProgress.updateProgress();
|
|
4723
|
-
}, 200);
|
|
4647
|
+
}
|
|
4648
|
+
async function initChunkSession(filePath, deviceId, isDirectory = false) {
|
|
4649
|
+
const stats = import_fs_extra3.default.statSync(filePath);
|
|
4650
|
+
const fileName = import_path4.default.basename(filePath);
|
|
4651
|
+
const fileSize = stats.size;
|
|
4652
|
+
const md5 = await calculateMD5(filePath);
|
|
4724
4653
|
try {
|
|
4725
|
-
smartProgress.startUpload();
|
|
4726
4654
|
const response = await axios_default.post(
|
|
4727
|
-
`${
|
|
4728
|
-
formData,
|
|
4655
|
+
`${IPFS_API_URL}/chunk/init`,
|
|
4729
4656
|
{
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4657
|
+
file_name: fileName,
|
|
4658
|
+
file_size: fileSize,
|
|
4659
|
+
md5,
|
|
4660
|
+
is_directory: isDirectory,
|
|
4661
|
+
uid: deviceId
|
|
4662
|
+
},
|
|
4663
|
+
{
|
|
4664
|
+
timeout: TIMEOUT,
|
|
4665
|
+
headers: { "Content-Type": "application/json" }
|
|
4735
4666
|
}
|
|
4736
4667
|
);
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
if (!trace_id) {
|
|
4741
|
-
smartProgress.fail("No request id received from server");
|
|
4742
|
-
clearInterval(timeInterval);
|
|
4743
|
-
return null;
|
|
4744
|
-
}
|
|
4745
|
-
smartProgress.updateDisplay();
|
|
4746
|
-
const uploadResult = await pollUploadStatus(
|
|
4747
|
-
trace_id,
|
|
4748
|
-
deviceId,
|
|
4749
|
-
smartProgress,
|
|
4750
|
-
startTime
|
|
4751
|
-
);
|
|
4752
|
-
if (!uploadResult) {
|
|
4753
|
-
clearInterval(timeInterval);
|
|
4754
|
-
return null;
|
|
4755
|
-
}
|
|
4756
|
-
const directoryItem = uploadResult.upload_rst;
|
|
4757
|
-
if (directoryItem) {
|
|
4758
|
-
const fileCount = countFilesInDirectory(directoryPath);
|
|
4759
|
-
const uploadData = {
|
|
4760
|
-
path: directoryPath,
|
|
4761
|
-
filename: import_path4.default.basename(directoryPath),
|
|
4762
|
-
contentHash: directoryItem.Hash,
|
|
4763
|
-
previewHash: null,
|
|
4764
|
-
size: sizeCheck.size,
|
|
4765
|
-
fileCount,
|
|
4766
|
-
isDirectory: true,
|
|
4767
|
-
shortUrl: directoryItem.ShortUrl || null
|
|
4768
|
-
};
|
|
4769
|
-
saveUploadHistory(uploadData);
|
|
4770
|
-
clearInterval(timeInterval);
|
|
4771
|
-
return {
|
|
4772
|
-
hash: directoryItem.Hash,
|
|
4773
|
-
shortUrl: directoryItem.ShortUrl
|
|
4774
|
-
};
|
|
4668
|
+
const { code, msg, data } = response.data;
|
|
4669
|
+
if (code === 200 && data) {
|
|
4670
|
+
return data;
|
|
4775
4671
|
}
|
|
4776
|
-
|
|
4777
|
-
dist,
|
|
4778
|
-
uploadResult.upload_rst,
|
|
4779
|
-
dist
|
|
4780
|
-
);
|
|
4781
|
-
smartProgress.fail("Directory hash not found in response");
|
|
4782
|
-
console.log(
|
|
4783
|
-
import_chalk2.default.red(
|
|
4784
|
-
`
|
|
4785
|
-
\u274C Directory upload failed: Directory hash not found in response`
|
|
4786
|
-
)
|
|
4787
|
-
);
|
|
4788
|
-
console.log(import_chalk2.default.yellow(`
|
|
4789
|
-
\u{1F4CB} Error diagnosis information:`));
|
|
4790
|
-
console.log(import_chalk2.default.gray(` - ${diagnosticInfo}`));
|
|
4791
|
-
console.log(import_chalk2.default.blue(`
|
|
4792
|
-
\u{1F527} Solutions:`));
|
|
4793
|
-
console.log(
|
|
4794
|
-
import_chalk2.default.gray(` 1. Ensure directory is not empty and contains valid files`)
|
|
4795
|
-
);
|
|
4796
|
-
console.log(import_chalk2.default.gray(` 2. Check network connection stability`));
|
|
4797
|
-
console.log(
|
|
4798
|
-
import_chalk2.default.gray(` 3. Try uploading a smaller directory for testing`)
|
|
4799
|
-
);
|
|
4800
|
-
clearInterval(timeInterval);
|
|
4801
|
-
return null;
|
|
4672
|
+
throw new Error(`Session initialization failed: ${msg} (code: ${code})`);
|
|
4802
4673
|
} catch (error) {
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
if (error.message && error.message.includes("multipart")) {
|
|
4806
|
-
const errorMessage = handleMultipartError(
|
|
4807
|
-
error,
|
|
4808
|
-
`Directory upload: ${dist}`
|
|
4809
|
-
);
|
|
4810
|
-
smartProgress.fail(errorMessage);
|
|
4811
|
-
console.log(import_chalk2.default.red(`
|
|
4812
|
-
\u274C ${errorMessage}`));
|
|
4813
|
-
return null;
|
|
4674
|
+
if (axios_default.isAxiosError(error)) {
|
|
4675
|
+
throw new Error(`Network error: ${error.message}`);
|
|
4814
4676
|
}
|
|
4815
|
-
|
|
4816
|
-
const errorCode = error.response.data.code.toString();
|
|
4817
|
-
if (ERROR_CODES[errorCode]) {
|
|
4818
|
-
smartProgress.fail(
|
|
4819
|
-
`Error: ${ERROR_CODES[errorCode]} (Code: ${errorCode})`
|
|
4820
|
-
);
|
|
4821
|
-
console.log(
|
|
4822
|
-
import_chalk2.default.red(`Error: ${ERROR_CODES[errorCode]} (Code: ${errorCode})`)
|
|
4823
|
-
);
|
|
4824
|
-
return null;
|
|
4825
|
-
}
|
|
4826
|
-
}
|
|
4827
|
-
smartProgress.fail(`Error: ${error.message}`);
|
|
4828
|
-
console.log(import_chalk2.default.red(`Error: ${error.message}`));
|
|
4829
|
-
return null;
|
|
4677
|
+
throw error;
|
|
4830
4678
|
}
|
|
4831
4679
|
}
|
|
4832
|
-
async function
|
|
4833
|
-
const sizeCheck = checkFileSizeLimit(filePath);
|
|
4834
|
-
if (sizeCheck.exceeds) {
|
|
4835
|
-
throw new Error(
|
|
4836
|
-
`File ${filePath} exceeds size limit of ${formatSize(
|
|
4837
|
-
sizeCheck.limit
|
|
4838
|
-
)} (size: ${formatSize(sizeCheck.size)})`
|
|
4839
|
-
);
|
|
4840
|
-
}
|
|
4841
|
-
const fileName = filePath.split(import_path4.default.sep).pop() || "";
|
|
4842
|
-
if (!import_fs_extra3.default.existsSync(filePath)) {
|
|
4843
|
-
throw new Error(`File not found: ${filePath}`);
|
|
4844
|
-
}
|
|
4845
|
-
const fileStats = import_fs_extra3.default.statSync(filePath);
|
|
4846
|
-
if (!fileStats.isFile()) {
|
|
4847
|
-
throw new Error(`Path is not a file: ${filePath}`);
|
|
4848
|
-
}
|
|
4849
|
-
console.log(import_chalk2.default.blue("\n\u{1F4C4} File Upload Analysis:"));
|
|
4850
|
-
console.log(import_chalk2.default.gray(` File path: ${filePath}`));
|
|
4851
|
-
console.log(import_chalk2.default.gray(` File name: ${fileName}`));
|
|
4852
|
-
console.log(import_chalk2.default.gray(` File size: ${formatSize(fileStats.size)}`));
|
|
4853
|
-
console.log(import_chalk2.default.gray(` File exists: ${import_fs_extra3.default.existsSync(filePath)}`));
|
|
4854
|
-
console.log(import_chalk2.default.gray(` Is file: ${fileStats.isFile()}
|
|
4855
|
-
`));
|
|
4856
|
-
const startTime = Date.now();
|
|
4857
|
-
const spinner = (0, import_ora.default)(`Preparing upload...`).start();
|
|
4858
|
-
let totalSize = 0;
|
|
4859
|
-
try {
|
|
4860
|
-
const stats = import_fs_extra3.default.statSync(filePath);
|
|
4861
|
-
totalSize = stats.size;
|
|
4862
|
-
} catch (error) {
|
|
4863
|
-
}
|
|
4864
|
-
const smartProgress = new SmartProgressBar(fileName, 1, totalSize, spinner);
|
|
4865
|
-
const timeInterval = setInterval(() => {
|
|
4866
|
-
smartProgress.updateTime();
|
|
4867
|
-
}, 1e3);
|
|
4868
|
-
const progressInterval = setInterval(() => {
|
|
4869
|
-
smartProgress.updateProgress();
|
|
4870
|
-
}, 200);
|
|
4680
|
+
async function uploadChunkWithAbort(sessionId, chunkIndex, chunkData, deviceId, signal, retryCount = 0) {
|
|
4871
4681
|
try {
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4682
|
+
if (signal.aborted) {
|
|
4683
|
+
throw new Error("Request cancelled");
|
|
4684
|
+
}
|
|
4685
|
+
const form = new import_form_data2.default();
|
|
4686
|
+
form.append("session_id", sessionId);
|
|
4687
|
+
form.append("chunk_index", chunkIndex.toString());
|
|
4688
|
+
form.append("uid", deviceId);
|
|
4689
|
+
form.append("chunk", chunkData, {
|
|
4690
|
+
filename: `chunk_${chunkIndex}`,
|
|
4691
|
+
contentType: "application/octet-stream"
|
|
4877
4692
|
});
|
|
4878
4693
|
const response = await axios_default.post(
|
|
4879
|
-
`${
|
|
4880
|
-
|
|
4694
|
+
`${IPFS_API_URL}/chunk/upload`,
|
|
4695
|
+
form,
|
|
4881
4696
|
{
|
|
4882
|
-
headers: {
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
timeout: 18e5
|
|
4886
|
-
// 30 minutes timeout
|
|
4697
|
+
headers: { ...form.getHeaders() },
|
|
4698
|
+
timeout: TIMEOUT,
|
|
4699
|
+
signal
|
|
4887
4700
|
}
|
|
4888
4701
|
);
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
if (!trace_id) {
|
|
4893
|
-
smartProgress.fail("No request id received from server");
|
|
4894
|
-
clearInterval(timeInterval);
|
|
4895
|
-
return null;
|
|
4896
|
-
}
|
|
4897
|
-
smartProgress.updateDisplay();
|
|
4898
|
-
const uploadResult = await pollUploadStatus(
|
|
4899
|
-
trace_id,
|
|
4900
|
-
deviceId,
|
|
4901
|
-
smartProgress,
|
|
4902
|
-
startTime
|
|
4903
|
-
);
|
|
4904
|
-
if (!uploadResult) {
|
|
4905
|
-
clearInterval(timeInterval);
|
|
4906
|
-
return null;
|
|
4907
|
-
}
|
|
4908
|
-
const fileItem = uploadResult.upload_rst;
|
|
4909
|
-
if (fileItem) {
|
|
4910
|
-
const uploadData = {
|
|
4911
|
-
path: filePath,
|
|
4912
|
-
filename: fileName,
|
|
4913
|
-
contentHash: fileItem.Hash,
|
|
4914
|
-
previewHash: null,
|
|
4915
|
-
size: sizeCheck.size,
|
|
4916
|
-
fileCount: 1,
|
|
4917
|
-
isDirectory: false,
|
|
4918
|
-
shortUrl: fileItem.ShortUrl || null
|
|
4919
|
-
};
|
|
4920
|
-
saveUploadHistory(uploadData);
|
|
4921
|
-
smartProgress.complete(trace_id);
|
|
4922
|
-
clearInterval(timeInterval);
|
|
4923
|
-
return {
|
|
4924
|
-
hash: fileItem.Hash,
|
|
4925
|
-
shortUrl: fileItem.ShortUrl
|
|
4926
|
-
};
|
|
4702
|
+
const { code, msg, data } = response.data;
|
|
4703
|
+
if (code === 200 && data) {
|
|
4704
|
+
return data;
|
|
4927
4705
|
}
|
|
4928
|
-
|
|
4929
|
-
console.log(
|
|
4930
|
-
import_chalk2.default.red(`
|
|
4931
|
-
\u274C File upload failed: File hash not found in response`)
|
|
4932
|
-
);
|
|
4933
|
-
console.log(import_chalk2.default.yellow(`
|
|
4934
|
-
\u{1F4CB} Error diagnosis information:`));
|
|
4935
|
-
console.log(import_chalk2.default.gray(` - File name: ${fileName}`));
|
|
4936
|
-
console.log(
|
|
4937
|
-
import_chalk2.default.gray(` - Name returned by IPFS: ${uploadResult.upload_rst.Name}`)
|
|
4938
|
-
);
|
|
4939
|
-
console.log(import_chalk2.default.blue(`
|
|
4940
|
-
\u{1F527} Solutions:`));
|
|
4941
|
-
console.log(import_chalk2.default.gray(` 1. Check if file is corrupted or unreadable`));
|
|
4942
|
-
console.log(import_chalk2.default.gray(` 2. Check network connection stability`));
|
|
4943
|
-
console.log(import_chalk2.default.gray(` 3. Try uploading a smaller file for testing`));
|
|
4944
|
-
clearInterval(timeInterval);
|
|
4945
|
-
return null;
|
|
4706
|
+
throw new Error(`Chunk upload failed: ${msg} (code: ${code})`);
|
|
4946
4707
|
} catch (error) {
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4708
|
+
if (error.name === "CanceledError" || signal.aborted) {
|
|
4709
|
+
throw new Error("Request cancelled");
|
|
4710
|
+
}
|
|
4711
|
+
if (retryCount < MAX_RETRIES) {
|
|
4712
|
+
await delayWithAbortCheck(RETRY_DELAY, signal);
|
|
4713
|
+
return uploadChunkWithAbort(
|
|
4714
|
+
sessionId,
|
|
4715
|
+
chunkIndex,
|
|
4716
|
+
chunkData,
|
|
4717
|
+
deviceId,
|
|
4718
|
+
signal,
|
|
4719
|
+
retryCount + 1
|
|
4953
4720
|
);
|
|
4954
|
-
smartProgress.fail(errorMessage);
|
|
4955
|
-
console.log(import_chalk2.default.red(`
|
|
4956
|
-
\u274C ${errorMessage}`));
|
|
4957
|
-
return null;
|
|
4958
4721
|
}
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
smartProgress.fail(
|
|
4963
|
-
`Error: ${ERROR_CODES[errorCode]} (Code: ${errorCode})`
|
|
4964
|
-
);
|
|
4965
|
-
console.log(
|
|
4966
|
-
import_chalk2.default.red(`Error: ${ERROR_CODES[errorCode]} (Code: ${errorCode})`)
|
|
4967
|
-
);
|
|
4968
|
-
return null;
|
|
4969
|
-
}
|
|
4970
|
-
}
|
|
4971
|
-
smartProgress.fail(`Error: ${error.message}`);
|
|
4972
|
-
console.log(import_chalk2.default.red(`Error: ${error.message}`));
|
|
4973
|
-
return null;
|
|
4722
|
+
throw new Error(
|
|
4723
|
+
`Chunk ${chunkIndex + 1} upload failed after ${MAX_RETRIES} retries: ${error.message}`
|
|
4724
|
+
);
|
|
4974
4725
|
}
|
|
4975
4726
|
}
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
constructor(fileName, fileCount, totalSize, spinner) {
|
|
4989
|
-
this.fileName = fileName;
|
|
4990
|
-
this.fileCount = fileCount;
|
|
4991
|
-
this.totalSize = totalSize;
|
|
4992
|
-
this.spinner = spinner;
|
|
4993
|
-
this.timeConstant = this.calcTimeConstant(fileCount, totalSize);
|
|
4994
|
-
this.startTime = Date.now();
|
|
4995
|
-
this.uploadStartTime = 0;
|
|
4996
|
-
this.isUploading = false;
|
|
4997
|
-
this.isPolling = false;
|
|
4998
|
-
this.isCompleted = false;
|
|
4999
|
-
}
|
|
5000
|
-
// Calculate time constant based on file count and total size
|
|
5001
|
-
calcTimeConstant(fileCount, totalSize) {
|
|
5002
|
-
const base = 8e3;
|
|
5003
|
-
const countFactor = 0.3 * Math.log(1 + fileCount);
|
|
5004
|
-
const sizeFactor = 0.7 * Math.log(1 + totalSize / 1024 / 1024);
|
|
5005
|
-
const minTimeConstant = 15e3;
|
|
5006
|
-
const calculatedTimeConstant = base * (1 + countFactor + sizeFactor);
|
|
5007
|
-
return Math.max(calculatedTimeConstant, minTimeConstant);
|
|
5008
|
-
}
|
|
5009
|
-
// Calculate progress using exponential decay model with upper limit
|
|
5010
|
-
calculateProgress() {
|
|
5011
|
-
const elapsed = Date.now() - this.startTime;
|
|
5012
|
-
const rawProgress = 1 - Math.exp(-elapsed / this.timeConstant);
|
|
5013
|
-
const maxProgress = this.isPolling ? 0.95 : 0.9;
|
|
5014
|
-
return Math.min(rawProgress, maxProgress);
|
|
5015
|
-
}
|
|
5016
|
-
// Start upload phase
|
|
5017
|
-
startUpload() {
|
|
5018
|
-
this.isUploading = true;
|
|
5019
|
-
this.uploadStartTime = Date.now();
|
|
5020
|
-
}
|
|
5021
|
-
// Start polling phase
|
|
5022
|
-
startPolling() {
|
|
5023
|
-
this.isPolling = true;
|
|
5024
|
-
this.isUploading = false;
|
|
5025
|
-
}
|
|
5026
|
-
// Update progress display
|
|
5027
|
-
update() {
|
|
5028
|
-
if (this.isCompleted) {
|
|
4727
|
+
async function delayWithAbortCheck(delay, signal) {
|
|
4728
|
+
return new Promise((resolve, reject) => {
|
|
4729
|
+
const timeoutId = setTimeout(() => {
|
|
4730
|
+
if (signal.aborted) {
|
|
4731
|
+
reject(new Error("Request cancelled"));
|
|
4732
|
+
} else {
|
|
4733
|
+
resolve();
|
|
4734
|
+
}
|
|
4735
|
+
}, delay);
|
|
4736
|
+
if (signal.aborted) {
|
|
4737
|
+
clearTimeout(timeoutId);
|
|
4738
|
+
reject(new Error("Request cancelled"));
|
|
5029
4739
|
return;
|
|
5030
4740
|
}
|
|
5031
|
-
const
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
4741
|
+
const checkInterval = setInterval(() => {
|
|
4742
|
+
if (signal.aborted) {
|
|
4743
|
+
clearTimeout(timeoutId);
|
|
4744
|
+
clearInterval(checkInterval);
|
|
4745
|
+
reject(new Error("Request cancelled"));
|
|
4746
|
+
}
|
|
4747
|
+
}, 50);
|
|
4748
|
+
});
|
|
4749
|
+
}
|
|
4750
|
+
async function uploadFileChunks(filePath, sessionId, totalChunks, chunkSize, deviceId, progressBar) {
|
|
4751
|
+
const fileData = import_fs_extra3.default.readFileSync(filePath);
|
|
4752
|
+
const abortController = new AbortController();
|
|
4753
|
+
let completedCount = 0;
|
|
4754
|
+
let hasFatalError = false;
|
|
4755
|
+
let fatalError = null;
|
|
4756
|
+
const uploadTasks = Array.from({ length: totalChunks }, (_, chunkIndex) => {
|
|
4757
|
+
const start = chunkIndex * chunkSize;
|
|
4758
|
+
const end = Math.min(start + chunkSize, fileData.length);
|
|
4759
|
+
const chunkData = fileData.slice(start, end);
|
|
4760
|
+
return async () => {
|
|
4761
|
+
if (abortController.signal.aborted) return;
|
|
4762
|
+
try {
|
|
4763
|
+
await uploadChunkWithAbort(
|
|
4764
|
+
sessionId,
|
|
4765
|
+
chunkIndex,
|
|
4766
|
+
chunkData,
|
|
4767
|
+
deviceId,
|
|
4768
|
+
abortController.signal
|
|
4769
|
+
);
|
|
4770
|
+
if (abortController.signal.aborted) return;
|
|
4771
|
+
completedCount++;
|
|
4772
|
+
progressBar.updateProgress(completedCount, totalChunks);
|
|
4773
|
+
} catch (error) {
|
|
4774
|
+
if (error.name === "AbortError" || abortController.signal.aborted) {
|
|
4775
|
+
return;
|
|
4776
|
+
}
|
|
4777
|
+
hasFatalError = true;
|
|
4778
|
+
fatalError = `Chunk ${chunkIndex + 1}/${totalChunks} upload failed: ${error.message}`;
|
|
4779
|
+
abortController.abort();
|
|
4780
|
+
throw new Error(fatalError);
|
|
4781
|
+
}
|
|
4782
|
+
};
|
|
4783
|
+
});
|
|
4784
|
+
try {
|
|
4785
|
+
const results = await Promise.allSettled(uploadTasks.map((task) => task()));
|
|
4786
|
+
const failedResults = results.filter((result) => result.status === "rejected");
|
|
4787
|
+
if (failedResults.length > 0) {
|
|
4788
|
+
const firstFailure = failedResults[0];
|
|
4789
|
+
throw new Error(firstFailure.reason.message || "Error occurred during upload");
|
|
5042
4790
|
}
|
|
5043
|
-
|
|
5044
|
-
|
|
4791
|
+
if (hasFatalError) {
|
|
4792
|
+
throw new Error(fatalError || "Unknown error occurred during upload");
|
|
4793
|
+
}
|
|
4794
|
+
} catch (error) {
|
|
4795
|
+
throw fatalError ? new Error(fatalError) : error;
|
|
5045
4796
|
}
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
4797
|
+
}
|
|
4798
|
+
async function completeChunkUpload(sessionId, deviceId) {
|
|
4799
|
+
try {
|
|
4800
|
+
const response = await axios_default.post(
|
|
4801
|
+
`${IPFS_API_URL}/chunk/complete`,
|
|
4802
|
+
{ session_id: sessionId, uid: deviceId },
|
|
4803
|
+
{
|
|
4804
|
+
timeout: TIMEOUT,
|
|
4805
|
+
headers: { "Content-Type": "application/json" }
|
|
4806
|
+
}
|
|
4807
|
+
);
|
|
4808
|
+
const { code, msg, data } = response.data;
|
|
4809
|
+
if (code === 200 && data) {
|
|
4810
|
+
return data.trace_id;
|
|
5050
4811
|
}
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
let status = "";
|
|
5056
|
-
if (this.isUploading) {
|
|
5057
|
-
status = "uploading";
|
|
5058
|
-
} else if (this.isPolling) {
|
|
5059
|
-
status = "processing";
|
|
5060
|
-
} else {
|
|
5061
|
-
status = "preparing";
|
|
4812
|
+
throw new Error(`Complete upload failed: ${msg} (code: ${code})`);
|
|
4813
|
+
} catch (error) {
|
|
4814
|
+
if (axios_default.isAxiosError(error)) {
|
|
4815
|
+
throw new Error(`Network error: ${error.message}`);
|
|
5062
4816
|
}
|
|
5063
|
-
|
|
5064
|
-
this.spinner.text = `Uploading ${fileInfo} ${progressBar} ${duration} (${status})`;
|
|
4817
|
+
throw error;
|
|
5065
4818
|
}
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
4819
|
+
}
|
|
4820
|
+
async function getChunkStatus(sessionId, deviceId) {
|
|
4821
|
+
try {
|
|
4822
|
+
const response = await axios_default.get(
|
|
4823
|
+
`${IPFS_API_URL}/up_status`,
|
|
4824
|
+
{
|
|
4825
|
+
params: { trace_id: sessionId, uid: deviceId },
|
|
4826
|
+
timeout: TIMEOUT,
|
|
4827
|
+
headers: { "Content-Type": "application/json" }
|
|
4828
|
+
}
|
|
4829
|
+
);
|
|
4830
|
+
const { code, msg, data } = response.data;
|
|
4831
|
+
if (code === 200) {
|
|
4832
|
+
return data;
|
|
5070
4833
|
}
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
let status = "";
|
|
5076
|
-
if (this.isUploading) {
|
|
5077
|
-
status = "uploading";
|
|
5078
|
-
} else if (this.isPolling) {
|
|
5079
|
-
status = "processing";
|
|
5080
|
-
} else {
|
|
5081
|
-
status = "preparing";
|
|
4834
|
+
throw new Error(`Server returned error: ${msg} (code: ${code})`);
|
|
4835
|
+
} catch (error) {
|
|
4836
|
+
if (axios_default.isAxiosError(error)) {
|
|
4837
|
+
throw new Error(`Network error: ${error.message}`);
|
|
5082
4838
|
}
|
|
5083
|
-
|
|
5084
|
-
this.spinner.text = `Uploading ${fileInfo} ${progressBar} ${duration} (${status})`;
|
|
4839
|
+
throw error;
|
|
5085
4840
|
}
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
4841
|
+
}
|
|
4842
|
+
async function monitorChunkProgress(traceId, deviceId) {
|
|
4843
|
+
let consecutiveErrors = 0;
|
|
4844
|
+
const startTime = Date.now();
|
|
4845
|
+
while (Date.now() - startTime < MAX_POLL_TIME) {
|
|
4846
|
+
try {
|
|
4847
|
+
const status = await getChunkStatus(traceId, deviceId);
|
|
4848
|
+
consecutiveErrors = 0;
|
|
4849
|
+
if (status.is_ready && status.upload_rst.Hash) {
|
|
4850
|
+
return {
|
|
4851
|
+
hash: status.upload_rst.Hash,
|
|
4852
|
+
shortUrl: status.upload_rst.ShortUrl
|
|
4853
|
+
};
|
|
4854
|
+
}
|
|
4855
|
+
} catch (error) {
|
|
4856
|
+
consecutiveErrors++;
|
|
4857
|
+
if (consecutiveErrors > 10) {
|
|
4858
|
+
throw new Error(`Polling failed: ${error.message}`);
|
|
4859
|
+
}
|
|
4860
|
+
}
|
|
4861
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
|
5089
4862
|
}
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
4863
|
+
const maxPollTimeMinutes = Math.floor(MAX_POLL_TIME / (60 * 1e3));
|
|
4864
|
+
throw new Error(`Polling timeout after ${maxPollTimeMinutes} minutes`);
|
|
4865
|
+
}
|
|
4866
|
+
async function uploadDirectoryInChunks(directoryPath, deviceId) {
|
|
4867
|
+
const sizeCheck = checkDirectorySizeLimit(directoryPath);
|
|
4868
|
+
if (sizeCheck.exceeds) {
|
|
4869
|
+
throw new Error(
|
|
4870
|
+
`Directory ${directoryPath} exceeds size limit ${formatSize(sizeCheck.limit)} (size: ${formatSize(sizeCheck.size)})`
|
|
4871
|
+
);
|
|
5095
4872
|
}
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
4873
|
+
const progressBar = new StepProgressBar(import_path4.default.basename(directoryPath), true);
|
|
4874
|
+
try {
|
|
4875
|
+
progressBar.startStep(0, "Preparing compression");
|
|
4876
|
+
const compressedPath = await compressDirectory(directoryPath);
|
|
4877
|
+
progressBar.completeStep();
|
|
4878
|
+
progressBar.startStep(1, "Initializing session");
|
|
4879
|
+
const sessionInfo = await initChunkSession(compressedPath, deviceId, true);
|
|
4880
|
+
progressBar.completeStep();
|
|
4881
|
+
progressBar.startStep(2, "Chunk upload");
|
|
4882
|
+
await uploadFileChunks(
|
|
4883
|
+
compressedPath,
|
|
4884
|
+
sessionInfo.session_id,
|
|
4885
|
+
sessionInfo.total_chunks,
|
|
4886
|
+
sessionInfo.chunk_size,
|
|
4887
|
+
deviceId,
|
|
4888
|
+
progressBar
|
|
4889
|
+
);
|
|
4890
|
+
progressBar.completeStep();
|
|
4891
|
+
progressBar.startStep(3, "Completing upload");
|
|
4892
|
+
const traceId = await completeChunkUpload(sessionInfo.session_id, deviceId);
|
|
4893
|
+
progressBar.completeStep();
|
|
4894
|
+
progressBar.startStep(4, "Waiting for processing");
|
|
4895
|
+
const result = await monitorChunkProgress(traceId, deviceId);
|
|
4896
|
+
progressBar.completeStep();
|
|
4897
|
+
try {
|
|
4898
|
+
import_fs_extra3.default.unlinkSync(compressedPath);
|
|
4899
|
+
} catch (error) {
|
|
5100
4900
|
}
|
|
5101
|
-
const
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
4901
|
+
const uploadData = {
|
|
4902
|
+
path: directoryPath,
|
|
4903
|
+
filename: import_path4.default.basename(directoryPath),
|
|
4904
|
+
contentHash: (result == null ? void 0 : result.hash) || "unknown",
|
|
4905
|
+
size: sizeCheck.size,
|
|
4906
|
+
fileCount: 0,
|
|
4907
|
+
isDirectory: true,
|
|
4908
|
+
shortUrl: (result == null ? void 0 : result.shortUrl) || null
|
|
4909
|
+
};
|
|
4910
|
+
saveUploadHistory(uploadData);
|
|
4911
|
+
if (!(result == null ? void 0 : result.hash)) {
|
|
4912
|
+
throw new Error("Server did not return valid hash value");
|
|
5111
4913
|
}
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
4914
|
+
progressBar.complete();
|
|
4915
|
+
return result;
|
|
4916
|
+
} catch (error) {
|
|
4917
|
+
progressBar.fail(error.message);
|
|
4918
|
+
throw error;
|
|
5116
4919
|
}
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
return `[${filled}${empty}] ${Math.round(percentage * 100)}%`;
|
|
4920
|
+
}
|
|
4921
|
+
async function uploadFileInChunks(filePath, deviceId) {
|
|
4922
|
+
const sizeCheck = checkFileSizeLimit(filePath);
|
|
4923
|
+
if (sizeCheck.exceeds) {
|
|
4924
|
+
throw new Error(
|
|
4925
|
+
`File ${filePath} exceeds size limit ${formatSize(sizeCheck.limit)} (size: ${formatSize(sizeCheck.size)})`
|
|
4926
|
+
);
|
|
5125
4927
|
}
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
4928
|
+
const fileName = import_path4.default.basename(filePath);
|
|
4929
|
+
const progressBar = new StepProgressBar(fileName, false);
|
|
4930
|
+
try {
|
|
4931
|
+
progressBar.startStep(0, "Initializing session");
|
|
4932
|
+
const sessionInfo = await initChunkSession(filePath, deviceId, false);
|
|
4933
|
+
progressBar.completeStep();
|
|
4934
|
+
progressBar.startStep(1, "Chunk upload");
|
|
4935
|
+
await uploadFileChunks(
|
|
4936
|
+
filePath,
|
|
4937
|
+
sessionInfo.session_id,
|
|
4938
|
+
sessionInfo.total_chunks,
|
|
4939
|
+
sessionInfo.chunk_size,
|
|
4940
|
+
deviceId,
|
|
4941
|
+
progressBar
|
|
4942
|
+
);
|
|
4943
|
+
progressBar.completeStep();
|
|
4944
|
+
progressBar.startStep(2, "Completing upload");
|
|
4945
|
+
const traceId = await completeChunkUpload(sessionInfo.session_id, deviceId);
|
|
4946
|
+
progressBar.completeStep();
|
|
4947
|
+
progressBar.startStep(3, "Waiting for processing");
|
|
4948
|
+
const result = await monitorChunkProgress(traceId, deviceId);
|
|
4949
|
+
progressBar.completeStep();
|
|
4950
|
+
const uploadData = {
|
|
4951
|
+
path: filePath,
|
|
4952
|
+
filename: fileName,
|
|
4953
|
+
contentHash: (result == null ? void 0 : result.hash) || "unknown",
|
|
4954
|
+
previewHash: null,
|
|
4955
|
+
size: sizeCheck.size,
|
|
4956
|
+
fileCount: 1,
|
|
4957
|
+
isDirectory: false,
|
|
4958
|
+
shortUrl: (result == null ? void 0 : result.shortUrl) || null
|
|
4959
|
+
};
|
|
4960
|
+
saveUploadHistory(uploadData);
|
|
4961
|
+
if (!(result == null ? void 0 : result.hash)) {
|
|
4962
|
+
throw new Error("Server did not return valid hash value");
|
|
5139
4963
|
}
|
|
4964
|
+
progressBar.complete();
|
|
4965
|
+
return result;
|
|
4966
|
+
} catch (error) {
|
|
4967
|
+
progressBar.fail(error.message);
|
|
4968
|
+
throw error;
|
|
5140
4969
|
}
|
|
5141
|
-
}
|
|
5142
|
-
async function
|
|
4970
|
+
}
|
|
4971
|
+
async function uploadToIpfs2_default(filePath) {
|
|
5143
4972
|
const deviceId = getDeviceId();
|
|
5144
4973
|
if (!deviceId) {
|
|
5145
4974
|
throw new Error("Device ID not found");
|
|
5146
4975
|
}
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
const result = await uploadFile(filePath, deviceId);
|
|
5157
|
-
if (result) {
|
|
5158
|
-
contentHash = result.hash;
|
|
5159
|
-
shortUrl = result.shortUrl || "";
|
|
4976
|
+
try {
|
|
4977
|
+
const isDirectory = import_fs_extra3.default.statSync(filePath).isDirectory();
|
|
4978
|
+
const result = isDirectory ? await uploadDirectoryInChunks(filePath, deviceId) : await uploadFileInChunks(filePath, deviceId);
|
|
4979
|
+
if (result == null ? void 0 : result.hash) {
|
|
4980
|
+
return {
|
|
4981
|
+
contentHash: result.hash,
|
|
4982
|
+
previewHash: null,
|
|
4983
|
+
shortUrl: result.shortUrl
|
|
4984
|
+
};
|
|
5160
4985
|
}
|
|
4986
|
+
return null;
|
|
4987
|
+
} catch (error) {
|
|
4988
|
+
return null;
|
|
5161
4989
|
}
|
|
5162
|
-
if (contentHash) {
|
|
5163
|
-
return {
|
|
5164
|
-
contentHash,
|
|
5165
|
-
previewHash: null,
|
|
5166
|
-
shortUrl
|
|
5167
|
-
};
|
|
5168
|
-
}
|
|
5169
|
-
return null;
|
|
5170
4990
|
}
|
|
5171
4991
|
|
|
5172
4992
|
// bin/upload.ts
|
|
@@ -5195,7 +5015,7 @@ function checkPathSync(inputPath) {
|
|
|
5195
5015
|
}
|
|
5196
5016
|
return null;
|
|
5197
5017
|
} catch (error) {
|
|
5198
|
-
console.error(
|
|
5018
|
+
console.error(import_chalk2.default.red(`error checking path: ${error.message}`));
|
|
5199
5019
|
return null;
|
|
5200
5020
|
}
|
|
5201
5021
|
}
|
|
@@ -5214,26 +5034,27 @@ var upload_default = async (options) => {
|
|
|
5214
5034
|
if (argPath && !argPath.startsWith("-")) {
|
|
5215
5035
|
const absolutePath = checkPathSync(argPath);
|
|
5216
5036
|
if (!absolutePath) {
|
|
5217
|
-
console.log(
|
|
5037
|
+
console.log(import_chalk2.default.red(`path ${argPath} does not exist`));
|
|
5218
5038
|
return;
|
|
5219
5039
|
}
|
|
5220
|
-
console.log(
|
|
5040
|
+
console.log(import_chalk2.default.blue(`uploading ${absolutePath} to ipfs...`));
|
|
5221
5041
|
try {
|
|
5222
|
-
const result = await
|
|
5042
|
+
const result = await uploadToIpfs2_default(absolutePath);
|
|
5223
5043
|
if (result) {
|
|
5224
5044
|
const encryptedCID = encryptHash(result.contentHash, secretKey);
|
|
5225
5045
|
console.log(
|
|
5226
|
-
|
|
5046
|
+
import_chalk2.default.cyan(
|
|
5227
5047
|
import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
|
|
5228
5048
|
)
|
|
5229
5049
|
);
|
|
5230
|
-
console.log(
|
|
5231
|
-
console.log(
|
|
5050
|
+
console.log(import_chalk2.default.cyan(`URL:`));
|
|
5051
|
+
console.log(import_chalk2.default.cyan(`${URL2}${encryptedCID}`));
|
|
5052
|
+
console.log(import_chalk2.default.green("\n\u{1F389} upload successful, program exit"));
|
|
5232
5053
|
}
|
|
5233
5054
|
} catch (error) {
|
|
5234
|
-
console.error(
|
|
5055
|
+
console.error(import_chalk2.default.red(`Error: ${error.message}`));
|
|
5235
5056
|
}
|
|
5236
|
-
|
|
5057
|
+
process.exit(0);
|
|
5237
5058
|
}
|
|
5238
5059
|
const answer = await import_inquirer.default.prompt([
|
|
5239
5060
|
{
|
|
@@ -5245,44 +5066,46 @@ var upload_default = async (options) => {
|
|
|
5245
5066
|
if (answer.path) {
|
|
5246
5067
|
const absolutePath = checkPathSync(answer.path);
|
|
5247
5068
|
if (!absolutePath) {
|
|
5248
|
-
console.log(
|
|
5069
|
+
console.log(import_chalk2.default.red(`path ${answer.path} does not exist`));
|
|
5249
5070
|
return;
|
|
5250
5071
|
}
|
|
5251
|
-
console.log(
|
|
5072
|
+
console.log(import_chalk2.default.blue(`uploading ${absolutePath} to ipfs...`));
|
|
5252
5073
|
try {
|
|
5253
|
-
const result = await
|
|
5074
|
+
const result = await uploadToIpfs2_default(absolutePath);
|
|
5254
5075
|
if (result) {
|
|
5255
5076
|
const encryptedCID = encryptHash(result.contentHash, secretKey);
|
|
5256
5077
|
console.log(
|
|
5257
|
-
|
|
5078
|
+
import_chalk2.default.cyan(
|
|
5258
5079
|
import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
|
|
5259
5080
|
)
|
|
5260
5081
|
);
|
|
5261
|
-
console.log(
|
|
5262
|
-
console.log(
|
|
5082
|
+
console.log(import_chalk2.default.cyan(`URL:`));
|
|
5083
|
+
console.log(import_chalk2.default.cyan(`${URL2}${encryptedCID}`));
|
|
5084
|
+
console.log(import_chalk2.default.green("\n\u{1F389} upload successful, program exit"));
|
|
5263
5085
|
}
|
|
5264
5086
|
} catch (error) {
|
|
5265
|
-
console.error(
|
|
5087
|
+
console.error(import_chalk2.default.red(`Error: ${error.message}`));
|
|
5266
5088
|
}
|
|
5089
|
+
process.exit(0);
|
|
5267
5090
|
}
|
|
5268
5091
|
} catch (error) {
|
|
5269
|
-
console.error(
|
|
5092
|
+
console.error(import_chalk2.default.red(`error executing: ${error.message}`));
|
|
5270
5093
|
console.error(error.stack);
|
|
5271
5094
|
}
|
|
5272
5095
|
};
|
|
5273
5096
|
|
|
5274
5097
|
// bin/remove.ts
|
|
5275
|
-
var
|
|
5098
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
5276
5099
|
var import_inquirer2 = __toESM(require("inquirer"));
|
|
5277
5100
|
var import_figlet2 = __toESM(require("figlet"));
|
|
5278
5101
|
|
|
5279
5102
|
// bin/utils/removeFromIpfs.ts
|
|
5280
|
-
var
|
|
5281
|
-
var
|
|
5103
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
5104
|
+
var ipfsApiUrl = "https://pinme.dev/api/v3";
|
|
5282
5105
|
async function removeFromIpfs(value, type = "hash") {
|
|
5283
5106
|
try {
|
|
5284
5107
|
const uid = getDeviceId();
|
|
5285
|
-
console.log(
|
|
5108
|
+
console.log(import_chalk3.default.blue(`Removing content from IPFS: ${value}...`));
|
|
5286
5109
|
const queryParams = new URLSearchParams({
|
|
5287
5110
|
uid
|
|
5288
5111
|
});
|
|
@@ -5291,37 +5114,37 @@ async function removeFromIpfs(value, type = "hash") {
|
|
|
5291
5114
|
} else {
|
|
5292
5115
|
queryParams.append("arg", value);
|
|
5293
5116
|
}
|
|
5294
|
-
const response = await axios_default.post(`${
|
|
5117
|
+
const response = await axios_default.post(`${ipfsApiUrl}/block/rm?${queryParams.toString()}`, {
|
|
5295
5118
|
timeout: 3e4
|
|
5296
5119
|
// 30 seconds timeout
|
|
5297
5120
|
});
|
|
5298
5121
|
const { code, msg, data } = response.data;
|
|
5299
5122
|
if (code === 200) {
|
|
5300
|
-
console.log(
|
|
5301
|
-
console.log(
|
|
5123
|
+
console.log(import_chalk3.default.green("\u2713 Removal successful!"));
|
|
5124
|
+
console.log(import_chalk3.default.cyan(`Content ${type}: ${value} has been removed from IPFS network`));
|
|
5302
5125
|
return true;
|
|
5303
5126
|
} else {
|
|
5304
|
-
console.log(
|
|
5305
|
-
console.log(
|
|
5127
|
+
console.log(import_chalk3.default.red("\u2717 Removal failed"));
|
|
5128
|
+
console.log(import_chalk3.default.red(`Error: ${msg || "Unknown error occurred"}`));
|
|
5306
5129
|
return false;
|
|
5307
5130
|
}
|
|
5308
5131
|
} catch (error) {
|
|
5309
|
-
console.log(
|
|
5132
|
+
console.log(import_chalk3.default.red("\u2717 Removal failed", error));
|
|
5310
5133
|
if (error.response) {
|
|
5311
5134
|
const { status, data } = error.response;
|
|
5312
|
-
console.log(
|
|
5135
|
+
console.log(import_chalk3.default.red(`HTTP Error ${status}: ${(data == null ? void 0 : data.msg) || "Server error"}`));
|
|
5313
5136
|
if (status === 404) {
|
|
5314
|
-
console.log(
|
|
5137
|
+
console.log(import_chalk3.default.yellow("Content not found on the network or already removed"));
|
|
5315
5138
|
} else if (status === 403) {
|
|
5316
|
-
console.log(
|
|
5139
|
+
console.log(import_chalk3.default.yellow("Permission denied - you may not have access to remove this content"));
|
|
5317
5140
|
} else if (status === 500) {
|
|
5318
|
-
console.log(
|
|
5141
|
+
console.log(import_chalk3.default.yellow("Server internal error - please try again later"));
|
|
5319
5142
|
}
|
|
5320
5143
|
} else if (error.request) {
|
|
5321
|
-
console.log(
|
|
5322
|
-
console.log(
|
|
5144
|
+
console.log(import_chalk3.default.red("Network error: Unable to connect to IPFS service"));
|
|
5145
|
+
console.log(import_chalk3.default.yellow("Please check your internet connection and try again"));
|
|
5323
5146
|
} else {
|
|
5324
|
-
console.log(
|
|
5147
|
+
console.log(import_chalk3.default.red(`Error: ${error.message}`));
|
|
5325
5148
|
}
|
|
5326
5149
|
return false;
|
|
5327
5150
|
}
|
|
@@ -5380,30 +5203,30 @@ var remove_default = async (options) => {
|
|
|
5380
5203
|
if (argHash && !argHash.startsWith("-")) {
|
|
5381
5204
|
const parsedInput = parseInput(argHash);
|
|
5382
5205
|
if (!parsedInput) {
|
|
5383
|
-
console.log(
|
|
5384
|
-
console.log(
|
|
5385
|
-
console.log(
|
|
5386
|
-
console.log(
|
|
5387
|
-
console.log(
|
|
5388
|
-
console.log(
|
|
5206
|
+
console.log(import_chalk4.default.red(`Invalid input format: ${argHash}`));
|
|
5207
|
+
console.log(import_chalk4.default.yellow("Supported formats:"));
|
|
5208
|
+
console.log(import_chalk4.default.yellow(" - IPFS hash: bafybeig..."));
|
|
5209
|
+
console.log(import_chalk4.default.yellow(" - Full URL: https://bafybeig....pinme.dev"));
|
|
5210
|
+
console.log(import_chalk4.default.yellow(" - Subname: 3abt6ztu"));
|
|
5211
|
+
console.log(import_chalk4.default.yellow(" - Subname URL: https://3abt6ztu.pinit.eth.limo"));
|
|
5389
5212
|
return;
|
|
5390
5213
|
}
|
|
5391
5214
|
try {
|
|
5392
5215
|
const success = await removeFromIpfs(parsedInput.value, parsedInput.type);
|
|
5393
5216
|
if (success) {
|
|
5394
5217
|
console.log(
|
|
5395
|
-
|
|
5218
|
+
import_chalk4.default.cyan(
|
|
5396
5219
|
import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
|
|
5397
5220
|
)
|
|
5398
5221
|
);
|
|
5399
5222
|
}
|
|
5400
5223
|
} catch (error) {
|
|
5401
|
-
console.error(
|
|
5224
|
+
console.error(import_chalk4.default.red(`Error: ${error.message}`));
|
|
5402
5225
|
}
|
|
5403
5226
|
return;
|
|
5404
5227
|
}
|
|
5405
|
-
console.log(
|
|
5406
|
-
console.log(
|
|
5228
|
+
console.log(import_chalk4.default.yellow("\u26A0\uFE0F Warning: This action will permanently remove the content from IPFS network"));
|
|
5229
|
+
console.log(import_chalk4.default.yellow("\u26A0\uFE0F Make sure you have the correct IPFS hash"));
|
|
5407
5230
|
console.log("");
|
|
5408
5231
|
const confirmAnswer = await import_inquirer2.default.prompt([
|
|
5409
5232
|
{
|
|
@@ -5414,7 +5237,7 @@ var remove_default = async (options) => {
|
|
|
5414
5237
|
}
|
|
5415
5238
|
]);
|
|
5416
5239
|
if (!confirmAnswer.confirm) {
|
|
5417
|
-
console.log(
|
|
5240
|
+
console.log(import_chalk4.default.yellow("Operation cancelled"));
|
|
5418
5241
|
return;
|
|
5419
5242
|
}
|
|
5420
5243
|
const answer = await import_inquirer2.default.prompt([
|
|
@@ -5437,7 +5260,7 @@ var remove_default = async (options) => {
|
|
|
5437
5260
|
if (answer.input) {
|
|
5438
5261
|
const parsedInput = parseInput(answer.input.trim());
|
|
5439
5262
|
if (!parsedInput) {
|
|
5440
|
-
console.log(
|
|
5263
|
+
console.log(import_chalk4.default.red("Invalid input format"));
|
|
5441
5264
|
return;
|
|
5442
5265
|
}
|
|
5443
5266
|
const finalConfirm = await import_inquirer2.default.prompt([
|
|
@@ -5449,24 +5272,24 @@ var remove_default = async (options) => {
|
|
|
5449
5272
|
}
|
|
5450
5273
|
]);
|
|
5451
5274
|
if (!finalConfirm.confirm) {
|
|
5452
|
-
console.log(
|
|
5275
|
+
console.log(import_chalk4.default.yellow("Operation cancelled"));
|
|
5453
5276
|
return;
|
|
5454
5277
|
}
|
|
5455
5278
|
try {
|
|
5456
5279
|
const success = await removeFromIpfs(parsedInput.value, parsedInput.type);
|
|
5457
5280
|
if (success) {
|
|
5458
5281
|
console.log(
|
|
5459
|
-
|
|
5282
|
+
import_chalk4.default.cyan(
|
|
5460
5283
|
import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
|
|
5461
5284
|
)
|
|
5462
5285
|
);
|
|
5463
5286
|
}
|
|
5464
5287
|
} catch (error) {
|
|
5465
|
-
console.error(
|
|
5288
|
+
console.error(import_chalk4.default.red(`Error: ${error.message}`));
|
|
5466
5289
|
}
|
|
5467
5290
|
}
|
|
5468
5291
|
} catch (error) {
|
|
5469
|
-
console.error(
|
|
5292
|
+
console.error(import_chalk4.default.red(`Error executing remove command: ${error.message}`));
|
|
5470
5293
|
console.error(error.stack);
|
|
5471
5294
|
}
|
|
5472
5295
|
};
|
|
@@ -5475,11 +5298,11 @@ var remove_default = async (options) => {
|
|
|
5475
5298
|
import_dotenv.default.config();
|
|
5476
5299
|
function showBanner() {
|
|
5477
5300
|
console.log(
|
|
5478
|
-
|
|
5301
|
+
import_chalk5.default.cyan(
|
|
5479
5302
|
import_figlet3.default.textSync("Pinme", { horizontalLayout: "full" })
|
|
5480
5303
|
)
|
|
5481
5304
|
);
|
|
5482
|
-
console.log(
|
|
5305
|
+
console.log(import_chalk5.default.cyan("A command-line tool for uploading files to IPFS\n"));
|
|
5483
5306
|
}
|
|
5484
5307
|
var program = new import_commander.Command();
|
|
5485
5308
|
program.name("pinme").version(version).option("-v, --version", "output the current version");
|