@leeguoo/pwtk-network-debugger 1.1.0 → 1.2.0
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.cjs.js +3 -3
- package/dist/index.esm.js +155 -63
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -6671,17 +6671,10 @@ function decrypt(encryptedData, keyStr) {
|
|
|
6671
6671
|
return encryptedData;
|
|
6672
6672
|
}
|
|
6673
6673
|
class NetworkInterceptor {
|
|
6674
|
-
constructor(
|
|
6674
|
+
constructor() {
|
|
6675
6675
|
this.requests = /* @__PURE__ */ new Map();
|
|
6676
6676
|
this.listeners = [];
|
|
6677
6677
|
this.decryptConfig = { enabled: false };
|
|
6678
|
-
this.STORAGE_KEY = "network_debugger_requests";
|
|
6679
|
-
this.MAX_STORAGE_SIZE = 100;
|
|
6680
|
-
this.persistenceEnabled = true;
|
|
6681
|
-
this.persistenceEnabled = options.persistence !== false;
|
|
6682
|
-
if (this.persistenceEnabled) {
|
|
6683
|
-
this.loadFromStorage();
|
|
6684
|
-
}
|
|
6685
6678
|
this.interceptXHR();
|
|
6686
6679
|
this.interceptFetch();
|
|
6687
6680
|
}
|
|
@@ -6714,9 +6707,6 @@ class NetworkInterceptor {
|
|
|
6714
6707
|
}
|
|
6715
6708
|
clearRequests() {
|
|
6716
6709
|
this.requests.clear();
|
|
6717
|
-
if (this.persistenceEnabled) {
|
|
6718
|
-
this.clearStorage();
|
|
6719
|
-
}
|
|
6720
6710
|
}
|
|
6721
6711
|
generateRequestId() {
|
|
6722
6712
|
return Math.random().toString(36).substr(2, 9);
|
|
@@ -6781,37 +6771,6 @@ class NetworkInterceptor {
|
|
|
6781
6771
|
}
|
|
6782
6772
|
return null;
|
|
6783
6773
|
}
|
|
6784
|
-
// 持久化存储方法
|
|
6785
|
-
saveToStorage() {
|
|
6786
|
-
if (!this.persistenceEnabled) return;
|
|
6787
|
-
try {
|
|
6788
|
-
const requests = Array.from(this.requests.values()).sort((a, b) => b.timestamp - a.timestamp).slice(0, this.MAX_STORAGE_SIZE);
|
|
6789
|
-
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(requests));
|
|
6790
|
-
} catch (e) {
|
|
6791
|
-
console.warn("NetworkDebugger: Failed to save to localStorage:", e);
|
|
6792
|
-
}
|
|
6793
|
-
}
|
|
6794
|
-
loadFromStorage() {
|
|
6795
|
-
try {
|
|
6796
|
-
const stored = localStorage.getItem(this.STORAGE_KEY);
|
|
6797
|
-
if (stored) {
|
|
6798
|
-
const requests = JSON.parse(stored);
|
|
6799
|
-
requests.forEach((req) => {
|
|
6800
|
-
this.requests.set(req.id, req);
|
|
6801
|
-
});
|
|
6802
|
-
console.log(`NetworkDebugger: 从存储中恢复了 ${requests.length} 条请求记录`);
|
|
6803
|
-
}
|
|
6804
|
-
} catch (e) {
|
|
6805
|
-
console.warn("NetworkDebugger: Failed to load from localStorage:", e);
|
|
6806
|
-
}
|
|
6807
|
-
}
|
|
6808
|
-
clearStorage() {
|
|
6809
|
-
try {
|
|
6810
|
-
localStorage.removeItem(this.STORAGE_KEY);
|
|
6811
|
-
} catch (e) {
|
|
6812
|
-
console.warn("NetworkDebugger: Failed to clear storage:", e);
|
|
6813
|
-
}
|
|
6814
|
-
}
|
|
6815
6774
|
interceptXHR() {
|
|
6816
6775
|
const originalXHR = window.XMLHttpRequest;
|
|
6817
6776
|
const self2 = this;
|
|
@@ -6848,13 +6807,11 @@ class NetworkInterceptor {
|
|
|
6848
6807
|
if (decrypted !== null) {
|
|
6849
6808
|
requestData.decryptedRequest = decrypted;
|
|
6850
6809
|
self2.requests.set(requestId, requestData);
|
|
6851
|
-
self2.saveToStorage();
|
|
6852
6810
|
self2.notifyListeners(requestData);
|
|
6853
6811
|
}
|
|
6854
6812
|
}).catch((e) => console.warn("解密请求失败:", e));
|
|
6855
6813
|
}
|
|
6856
6814
|
self2.requests.set(requestId, requestData);
|
|
6857
|
-
self2.saveToStorage();
|
|
6858
6815
|
self2.notifyListeners(requestData);
|
|
6859
6816
|
return originalSend.call(this, body);
|
|
6860
6817
|
};
|
|
@@ -6887,13 +6844,11 @@ class NetworkInterceptor {
|
|
|
6887
6844
|
if (decrypted !== null) {
|
|
6888
6845
|
requestData.decryptedResponse = decrypted;
|
|
6889
6846
|
self2.requests.set(requestId, requestData);
|
|
6890
|
-
self2.saveToStorage();
|
|
6891
6847
|
self2.notifyListeners(requestData);
|
|
6892
6848
|
}
|
|
6893
6849
|
}).catch((e) => console.warn("解密响应失败:", e));
|
|
6894
6850
|
}
|
|
6895
6851
|
self2.requests.set(requestId, requestData);
|
|
6896
|
-
self2.saveToStorage();
|
|
6897
6852
|
self2.notifyListeners(requestData);
|
|
6898
6853
|
}
|
|
6899
6854
|
}
|
|
@@ -6951,13 +6906,11 @@ class NetworkInterceptor {
|
|
|
6951
6906
|
if (decrypted !== null) {
|
|
6952
6907
|
requestData.decryptedRequest = decrypted;
|
|
6953
6908
|
self2.requests.set(requestId, requestData);
|
|
6954
|
-
self2.saveToStorage();
|
|
6955
6909
|
self2.notifyListeners(requestData);
|
|
6956
6910
|
}
|
|
6957
6911
|
}).catch((e) => console.warn("解密请求失败:", e));
|
|
6958
6912
|
}
|
|
6959
6913
|
self2.requests.set(requestId, requestData);
|
|
6960
|
-
self2.saveToStorage();
|
|
6961
6914
|
self2.notifyListeners(requestData);
|
|
6962
6915
|
try {
|
|
6963
6916
|
const response = await originalFetch.call(this, input, init);
|
|
@@ -6988,7 +6941,6 @@ class NetworkInterceptor {
|
|
|
6988
6941
|
if (decrypted !== null) {
|
|
6989
6942
|
updatedRequestData.decryptedResponse = decrypted;
|
|
6990
6943
|
self2.requests.set(requestId, updatedRequestData);
|
|
6991
|
-
self2.saveToStorage();
|
|
6992
6944
|
self2.notifyListeners(updatedRequestData);
|
|
6993
6945
|
}
|
|
6994
6946
|
}).catch((e) => console.warn("解密响应失败:", e));
|
|
@@ -6997,7 +6949,6 @@ class NetworkInterceptor {
|
|
|
6997
6949
|
updatedRequestData.error = `Failed to read response: ${error}`;
|
|
6998
6950
|
}
|
|
6999
6951
|
self2.requests.set(requestId, updatedRequestData);
|
|
7000
|
-
self2.saveToStorage();
|
|
7001
6952
|
self2.notifyListeners(updatedRequestData);
|
|
7002
6953
|
}
|
|
7003
6954
|
return response;
|
|
@@ -7008,7 +6959,6 @@ class NetworkInterceptor {
|
|
|
7008
6959
|
updatedRequestData.error = error instanceof Error ? error.message : String(error);
|
|
7009
6960
|
updatedRequestData.duration = endTime - startTime;
|
|
7010
6961
|
self2.requests.set(requestId, updatedRequestData);
|
|
7011
|
-
self2.saveToStorage();
|
|
7012
6962
|
self2.notifyListeners(updatedRequestData);
|
|
7013
6963
|
}
|
|
7014
6964
|
throw error;
|
|
@@ -7330,6 +7280,7 @@ const styles = `
|
|
|
7330
7280
|
padding: 10px;
|
|
7331
7281
|
cursor: pointer;
|
|
7332
7282
|
transition: all 0.2s;
|
|
7283
|
+
position: relative;
|
|
7333
7284
|
}
|
|
7334
7285
|
|
|
7335
7286
|
.request-item:hover {
|
|
@@ -7479,6 +7430,27 @@ const styles = `
|
|
|
7479
7430
|
font-weight: bold;
|
|
7480
7431
|
}
|
|
7481
7432
|
|
|
7433
|
+
.share-btn {
|
|
7434
|
+
background: #2196F3;
|
|
7435
|
+
color: #fff;
|
|
7436
|
+
border: none;
|
|
7437
|
+
padding: 4px 8px;
|
|
7438
|
+
border-radius: 3px;
|
|
7439
|
+
font-size: 10px;
|
|
7440
|
+
margin-left: 8px;
|
|
7441
|
+
cursor: pointer;
|
|
7442
|
+
transition: all 0.2s;
|
|
7443
|
+
}
|
|
7444
|
+
|
|
7445
|
+
.share-btn:hover {
|
|
7446
|
+
background: #1976D2;
|
|
7447
|
+
transform: scale(1.1);
|
|
7448
|
+
}
|
|
7449
|
+
|
|
7450
|
+
.share-btn:active {
|
|
7451
|
+
transform: scale(0.95);
|
|
7452
|
+
}
|
|
7453
|
+
|
|
7482
7454
|
.console-content {
|
|
7483
7455
|
background: #000;
|
|
7484
7456
|
color: #0f0;
|
|
@@ -7646,6 +7618,77 @@ const styles = `
|
|
|
7646
7618
|
cursor: sw-resize;
|
|
7647
7619
|
}
|
|
7648
7620
|
`;
|
|
7621
|
+
async function createShareLink(requestData) {
|
|
7622
|
+
try {
|
|
7623
|
+
const shareData = {
|
|
7624
|
+
// 基础信息
|
|
7625
|
+
url: requestData.url,
|
|
7626
|
+
method: requestData.method,
|
|
7627
|
+
headers: requestData.headers,
|
|
7628
|
+
status: requestData.status,
|
|
7629
|
+
statusText: requestData.statusText,
|
|
7630
|
+
timestamp: requestData.timestamp,
|
|
7631
|
+
duration: requestData.duration,
|
|
7632
|
+
// 请求和响应数据
|
|
7633
|
+
requestBody: requestData.requestBody,
|
|
7634
|
+
responseBody: requestData.responseBody,
|
|
7635
|
+
responseHeaders: requestData.responseHeaders,
|
|
7636
|
+
// 解密后的数据(如果有)
|
|
7637
|
+
decryptedRequest: requestData.decryptedRequest,
|
|
7638
|
+
decryptedResponse: requestData.decryptedResponse,
|
|
7639
|
+
// 错误信息(如果有)
|
|
7640
|
+
error: requestData.error,
|
|
7641
|
+
// 元数据
|
|
7642
|
+
creator: "PWTK Network Debugger by Leo (@leeguoo)",
|
|
7643
|
+
createdAt: Date.now(),
|
|
7644
|
+
version: "1.2.0"
|
|
7645
|
+
};
|
|
7646
|
+
const response = await fetch("https://gw-card-pay.buyacard.cc/api/dokv/storage", {
|
|
7647
|
+
method: "POST",
|
|
7648
|
+
headers: {
|
|
7649
|
+
"Content-Type": "application/json"
|
|
7650
|
+
},
|
|
7651
|
+
body: JSON.stringify({
|
|
7652
|
+
data: shareData,
|
|
7653
|
+
type: "network-request",
|
|
7654
|
+
expireIn: 7 * 24 * 60 * 60 * 1e3
|
|
7655
|
+
// 7天过期
|
|
7656
|
+
})
|
|
7657
|
+
});
|
|
7658
|
+
const result = await response.json();
|
|
7659
|
+
if (result.success && result.id) {
|
|
7660
|
+
const shareUrl = `https://curl.bwg.leeguoo.com/share/${result.id}`;
|
|
7661
|
+
console.log(`🔗 分享链接创建成功 (by Leo): ${shareUrl}`);
|
|
7662
|
+
return shareUrl;
|
|
7663
|
+
} else {
|
|
7664
|
+
throw new Error(result.message || "创建分享失败");
|
|
7665
|
+
}
|
|
7666
|
+
} catch (error) {
|
|
7667
|
+
console.error("NetworkDebugger: 创建分享链接失败:", error);
|
|
7668
|
+
throw error;
|
|
7669
|
+
}
|
|
7670
|
+
}
|
|
7671
|
+
async function copyToClipboard(text) {
|
|
7672
|
+
try {
|
|
7673
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
7674
|
+
await navigator.clipboard.writeText(text);
|
|
7675
|
+
return true;
|
|
7676
|
+
} else {
|
|
7677
|
+
const textArea = document.createElement("textarea");
|
|
7678
|
+
textArea.value = text;
|
|
7679
|
+
textArea.style.position = "fixed";
|
|
7680
|
+
textArea.style.opacity = "0";
|
|
7681
|
+
document.body.appendChild(textArea);
|
|
7682
|
+
textArea.select();
|
|
7683
|
+
const success = document.execCommand("copy");
|
|
7684
|
+
document.body.removeChild(textArea);
|
|
7685
|
+
return success;
|
|
7686
|
+
}
|
|
7687
|
+
} catch (error) {
|
|
7688
|
+
console.error("复制到剪贴板失败:", error);
|
|
7689
|
+
return false;
|
|
7690
|
+
}
|
|
7691
|
+
}
|
|
7649
7692
|
class DebugPanel {
|
|
7650
7693
|
constructor(interceptor, config = {}) {
|
|
7651
7694
|
this.isDragging = false;
|
|
@@ -7678,7 +7721,7 @@ class DebugPanel {
|
|
|
7678
7721
|
this.container.className = `${this.config.position} ${this.config.minimized ? "minimized" : ""}`;
|
|
7679
7722
|
this.container.innerHTML = `
|
|
7680
7723
|
<div class="debugger-header">
|
|
7681
|
-
<div class="debugger-title">🔍 Network Debugger</div>
|
|
7724
|
+
<div class="debugger-title">🔍 Network Debugger <span style="font-size: 10px; opacity: 0.7;">by Leo</span></div>
|
|
7682
7725
|
<div class="debugger-controls">
|
|
7683
7726
|
<button class="debugger-btn" data-action="clear" title="清空">🗑️</button>
|
|
7684
7727
|
<button class="debugger-btn" data-action="export" title="导出">💾</button>
|
|
@@ -7692,6 +7735,7 @@ class DebugPanel {
|
|
|
7692
7735
|
<button class="debugger-tab active" data-tab="network">网络</button>
|
|
7693
7736
|
${this.config.showConsole ? '<button class="debugger-tab" data-tab="console">控制台</button>' : ""}
|
|
7694
7737
|
<button class="debugger-tab" data-tab="tools">工具</button>
|
|
7738
|
+
<button class="debugger-tab" data-tab="about">关于</button>
|
|
7695
7739
|
</div>
|
|
7696
7740
|
<div class="debugger-panel-content">
|
|
7697
7741
|
<div class="network-panel" data-panel="network">
|
|
@@ -7719,6 +7763,19 @@ class DebugPanel {
|
|
|
7719
7763
|
<textarea placeholder="在这里粘贴 cURL 命令或输入要测试的数据..." style="width: 100%; height: 200px; background: #222; color: #fff; border: 1px solid #444; padding: 8px; font-family: monospace;"></textarea>
|
|
7720
7764
|
</div>
|
|
7721
7765
|
</div>
|
|
7766
|
+
<div class="about-panel" data-panel="about" style="display: none;">
|
|
7767
|
+
<div style="padding: 20px; color: #fff; text-align: center;">
|
|
7768
|
+
<h2 style="margin: 0 0 20px 0;">🔍 PWTK Network Debugger</h2>
|
|
7769
|
+
<p style="margin: 10px 0;">Version: 1.2.0</p>
|
|
7770
|
+
<p style="margin: 10px 0;">👨💻 Created by <strong>Leo (@leeguoo)</strong></p>
|
|
7771
|
+
<p style="margin: 10px 0;">📧 技术支持:请联系 Leo</p>
|
|
7772
|
+
<p style="margin: 10px 0;">🌐 分享服务:curl.bwg.leeguoo.com</p>
|
|
7773
|
+
<div style="margin-top: 20px; padding: 15px; background: #333; border-radius: 8px;">
|
|
7774
|
+
<p style="margin: 5px 0; font-size: 12px;">本工具专为 PWTK 项目开发</p>
|
|
7775
|
+
<p style="margin: 5px 0; font-size: 12px;">提供网络请求拦截、解密、分享等功能</p>
|
|
7776
|
+
</div>
|
|
7777
|
+
</div>
|
|
7778
|
+
</div>
|
|
7722
7779
|
</div>
|
|
7723
7780
|
</div>
|
|
7724
7781
|
`;
|
|
@@ -7838,6 +7895,7 @@ class DebugPanel {
|
|
|
7838
7895
|
<span class="request-status ${statusClass}">${request.status || "ERR"}</span>
|
|
7839
7896
|
${hasDecryptedData ? '<span class="decrypted-badge">🔓</span>' : ""}
|
|
7840
7897
|
${hasError ? '<span class="error-badge">⚠️</span>' : ""}
|
|
7898
|
+
<button class="share-btn" title="分享此请求 (by Leo)" onclick="event.stopPropagation()">📤</button>
|
|
7841
7899
|
</div>
|
|
7842
7900
|
<div class="request-info">
|
|
7843
7901
|
<span>${new Date(request.timestamp).toLocaleTimeString()}</span>
|
|
@@ -7850,6 +7908,13 @@ class DebugPanel {
|
|
|
7850
7908
|
item.addEventListener("click", () => {
|
|
7851
7909
|
item.classList.toggle("expanded");
|
|
7852
7910
|
});
|
|
7911
|
+
const shareBtn = item.querySelector(".share-btn");
|
|
7912
|
+
if (shareBtn) {
|
|
7913
|
+
shareBtn.addEventListener("click", async (e) => {
|
|
7914
|
+
e.stopPropagation();
|
|
7915
|
+
await this.shareRequest(request);
|
|
7916
|
+
});
|
|
7917
|
+
}
|
|
7853
7918
|
return item;
|
|
7854
7919
|
}
|
|
7855
7920
|
renderRequestDetails(request) {
|
|
@@ -7982,7 +8047,8 @@ class DebugPanel {
|
|
|
7982
8047
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7983
8048
|
requests: this.requestsCache,
|
|
7984
8049
|
userAgent: navigator.userAgent,
|
|
7985
|
-
url: window.location.href
|
|
8050
|
+
url: window.location.href,
|
|
8051
|
+
creator: "PWTK Network Debugger by Leo (@leeguoo)"
|
|
7986
8052
|
};
|
|
7987
8053
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
|
|
7988
8054
|
const url = URL.createObjectURL(blob);
|
|
@@ -7991,7 +8057,32 @@ class DebugPanel {
|
|
|
7991
8057
|
a.download = `network-debug-${Date.now()}.json`;
|
|
7992
8058
|
a.click();
|
|
7993
8059
|
URL.revokeObjectURL(url);
|
|
7994
|
-
this.logToConsole("💾 网络数据已导出");
|
|
8060
|
+
this.logToConsole("💾 网络数据已导出 (by Leo)");
|
|
8061
|
+
}
|
|
8062
|
+
async shareRequest(request) {
|
|
8063
|
+
try {
|
|
8064
|
+
this.logToConsole("📤 正在创建分享链接...");
|
|
8065
|
+
const shareUrl = await createShareLink(request);
|
|
8066
|
+
if (shareUrl) {
|
|
8067
|
+
const copied = await copyToClipboard(shareUrl);
|
|
8068
|
+
if (copied) {
|
|
8069
|
+
this.logToConsole(`✅ 分享链接已复制到剪贴板: ${shareUrl}`);
|
|
8070
|
+
alert(`分享链接已复制到剪贴板!
|
|
8071
|
+
${shareUrl}
|
|
8072
|
+
|
|
8073
|
+
Created by Leo (@leeguoo)`);
|
|
8074
|
+
} else {
|
|
8075
|
+
this.logToConsole(`✅ 分享链接: ${shareUrl}`);
|
|
8076
|
+
prompt("分享链接已创建,请手动复制:\n\nCreated by Leo (@leeguoo)", shareUrl);
|
|
8077
|
+
}
|
|
8078
|
+
} else {
|
|
8079
|
+
throw new Error("无法创建分享链接");
|
|
8080
|
+
}
|
|
8081
|
+
} catch (error) {
|
|
8082
|
+
console.error("分享失败:", error);
|
|
8083
|
+
this.logToConsole(`❌ 分享失败: ${error}`);
|
|
8084
|
+
alert("分享失败,请稍后重试");
|
|
8085
|
+
}
|
|
7995
8086
|
}
|
|
7996
8087
|
toggleMinimize() {
|
|
7997
8088
|
this.config.minimized = !this.config.minimized;
|
|
@@ -8217,11 +8308,6 @@ class NetworkDebugger {
|
|
|
8217
8308
|
keyApiUrl: "https://gw-card-pay.buyacard.cc/ip/getSK",
|
|
8218
8309
|
...config.decrypt
|
|
8219
8310
|
},
|
|
8220
|
-
persistence: {
|
|
8221
|
-
enabled: true,
|
|
8222
|
-
maxRecords: 100,
|
|
8223
|
-
...config.persistence
|
|
8224
|
-
},
|
|
8225
8311
|
...config
|
|
8226
8312
|
};
|
|
8227
8313
|
try {
|
|
@@ -8229,9 +8315,7 @@ class NetworkDebugger {
|
|
|
8229
8315
|
this.wasmLoader = new WasmLoader();
|
|
8230
8316
|
await this.wasmLoader.loadWasm(this.config.wasm.wasmUrl, this.config.wasm.jsUrl);
|
|
8231
8317
|
}
|
|
8232
|
-
this.interceptor = new NetworkInterceptor(
|
|
8233
|
-
persistence: this.config.persistence?.enabled
|
|
8234
|
-
});
|
|
8318
|
+
this.interceptor = new NetworkInterceptor();
|
|
8235
8319
|
if (this.config.decrypt?.enabled) {
|
|
8236
8320
|
this.interceptor.enableDecryption({
|
|
8237
8321
|
keyExtractor: this.config.decrypt.keyExtractor || this.defaultKeyExtractor,
|
|
@@ -8244,7 +8328,15 @@ class NetworkDebugger {
|
|
|
8244
8328
|
this.createPanel();
|
|
8245
8329
|
}
|
|
8246
8330
|
this.initialized = true;
|
|
8247
|
-
console.log(
|
|
8331
|
+
console.log(`
|
|
8332
|
+
╔════════════════════════════════════════╗
|
|
8333
|
+
║ PWTK Network Debugger v1.2.0 ║
|
|
8334
|
+
║ Created by Leo (@leeguoo) ║
|
|
8335
|
+
║ 技术支持: 请联系 Leo ║
|
|
8336
|
+
║ 分享服务: curl.bwg.leeguoo.com ║
|
|
8337
|
+
╚════════════════════════════════════════╝
|
|
8338
|
+
`);
|
|
8339
|
+
console.log("🔍 NetworkDebugger initialized successfully");
|
|
8248
8340
|
} catch (error) {
|
|
8249
8341
|
console.error("NetworkDebugger initialization failed:", error);
|
|
8250
8342
|
throw error;
|