pinme 2.0.2-beta.5 → 2.0.2-beta.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/index.js +78 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1523,7 +1523,7 @@ var import_chalk25 = __toESM(require("chalk"));
|
|
|
1523
1523
|
var import_figlet5 = __toESM(require("figlet"));
|
|
1524
1524
|
|
|
1525
1525
|
// package.json
|
|
1526
|
-
var version = "2.0.2-beta.
|
|
1526
|
+
var version = "2.0.2-beta.7";
|
|
1527
1527
|
|
|
1528
1528
|
// bin/upload.ts
|
|
1529
1529
|
var import_path6 = __toESM(require("path"));
|
|
@@ -5439,6 +5439,47 @@ var POLL_INTERVAL = APP_CONFIG.upload.pollIntervalMs;
|
|
|
5439
5439
|
var PROGRESS_UPDATE_INTERVAL = 200;
|
|
5440
5440
|
var EXPECTED_UPLOAD_TIME = 6e4;
|
|
5441
5441
|
var MAX_PROGRESS = 0.9;
|
|
5442
|
+
function extractAxiosErrorMessage(error) {
|
|
5443
|
+
var _a2, _b, _c, _d;
|
|
5444
|
+
const responseData = (_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.data;
|
|
5445
|
+
if (typeof responseData === "string" && responseData.trim()) {
|
|
5446
|
+
return responseData.trim();
|
|
5447
|
+
}
|
|
5448
|
+
const message = (responseData == null ? void 0 : responseData.msg) || (responseData == null ? void 0 : responseData.message) || (responseData == null ? void 0 : responseData.error) || ((_b = responseData == null ? void 0 : responseData.data) == null ? void 0 : _b.msg) || ((_c = responseData == null ? void 0 : responseData.data) == null ? void 0 : _c.message) || ((_d = responseData == null ? void 0 : responseData.data) == null ? void 0 : _d.error);
|
|
5449
|
+
if (typeof message === "string" && message.trim()) {
|
|
5450
|
+
return message.trim();
|
|
5451
|
+
}
|
|
5452
|
+
return (error == null ? void 0 : error.message) || "Unknown network error";
|
|
5453
|
+
}
|
|
5454
|
+
function formatAxiosError(prefix, error) {
|
|
5455
|
+
var _a2;
|
|
5456
|
+
const status = (_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status;
|
|
5457
|
+
const message = extractAxiosErrorMessage(error);
|
|
5458
|
+
if (status) {
|
|
5459
|
+
return new Error(`${prefix}: ${message} (status: ${status})`);
|
|
5460
|
+
}
|
|
5461
|
+
return new Error(`${prefix}: ${message}`);
|
|
5462
|
+
}
|
|
5463
|
+
function logAxiosErrorDetails(prefix, error) {
|
|
5464
|
+
var _a2, _b;
|
|
5465
|
+
const status = (_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status;
|
|
5466
|
+
const responseData = (_b = error == null ? void 0 : error.response) == null ? void 0 : _b.data;
|
|
5467
|
+
console.error(`[pinme upload] ${prefix}`);
|
|
5468
|
+
console.error(`[pinme upload] status: ${status ?? "unknown"}`);
|
|
5469
|
+
if (responseData === void 0) {
|
|
5470
|
+
console.error("[pinme upload] response: <empty>");
|
|
5471
|
+
return;
|
|
5472
|
+
}
|
|
5473
|
+
try {
|
|
5474
|
+
console.error(`[pinme upload] response: ${JSON.stringify(responseData)}`);
|
|
5475
|
+
} catch {
|
|
5476
|
+
console.error(`[pinme upload] response: ${String(responseData)}`);
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
function isStorageLimitError(error) {
|
|
5480
|
+
const message = extractAxiosErrorMessage(error).toLowerCase();
|
|
5481
|
+
return message.includes("storage space limit") || message.includes("space limit reached") || message.includes("storage limit reached") || message.includes("quota exceeded") || message.includes("insufficient storage");
|
|
5482
|
+
}
|
|
5442
5483
|
var StepProgressBar = class {
|
|
5443
5484
|
spinner;
|
|
5444
5485
|
fileName;
|
|
@@ -5577,24 +5618,35 @@ async function compressDirectory(sourcePath) {
|
|
|
5577
5618
|
}
|
|
5578
5619
|
});
|
|
5579
5620
|
}
|
|
5580
|
-
async function initChunkSession(filePath, deviceId, isDirectory = false) {
|
|
5621
|
+
async function initChunkSession(filePath, deviceId, options = {}, isDirectory = false) {
|
|
5622
|
+
var _a2;
|
|
5581
5623
|
const stats = import_fs_extra4.default.statSync(filePath);
|
|
5582
5624
|
const fileName = import_path5.default.basename(filePath);
|
|
5583
5625
|
const fileSize = stats.size;
|
|
5584
5626
|
const md5 = await calculateMD5(filePath);
|
|
5585
5627
|
try {
|
|
5628
|
+
const projectName = (_a2 = options.projectName) == null ? void 0 : _a2.trim();
|
|
5629
|
+
let authHeaders = {};
|
|
5630
|
+
const requestBody = {
|
|
5631
|
+
file_name: fileName,
|
|
5632
|
+
file_size: fileSize,
|
|
5633
|
+
md5,
|
|
5634
|
+
is_directory: isDirectory,
|
|
5635
|
+
uid: deviceId
|
|
5636
|
+
};
|
|
5637
|
+
if (projectName) {
|
|
5638
|
+
requestBody.project_name = projectName;
|
|
5639
|
+
authHeaders = getAuthHeaders();
|
|
5640
|
+
}
|
|
5586
5641
|
const response = await axios_default.post(
|
|
5587
5642
|
`${IPFS_API_URL}/chunk/init`,
|
|
5588
|
-
|
|
5589
|
-
file_name: fileName,
|
|
5590
|
-
file_size: fileSize,
|
|
5591
|
-
md5,
|
|
5592
|
-
is_directory: isDirectory,
|
|
5593
|
-
uid: deviceId
|
|
5594
|
-
},
|
|
5643
|
+
requestBody,
|
|
5595
5644
|
{
|
|
5596
5645
|
timeout: TIMEOUT,
|
|
5597
|
-
headers: {
|
|
5646
|
+
headers: {
|
|
5647
|
+
"Content-Type": "application/json",
|
|
5648
|
+
...authHeaders
|
|
5649
|
+
}
|
|
5598
5650
|
}
|
|
5599
5651
|
);
|
|
5600
5652
|
const { code, msg, data } = response.data;
|
|
@@ -5604,7 +5656,8 @@ async function initChunkSession(filePath, deviceId, isDirectory = false) {
|
|
|
5604
5656
|
throw new Error(`Session initialization failed: ${msg} (code: ${code})`);
|
|
5605
5657
|
} catch (error) {
|
|
5606
5658
|
if (axios_default.isAxiosError(error)) {
|
|
5607
|
-
|
|
5659
|
+
logAxiosErrorDetails("chunk/init failed", error);
|
|
5660
|
+
throw formatAxiosError("Session initialization failed", error);
|
|
5608
5661
|
}
|
|
5609
5662
|
throw error;
|
|
5610
5663
|
}
|
|
@@ -5640,6 +5693,10 @@ async function uploadChunkWithAbort(sessionId, chunkIndex, chunkData, deviceId,
|
|
|
5640
5693
|
if (error.name === "CanceledError" || signal.aborted) {
|
|
5641
5694
|
throw new Error("Request cancelled");
|
|
5642
5695
|
}
|
|
5696
|
+
if (axios_default.isAxiosError(error) && isStorageLimitError(error)) {
|
|
5697
|
+
logAxiosErrorDetails("chunk/upload failed", error);
|
|
5698
|
+
throw formatAxiosError("Chunk upload failed", error);
|
|
5699
|
+
}
|
|
5643
5700
|
if (retryCount < MAX_RETRIES) {
|
|
5644
5701
|
await delayWithAbortCheck(RETRY_DELAY, signal);
|
|
5645
5702
|
return uploadChunkWithAbort(
|
|
@@ -5651,6 +5708,10 @@ async function uploadChunkWithAbort(sessionId, chunkIndex, chunkData, deviceId,
|
|
|
5651
5708
|
retryCount + 1
|
|
5652
5709
|
);
|
|
5653
5710
|
}
|
|
5711
|
+
if (axios_default.isAxiosError(error)) {
|
|
5712
|
+
logAxiosErrorDetails("chunk/upload failed", error);
|
|
5713
|
+
throw formatAxiosError("Chunk upload failed", error);
|
|
5714
|
+
}
|
|
5654
5715
|
throw new Error(
|
|
5655
5716
|
`Chunk ${chunkIndex + 1} upload failed after ${MAX_RETRIES} retries: ${error.message}`
|
|
5656
5717
|
);
|
|
@@ -5762,7 +5823,8 @@ async function completeChunkUpload(sessionId, deviceId, options = {}) {
|
|
|
5762
5823
|
throw new Error(`Complete upload failed: ${msg} (code: ${code})`);
|
|
5763
5824
|
} catch (error) {
|
|
5764
5825
|
if (axios_default.isAxiosError(error)) {
|
|
5765
|
-
|
|
5826
|
+
logAxiosErrorDetails("chunk/complete failed", error);
|
|
5827
|
+
throw formatAxiosError("Complete upload failed", error);
|
|
5766
5828
|
}
|
|
5767
5829
|
throw error;
|
|
5768
5830
|
}
|
|
@@ -5792,7 +5854,8 @@ async function getChunkStatus(sessionId, deviceId, options = {}) {
|
|
|
5792
5854
|
throw new Error(`Server returned error: ${msg} (code: ${code})`);
|
|
5793
5855
|
} catch (error) {
|
|
5794
5856
|
if (axios_default.isAxiosError(error)) {
|
|
5795
|
-
|
|
5857
|
+
logAxiosErrorDetails("up_status failed", error);
|
|
5858
|
+
throw formatAxiosError("Upload status check failed", error);
|
|
5796
5859
|
}
|
|
5797
5860
|
throw error;
|
|
5798
5861
|
}
|
|
@@ -5851,7 +5914,7 @@ async function uploadDirectoryInChunks(directoryPath, deviceId, options = {}) {
|
|
|
5851
5914
|
const compressedPath = await compressDirectory(directoryPath);
|
|
5852
5915
|
progressBar.completeStep();
|
|
5853
5916
|
progressBar.startStep(1, "Initializing session");
|
|
5854
|
-
const sessionInfo = await initChunkSession(compressedPath, deviceId, true);
|
|
5917
|
+
const sessionInfo = await initChunkSession(compressedPath, deviceId, options, true);
|
|
5855
5918
|
progressBar.completeStep();
|
|
5856
5919
|
progressBar.startStep(2, "Chunk upload");
|
|
5857
5920
|
await uploadFileChunks(
|
|
@@ -5910,7 +5973,7 @@ async function uploadFileInChunks(filePath, deviceId, options = {}) {
|
|
|
5910
5973
|
const progressBar = new StepProgressBar(fileName, false);
|
|
5911
5974
|
try {
|
|
5912
5975
|
progressBar.startStep(0, "Initializing session");
|
|
5913
|
-
const sessionInfo = await initChunkSession(filePath, deviceId, false);
|
|
5976
|
+
const sessionInfo = await initChunkSession(filePath, deviceId, options, false);
|
|
5914
5977
|
progressBar.completeStep();
|
|
5915
5978
|
progressBar.startStep(1, "Chunk upload");
|
|
5916
5979
|
await uploadFileChunks(
|