@leeguoo/pwtk-network-debugger 1.1.0 → 1.2.2

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.esm.js CHANGED
@@ -6671,17 +6671,10 @@ function decrypt(encryptedData, keyStr) {
6671
6671
  return encryptedData;
6672
6672
  }
6673
6673
  class NetworkInterceptor {
6674
- constructor(options = {}) {
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;
@@ -7196,6 +7146,16 @@ const styles = `
7196
7146
  #network-debugger-panel.minimized {
7197
7147
  height: 40px !important;
7198
7148
  overflow: hidden;
7149
+ width: auto !important;
7150
+ min-width: 200px;
7151
+ }
7152
+
7153
+ #network-debugger-panel.minimized .debugger-content {
7154
+ display: none;
7155
+ }
7156
+
7157
+ #network-debugger-panel.minimized .resize-handle {
7158
+ display: none;
7199
7159
  }
7200
7160
 
7201
7161
  #network-debugger-panel.bottom-right {
@@ -7330,6 +7290,7 @@ const styles = `
7330
7290
  padding: 10px;
7331
7291
  cursor: pointer;
7332
7292
  transition: all 0.2s;
7293
+ position: relative;
7333
7294
  }
7334
7295
 
7335
7296
  .request-item:hover {
@@ -7479,6 +7440,27 @@ const styles = `
7479
7440
  font-weight: bold;
7480
7441
  }
7481
7442
 
7443
+ .share-btn {
7444
+ background: #2196F3;
7445
+ color: #fff;
7446
+ border: none;
7447
+ padding: 4px 8px;
7448
+ border-radius: 3px;
7449
+ font-size: 10px;
7450
+ margin-left: 8px;
7451
+ cursor: pointer;
7452
+ transition: all 0.2s;
7453
+ }
7454
+
7455
+ .share-btn:hover {
7456
+ background: #1976D2;
7457
+ transform: scale(1.1);
7458
+ }
7459
+
7460
+ .share-btn:active {
7461
+ transform: scale(0.95);
7462
+ }
7463
+
7482
7464
  .console-content {
7483
7465
  background: #000;
7484
7466
  color: #0f0;
@@ -7646,6 +7628,109 @@ const styles = `
7646
7628
  cursor: sw-resize;
7647
7629
  }
7648
7630
  `;
7631
+ async function createShareLink(requestData) {
7632
+ try {
7633
+ const curlCommand = formatAsCurl(requestData);
7634
+ const shareData = {
7635
+ // 原项目需要的核心字段
7636
+ curl: curlCommand,
7637
+ response: requestData.responseBody || null,
7638
+ timestamp: Date.now(),
7639
+ // 密钥相关(如果有)
7640
+ keys: extractKeys(requestData.headers),
7641
+ slk: requestData.headers?.slk || "",
7642
+ // 额外的调试信息(向后兼容)
7643
+ debuggerData: {
7644
+ url: requestData.url,
7645
+ method: requestData.method,
7646
+ headers: requestData.headers,
7647
+ status: requestData.status,
7648
+ statusText: requestData.statusText,
7649
+ duration: requestData.duration,
7650
+ responseHeaders: requestData.responseHeaders,
7651
+ decryptedRequest: requestData.decryptedRequest,
7652
+ decryptedResponse: requestData.decryptedResponse,
7653
+ error: requestData.error,
7654
+ creator: "PWTK Network Debugger by Leo (@leeguoo)",
7655
+ version: "1.2.0"
7656
+ }
7657
+ };
7658
+ const response = await fetch("https://gw-card-pay.buyacard.cc/api/dokv/storage", {
7659
+ method: "POST",
7660
+ headers: {
7661
+ "Content-Type": "application/json"
7662
+ },
7663
+ body: JSON.stringify({
7664
+ projectId: "curl-tool",
7665
+ // 使用与原项目相同的项目ID
7666
+ key: `share:${generateShareId()}`,
7667
+ // 使用相同的key格式
7668
+ data: shareData,
7669
+ expireIn: 7 * 24 * 60 * 60 * 1e3
7670
+ // 7天过期
7671
+ })
7672
+ });
7673
+ const result = await response.json();
7674
+ if (result.success && (result.id || result.key)) {
7675
+ let shareId = result.id;
7676
+ if (!shareId && result.key) {
7677
+ shareId = result.key.replace("share:", "");
7678
+ }
7679
+ const shareUrl = `https://curl.bwg.leeguoo.com/share/${shareId}`;
7680
+ console.log(`🔗 分享链接创建成功 (by Leo): ${shareUrl}`);
7681
+ return shareUrl;
7682
+ } else {
7683
+ throw new Error(result.message || "创建分享失败");
7684
+ }
7685
+ } catch (error) {
7686
+ console.error("NetworkDebugger: 创建分享链接失败:", error);
7687
+ throw error;
7688
+ }
7689
+ }
7690
+ function generateShareId() {
7691
+ return Math.random().toString(36).substr(2, 10);
7692
+ }
7693
+ function extractKeys(headers) {
7694
+ if (!headers) return "";
7695
+ return headers.keys || headers.cid || headers["x-api-key"] || "";
7696
+ }
7697
+ async function copyToClipboard(text) {
7698
+ try {
7699
+ if (navigator.clipboard && navigator.clipboard.writeText) {
7700
+ await navigator.clipboard.writeText(text);
7701
+ return true;
7702
+ } else {
7703
+ const textArea = document.createElement("textarea");
7704
+ textArea.value = text;
7705
+ textArea.style.position = "fixed";
7706
+ textArea.style.opacity = "0";
7707
+ document.body.appendChild(textArea);
7708
+ textArea.select();
7709
+ const success = document.execCommand("copy");
7710
+ document.body.removeChild(textArea);
7711
+ return success;
7712
+ }
7713
+ } catch (error) {
7714
+ console.error("复制到剪贴板失败:", error);
7715
+ return false;
7716
+ }
7717
+ }
7718
+ function formatAsCurl(requestData) {
7719
+ let curl = `curl '${requestData.url}'`;
7720
+ if (requestData.method !== "GET") {
7721
+ curl += ` -X ${requestData.method}`;
7722
+ }
7723
+ if (requestData.headers) {
7724
+ Object.entries(requestData.headers).forEach(([key, value]) => {
7725
+ curl += ` -H '${key}: ${value}'`;
7726
+ });
7727
+ }
7728
+ if (requestData.requestBody) {
7729
+ const body = typeof requestData.requestBody === "string" ? requestData.requestBody : JSON.stringify(requestData.requestBody);
7730
+ curl += ` --data '${body}'`;
7731
+ }
7732
+ return curl;
7733
+ }
7649
7734
  class DebugPanel {
7650
7735
  constructor(interceptor, config = {}) {
7651
7736
  this.isDragging = false;
@@ -7678,12 +7763,12 @@ class DebugPanel {
7678
7763
  this.container.className = `${this.config.position} ${this.config.minimized ? "minimized" : ""}`;
7679
7764
  this.container.innerHTML = `
7680
7765
  <div class="debugger-header">
7681
- <div class="debugger-title">🔍 Network Debugger</div>
7766
+ <div class="debugger-title">🔓 ${this.config.minimized ? "PWTK" : "PWTK 解密小工具"} <span style="font-size: 10px; opacity: 0.7;">by Leo</span></div>
7682
7767
  <div class="debugger-controls">
7683
- <button class="debugger-btn" data-action="clear" title="清空">🗑️</button>
7684
- <button class="debugger-btn" data-action="export" title="导出">💾</button>
7685
- <button class="debugger-btn" data-action="minimize" title="最小化">${this.config.minimized ? "📖" : "📕"}</button>
7686
- <button class="debugger-btn" data-action="fullscreen" title="全屏">⛶</button>
7768
+ ${!this.config.minimized ? '<button class="debugger-btn" data-action="clear" title="清空">🗑️</button>' : ""}
7769
+ ${!this.config.minimized ? '<button class="debugger-btn" data-action="export" title="导出">💾</button>' : ""}
7770
+ <button class="debugger-btn" data-action="minimize" title="${this.config.minimized ? "展开" : "最小化"}">${this.config.minimized ? "📖" : "📕"}</button>
7771
+ ${!this.config.minimized ? '<button class="debugger-btn" data-action="fullscreen" title="全屏">⛶</button>' : ""}
7687
7772
  <button class="debugger-btn" data-action="close" title="关闭">✕</button>
7688
7773
  </div>
7689
7774
  </div>
@@ -7692,6 +7777,7 @@ class DebugPanel {
7692
7777
  <button class="debugger-tab active" data-tab="network">网络</button>
7693
7778
  ${this.config.showConsole ? '<button class="debugger-tab" data-tab="console">控制台</button>' : ""}
7694
7779
  <button class="debugger-tab" data-tab="tools">工具</button>
7780
+ <button class="debugger-tab" data-tab="about">关于</button>
7695
7781
  </div>
7696
7782
  <div class="debugger-panel-content">
7697
7783
  <div class="network-panel" data-panel="network">
@@ -7719,6 +7805,19 @@ class DebugPanel {
7719
7805
  <textarea placeholder="在这里粘贴 cURL 命令或输入要测试的数据..." style="width: 100%; height: 200px; background: #222; color: #fff; border: 1px solid #444; padding: 8px; font-family: monospace;"></textarea>
7720
7806
  </div>
7721
7807
  </div>
7808
+ <div class="about-panel" data-panel="about" style="display: none;">
7809
+ <div style="padding: 20px; color: #fff; text-align: center;">
7810
+ <h2 style="margin: 0 0 20px 0;">🔓 PWTK 解密小工具</h2>
7811
+ <p style="margin: 10px 0;">Version: 1.2.2</p>
7812
+ <p style="margin: 10px 0;">👨‍💻 Created by <strong>Leo (@leeguoo)</strong></p>
7813
+ <p style="margin: 10px 0;">📧 技术支持:请联系 Leo</p>
7814
+ <p style="margin: 10px 0;">🌐 分享服务:curl.bwg.leeguoo.com</p>
7815
+ <div style="margin-top: 20px; padding: 15px; background: #333; border-radius: 8px;">
7816
+ <p style="margin: 5px 0; font-size: 12px;">本工具专为 PWTK 项目开发</p>
7817
+ <p style="margin: 5px 0; font-size: 12px;">提供网络请求拦截、解密、分享等功能</p>
7818
+ </div>
7819
+ </div>
7820
+ </div>
7722
7821
  </div>
7723
7822
  </div>
7724
7823
  `;
@@ -7838,6 +7937,7 @@ class DebugPanel {
7838
7937
  <span class="request-status ${statusClass}">${request.status || "ERR"}</span>
7839
7938
  ${hasDecryptedData ? '<span class="decrypted-badge">🔓</span>' : ""}
7840
7939
  ${hasError ? '<span class="error-badge">⚠️</span>' : ""}
7940
+ <button class="share-btn" title="分享此请求 (by Leo)" onclick="event.stopPropagation()">📤</button>
7841
7941
  </div>
7842
7942
  <div class="request-info">
7843
7943
  <span>${new Date(request.timestamp).toLocaleTimeString()}</span>
@@ -7850,6 +7950,13 @@ class DebugPanel {
7850
7950
  item.addEventListener("click", () => {
7851
7951
  item.classList.toggle("expanded");
7852
7952
  });
7953
+ const shareBtn = item.querySelector(".share-btn");
7954
+ if (shareBtn) {
7955
+ shareBtn.addEventListener("click", async (e) => {
7956
+ e.stopPropagation();
7957
+ await this.shareRequest(request);
7958
+ });
7959
+ }
7853
7960
  return item;
7854
7961
  }
7855
7962
  renderRequestDetails(request) {
@@ -7982,7 +8089,8 @@ class DebugPanel {
7982
8089
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7983
8090
  requests: this.requestsCache,
7984
8091
  userAgent: navigator.userAgent,
7985
- url: window.location.href
8092
+ url: window.location.href,
8093
+ creator: "PWTK Network Debugger by Leo (@leeguoo)"
7986
8094
  };
7987
8095
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
7988
8096
  const url = URL.createObjectURL(blob);
@@ -7991,13 +8099,71 @@ class DebugPanel {
7991
8099
  a.download = `network-debug-${Date.now()}.json`;
7992
8100
  a.click();
7993
8101
  URL.revokeObjectURL(url);
7994
- this.logToConsole("💾 网络数据已导出");
8102
+ this.logToConsole("💾 网络数据已导出 (by Leo)");
8103
+ }
8104
+ async shareRequest(request) {
8105
+ try {
8106
+ this.logToConsole("📤 正在创建分享链接...");
8107
+ const shareUrl = await createShareLink(request);
8108
+ if (shareUrl) {
8109
+ const copied = await copyToClipboard(shareUrl);
8110
+ if (copied) {
8111
+ this.logToConsole(`✅ 分享链接已复制到剪贴板: ${shareUrl}`);
8112
+ alert(`分享链接已复制到剪贴板!
8113
+ ${shareUrl}
8114
+
8115
+ Created by Leo (@leeguoo)`);
8116
+ } else {
8117
+ this.logToConsole(`✅ 分享链接: ${shareUrl}`);
8118
+ prompt("分享链接已创建,请手动复制:\n\nCreated by Leo (@leeguoo)", shareUrl);
8119
+ }
8120
+ } else {
8121
+ throw new Error("无法创建分享链接");
8122
+ }
8123
+ } catch (error) {
8124
+ console.error("分享失败:", error);
8125
+ this.logToConsole(`❌ 分享失败: ${error}`);
8126
+ alert("分享失败,请稍后重试");
8127
+ }
7995
8128
  }
7996
8129
  toggleMinimize() {
7997
8130
  this.config.minimized = !this.config.minimized;
7998
8131
  this.container.classList.toggle("minimized", this.config.minimized);
7999
- const btn = this.container.querySelector('[data-action="minimize"]');
8000
- btn.textContent = this.config.minimized ? "📖" : "📕";
8132
+ const header = this.container.querySelector(".debugger-header");
8133
+ if (header) {
8134
+ header.innerHTML = `
8135
+ <div class="debugger-title">🔓 ${this.config.minimized ? "PWTK" : "PWTK 解密小工具"} <span style="font-size: 10px; opacity: 0.7;">by Leo</span></div>
8136
+ <div class="debugger-controls">
8137
+ ${!this.config.minimized ? '<button class="debugger-btn" data-action="clear" title="清空">🗑️</button>' : ""}
8138
+ ${!this.config.minimized ? '<button class="debugger-btn" data-action="export" title="导出">💾</button>' : ""}
8139
+ <button class="debugger-btn" data-action="minimize" title="${this.config.minimized ? "展开" : "最小化"}">${this.config.minimized ? "📖" : "📕"}</button>
8140
+ ${!this.config.minimized ? '<button class="debugger-btn" data-action="fullscreen" title="全屏">⛶</button>' : ""}
8141
+ <button class="debugger-btn" data-action="close" title="关闭">✕</button>
8142
+ </div>
8143
+ `;
8144
+ const controls = header.querySelector(".debugger-controls");
8145
+ controls.addEventListener("click", (e) => {
8146
+ const target = e.target;
8147
+ const action = target.dataset.action;
8148
+ switch (action) {
8149
+ case "clear":
8150
+ this.clearRequests();
8151
+ break;
8152
+ case "export":
8153
+ this.exportData();
8154
+ break;
8155
+ case "minimize":
8156
+ this.toggleMinimize();
8157
+ break;
8158
+ case "fullscreen":
8159
+ this.toggleFullscreen();
8160
+ break;
8161
+ case "close":
8162
+ this.hide();
8163
+ break;
8164
+ }
8165
+ });
8166
+ }
8001
8167
  }
8002
8168
  toggleFullscreen() {
8003
8169
  this.container.classList.toggle("fullscreen");
@@ -8217,11 +8383,6 @@ class NetworkDebugger {
8217
8383
  keyApiUrl: "https://gw-card-pay.buyacard.cc/ip/getSK",
8218
8384
  ...config.decrypt
8219
8385
  },
8220
- persistence: {
8221
- enabled: true,
8222
- maxRecords: 100,
8223
- ...config.persistence
8224
- },
8225
8386
  ...config
8226
8387
  };
8227
8388
  try {
@@ -8229,9 +8390,7 @@ class NetworkDebugger {
8229
8390
  this.wasmLoader = new WasmLoader();
8230
8391
  await this.wasmLoader.loadWasm(this.config.wasm.wasmUrl, this.config.wasm.jsUrl);
8231
8392
  }
8232
- this.interceptor = new NetworkInterceptor({
8233
- persistence: this.config.persistence?.enabled
8234
- });
8393
+ this.interceptor = new NetworkInterceptor();
8235
8394
  if (this.config.decrypt?.enabled) {
8236
8395
  this.interceptor.enableDecryption({
8237
8396
  keyExtractor: this.config.decrypt.keyExtractor || this.defaultKeyExtractor,
@@ -8244,7 +8403,15 @@ class NetworkDebugger {
8244
8403
  this.createPanel();
8245
8404
  }
8246
8405
  this.initialized = true;
8247
- console.log("🔍 NetworkDebugger initialized successfully by Leo (@leeguoo)");
8406
+ console.log(`
8407
+ ╔════════════════════════════════════════╗
8408
+ ║ 🔓 PWTK 解密小工具 v1.2.2 ║
8409
+ ║ Created by Leo (@leeguoo) ║
8410
+ ║ 技术支持: 请联系 Leo ║
8411
+ ║ 分享服务: curl.bwg.leeguoo.com ║
8412
+ ╚════════════════════════════════════════╝
8413
+ `);
8414
+ console.log("🔍 NetworkDebugger initialized successfully");
8248
8415
  } catch (error) {
8249
8416
  console.error("NetworkDebugger initialization failed:", error);
8250
8417
  throw error;