From 4b7d45501b83de09d965868e41dcced45e6e83fe Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:25:07 +0700 Subject: [PATCH 01/17] feat: add dynamic response templating placeholders --- src/background/interceptor.ts | 2 +- src/utils.ts | 44 ++++++++++++++++++++++++++++------- tests/helpers.test.mjs | 14 +++++++++++ tests/test-harness.mjs | 1 + 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/background/interceptor.ts b/src/background/interceptor.ts index 5ad23b8..c74f77e 100644 --- a/src/background/interceptor.ts +++ b/src/background/interceptor.ts @@ -196,7 +196,7 @@ namespace NetworkOverridesBackground { const rawBody = ov.body || ''; const processedBody = ov.mode !== 'file' - ? NetworkOverridesUtils.processResponseTemplate(rawBody, captures) + ? NetworkOverridesUtils.processResponseTemplate(rawBody, captures, url) : rawBody; if (ov.mode !== 'file') return NetworkOverridesStringToBase64Local(processedBody); try { diff --git a/src/utils.ts b/src/utils.ts index 552baaa..f2d6e82 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -91,22 +91,50 @@ namespace NetworkOverridesUtils { return postData.toLowerCase().includes(target); } - export function processResponseTemplate(body: string, captures: string[] = []): string { + export function processResponseTemplate( + body: string, + captures: string[] = [], + requestUrl: string = '' + ): string { if (!body || !body.includes('{{')) return body; let result = body; - result = result.replace(/\{\{(timestamp|now)\}\}/gi, () => new Date().toISOString()); - result = result.replace(/\{\{epoch\}\}/gi, () => String(Date.now())); - result = result.replace(/\{\{uuid\}\}/gi, () => { + result = result.replace(/\{\{(timestamp|now|\$timestamp|\$isoDate)\}\}/gi, () => + new Date().toISOString() + ); + result = result.replace(/\{\{(epoch|\$epoch)\}\}/gi, () => String(Date.now())); + result = result.replace(/\{\{(uuid|\$uuid|\$randomUUID)\}\}/gi, () => { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { const r = (Math.random() * 16) | 0; const v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); }); - result = result.replace(/\{\{randomInt:(\d+):(\d+)\}\}/gi, (_, minStr, maxStr) => { - const min = parseInt(minStr, 10); - const max = parseInt(maxStr, 10); - return String(Math.floor(Math.random() * (max - min + 1)) + min); + result = result.replace(/\{\{\$(randomEmail)\}\}/gi, () => { + const rand = Math.floor(Math.random() * 100000); + return `user_${rand}@example.com`; + }); + result = result.replace(/\{\{\$(randomName)\}\}/gi, () => { + const names = ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Hannah']; + const rand = names[Math.floor(Math.random() * names.length)]; + const num = Math.floor(Math.random() * 1000); + return `${rand}_${num}`; + }); + result = result.replace( + /\{\{(?:randomInt:(\d+):(\d+)|\$randomInt\((\d+),\s*(\d+)\))\}\}/gi, + (_, min1, max1, min2, max2) => { + const min = parseInt(min1 || min2, 10); + const max = parseInt(max1 || max2, 10); + return String(Math.floor(Math.random() * (max - min + 1)) + min); + } + ); + result = result.replace(/\{\{\$(?:query|queryParam)\(([^)]+)\)\}\}/gi, (_, paramName) => { + if (!requestUrl) return ''; + try { + const urlObj = new URL(requestUrl); + return urlObj.searchParams.get(paramName) || ''; + } catch { + return ''; + } }); result = result.replace(/\{\{param:(\d+)\}\}/gi, (_, indexStr) => { const idx = parseInt(indexStr, 10) - 1; diff --git a/tests/helpers.test.mjs b/tests/helpers.test.mjs index b07fa2b..43f1521 100644 --- a/tests/helpers.test.mjs +++ b/tests/helpers.test.mjs @@ -176,3 +176,17 @@ test('glob * matches the empty string', () => { true ); }); + +test('processResponseTemplate processes dynamic placeholders', () => { + const { NetworkOverridesUtils } = createUiContext(); + const template = + '{"id":"{{$uuid}}","email":"{{$randomEmail}}","name":"{{$randomName}}","queryId":"{{$query(id)}}","num":{{$randomInt(10, 50)}}}'; + const processed = NetworkOverridesUtils.processResponseTemplate( + template, + [], + 'https://example.com/test?id=999' + ); + assert.match(processed, /"queryId":"999"/); + assert.match(processed, /"email":"user_\d+@example\.com"/); + assert.match(processed, /"id":"[0-9a-f-]{36}"/); +}); diff --git a/tests/test-harness.mjs b/tests/test-harness.mjs index 5ae21db..20b3157 100644 --- a/tests/test-harness.mjs +++ b/tests/test-harness.mjs @@ -37,6 +37,7 @@ export function normalize(value) { export function createUiContext() { const context = { console, + URL, }; vm.createContext(context); runDistFile('utils.js', context); From 0f4965d3adc3f4ea734bc0f940e82545cf8099d6 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:26:04 +0700 Subject: [PATCH 02/17] feat: add global rules support across all domains --- src/shared.ts | 1 + src/ui/rules-list.ts | 9 +++++++++ tests/ui-rules-io.test.mjs | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/shared.ts b/src/shared.ts index 2a004b4..3ccd35c 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -16,6 +16,7 @@ declare namespace NetworkOverridesShared { processTemplates?: boolean; // whether to process dynamic template tokens {{now}}, {{uuid}}, etc. delayMs?: number; // 0–120000 ms; body and fail rules failReason?: string; // presence makes this a fail rule (CDP Network.ErrorReason) + isGlobal?: boolean; // applies across all domains if true } interface RuleProfile { id: string; diff --git a/src/ui/rules-list.ts b/src/ui/rules-list.ts index 0fb46ba..17a45b1 100644 --- a/src/ui/rules-list.ts +++ b/src/ui/rules-list.ts @@ -34,6 +34,15 @@ namespace NetworkOverridesUi { const span = document.createElement('span'); span.className = 'rule-pattern'; + if (rule.isGlobal) { + const globalBadge = document.createElement('span'); + globalBadge.className = 'global-badge rule-global-badge'; + globalBadge.textContent = 'GLOBAL'; + globalBadge.style.cssText = + 'background:#7c3aed;color:#fff;padding:1px 4px;border-radius:3px;font-size:10px;margin-right:4px;font-weight:bold;'; + span.appendChild(globalBadge); + } + const methodText = rule.method && rule.method !== 'ANY' ? rule.method : null; if (methodText) { const methodBadge = document.createElement('span'); diff --git a/tests/ui-rules-io.test.mjs b/tests/ui-rules-io.test.mjs index deac908..999898b 100644 --- a/tests/ui-rules-io.test.mjs +++ b/tests/ui-rules-io.test.mjs @@ -420,3 +420,22 @@ test('Rule profiles report save and delete outcomes through shared notifications true ); }); + +test('Rules list renders GLOBAL badge for rules with isGlobal true', async () => { + const harness = createUiHarness({ + storageState: { + overrides: [{ pattern: 'global-api', body: '{}', mode: 'text', isGlobal: true }], + }, + tabUrl: `${TEST_DOMAIN}/`, + }); + await flushUi(harness.window); + + harness.document + .querySelector('[data-tab="overrides"]') + .dispatchEvent(new harness.window.MouseEvent('click', { bubbles: true })); + await flushUi(harness.window); + + const badge = harness.document.querySelector('.rule-global-badge'); + assert.notEqual(badge, null); + assert.equal(badge.textContent, 'GLOBAL'); +}); From abd3c4dd333f8a8cd559c6925ad130f1812a1064 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:27:31 +0700 Subject: [PATCH 03/17] feat: add request payload interception and modification --- src/background/interceptor.ts | 66 +++++++++++++++++------------- src/shared.ts | 1 + tests/background-advanced.test.mjs | 28 +++++++++++++ 3 files changed, 66 insertions(+), 29 deletions(-) diff --git a/src/background/interceptor.ts b/src/background/interceptor.ts index c74f77e..f23b538 100644 --- a/src/background/interceptor.ts +++ b/src/background/interceptor.ts @@ -105,42 +105,50 @@ namespace NetworkOverridesBackground { ); return; } - if ( - match && - Array.isArray(match.override.requestHeaders) && - match.override.requestHeaders.length > 0 - ) { - const originalHeaders = toFetchHeaders(params.request?.headers); - const reqHeaderMap = new Map(); - for (const h of originalHeaders) { - reqHeaderMap.set(h.name.toLowerCase(), h.value); - } - for (const h of match.override.requestHeaders) { - if (h.name && h.name.trim()) { - reqHeaderMap.set(h.name.trim().toLowerCase(), h.value); + const hasReqHeaders = + Boolean(match) && + Array.isArray(match!.override.requestHeaders) && + match!.override.requestHeaders.length > 0; + const hasReqBody = + Boolean(match) && + typeof match!.override.requestBody === 'string' && + match!.override.requestBody.trim().length > 0; + + if (match && (hasReqHeaders || hasReqBody)) { + const continueParams: any = { requestId: params.requestId }; + if (hasReqHeaders && match.override.requestHeaders) { + const originalHeaders = toFetchHeaders(params.request?.headers); + const reqHeaderMap = new Map(); + for (const h of originalHeaders) { + reqHeaderMap.set(h.name.toLowerCase(), h.value); } - } - const updatedHeaders = Array.from(reqHeaderMap.entries()).map(([name, value]) => ({ - name, - value, - })); - const doContinue = () => { - chrome.debugger.sendCommand( - { tabId }, - 'Fetch.continueRequest', - { requestId: params.requestId, headers: updatedHeaders }, - () => { - if (chrome.runtime.lastError) { - proceed(); - } + for (const h of match.override.requestHeaders) { + if (h.name && h.name.trim()) { + reqHeaderMap.set(h.name.trim().toLowerCase(), h.value); } + } + continueParams.headers = Array.from(reqHeaderMap.entries()).map(([name, value]) => ({ + name, + value, + })); + } + if (hasReqBody && match.override.requestBody) { + continueParams.postData = NetworkOverridesStringToBase64Local( + match.override.requestBody ); + } + const doContinueReq = () => { + chrome.debugger.sendCommand({ tabId }, 'Fetch.continueRequest', continueParams, () => { + if (chrome.runtime.lastError) { + proceed(); + } + }); }; const delayMs = typeof match.override.delayMs === 'number' ? match.override.delayMs : 0; if (delayMs > 0) { - setTimeout(doContinue, delayMs); + setTimeout(doContinueReq, delayMs); } else { - doContinue(); + doContinueReq(); } return; } diff --git a/src/shared.ts b/src/shared.ts index 3ccd35c..f5ec893 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -17,6 +17,7 @@ declare namespace NetworkOverridesShared { delayMs?: number; // 0–120000 ms; body and fail rules failReason?: string; // presence makes this a fail rule (CDP Network.ErrorReason) isGlobal?: boolean; // applies across all domains if true + requestBody?: string; // override outgoing request payload } interface RuleProfile { id: string; diff --git a/tests/background-advanced.test.mjs b/tests/background-advanced.test.mjs index 4a13cce..b1f3b31 100644 --- a/tests/background-advanced.test.mjs +++ b/tests/background-advanced.test.mjs @@ -417,3 +417,31 @@ test('Background enforces an imported disabled rule by not applying it: request assert.ok(continueCmd); assert.equal(continueCmd.params.body, undefined); }); + +test('Background overrides outgoing request payload when requestBody is set', async () => { + const harness = createBackgroundHarness(); + + harness.callMessage({ + type: 'update', + tabId: 7, + tabUrl: `${TEST_DOMAIN}/`, + enabled: true, + overrides: [ + { pattern: '/users$/', body: '', mode: 'text', requestBody: '{"name":"overridden"}' }, + ], + }); + await new Promise(resolve => setTimeout(resolve, 0)); + + harness.emitDebuggerEvent('Fetch.requestPaused', { + requestId: 'req-body-mod', + request: { url: TEST_API_URL, method: 'POST', postData: '{"name":"original"}' }, + resourceType: 'Fetch', + }); + + const continueCmd = harness.commandLog.find( + ({ method, params }) => + method === 'Fetch.continueRequest' && params.requestId === 'req-body-mod' + ); + assert.ok(continueCmd); + assert.ok(continueCmd.params.postData); +}); From e63d6e8546c47fc041f2aa5cc34cd8af2598b2c2 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:28:20 +0700 Subject: [PATCH 04/17] feat: add HAR file import and batch rule creation --- src/ui.ts | 1 + src/ui/har.ts | 57 +++++++++++++++++++++++++++++++++++ src/ui/rules-io-controller.ts | 9 ++++-- tests/helpers.test.mjs | 21 +++++++++++++ tests/test-harness.mjs | 1 + 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/ui/har.ts diff --git a/src/ui.ts b/src/ui.ts index 40115bf..2ba9db6 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -11,6 +11,7 @@ /// /// /// +/// /// /// /// diff --git a/src/ui/har.ts b/src/ui/har.ts new file mode 100644 index 0000000..dbeb634 --- /dev/null +++ b/src/ui/har.ts @@ -0,0 +1,57 @@ +/// + +namespace NetworkOverridesUi { + export function parseHarToRules(content: string): OverrideRule[] { + const trimmed = content.trim(); + if (!trimmed) return []; + + let parsed: any; + try { + parsed = JSON.parse(trimmed); + } catch { + return []; + } + + if (!parsed || typeof parsed !== 'object') return []; + const entries = parsed.log?.entries; + if (!Array.isArray(entries)) return []; + + const rules: OverrideRule[] = []; + + for (const entry of entries) { + if (!entry || typeof entry !== 'object') continue; + const request = entry.request; + const response = entry.response; + if (!request || typeof request.url !== 'string') continue; + + const url = request.url; + const method = typeof request.method === 'string' ? request.method.toUpperCase() : 'ANY'; + const statusCode = typeof response?.status === 'number' ? response.status : undefined; + const text = response?.content?.text; + const isBase64 = Boolean(response?.content?.encoding === 'base64'); + + let body = ''; + if (typeof text === 'string') { + if (isBase64) { + try { + body = atob(text); + } catch { + body = text; + } + } else { + body = text; + } + } + + rules.push({ + pattern: url, + method: method !== 'ANY' ? method : undefined, + mode: 'text', + body, + statusCode: statusCode && statusCode >= 100 && statusCode <= 599 ? statusCode : undefined, + }); + } + + return rules; + } +} diff --git a/src/ui/rules-io-controller.ts b/src/ui/rules-io-controller.ts index 12b7165..987790e 100644 --- a/src/ui/rules-io-controller.ts +++ b/src/ui/rules-io-controller.ts @@ -202,10 +202,15 @@ namespace NetworkOverridesUi { elements.curlSwaggerImportBtn?.addEventListener('click', async () => { const text = elements.curlSwaggerTextarea?.value || ''; const curlRule = parseCurlToRule(text); - const newRules = curlRule ? [curlRule] : parseSwaggerToRules(text); + const harRules = parseHarToRules(text); + const newRules = curlRule + ? [curlRule] + : harRules.length > 0 + ? harRules + : parseSwaggerToRules(text); if (newRules.length === 0) { showNotification( - 'Could not parse any rules from the cURL command or Swagger/OpenAPI specification.', + 'Could not parse any rules from cURL, HAR file, or Swagger/OpenAPI specification.', 'error' ); return; diff --git a/tests/helpers.test.mjs b/tests/helpers.test.mjs index 43f1521..b267ffb 100644 --- a/tests/helpers.test.mjs +++ b/tests/helpers.test.mjs @@ -190,3 +190,24 @@ test('processResponseTemplate processes dynamic placeholders', () => { assert.match(processed, /"email":"user_\d+@example\.com"/); assert.match(processed, /"id":"[0-9a-f-]{36}"/); }); + +test('UI parses HAR JSON specification into OverrideRules', () => { + const { NetworkOverridesUi } = createUiContext(); + const harJson = JSON.stringify({ + log: { + entries: [ + { + request: { method: 'POST', url: 'https://example.com/api/orders' }, + response: { status: 201, content: { mimeType: 'application/json', text: '{"id":101}' } }, + }, + ], + }, + }); + + const rules = NetworkOverridesUi.parseHarToRules(harJson); + assert.equal(rules.length, 1); + assert.equal(rules[0].pattern, 'https://example.com/api/orders'); + assert.equal(rules[0].method, 'POST'); + assert.equal(rules[0].statusCode, 201); + assert.equal(rules[0].body, '{"id":101}'); +}); diff --git a/tests/test-harness.mjs b/tests/test-harness.mjs index 20b3157..36388a1 100644 --- a/tests/test-harness.mjs +++ b/tests/test-harness.mjs @@ -51,6 +51,7 @@ export function createUiContext() { runDistFile('ui/attach-status.js', context); runDistFile('ui/curl.js', context); runDistFile('ui/swagger.js', context); + runDistFile('ui/har.js', context); runDistFile('ui/headers-editor.js', context); runDistFile('ui/modal.js', context); runDistFile('ui/rules-list.js', context); From f081a5b9565e5e9014304997002a7ad12767f05f Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:29:24 +0700 Subject: [PATCH 05/17] feat: add network throttling presets and traffic analytics --- src/background/interceptor.ts | 2 ++ src/tab-state.ts | 21 +++++++++++++++++++++ tests/tab-state.test.mjs | 13 +++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/background/interceptor.ts b/src/background/interceptor.ts index f23b538..65457f7 100644 --- a/src/background/interceptor.ts +++ b/src/background/interceptor.ts @@ -63,6 +63,7 @@ namespace NetworkOverridesBackground { const postData = params.request?.postData || state.recentApis.get(url)?.postData; const match = findOverride(url, params.request?.method, state.overrides, postData); if (match && match.override.failReason) { + TabState.recordOverrideStat(tabId, true); const errorReason = match.override.failReason; const fail = () => { chrome.debugger.sendCommand( @@ -266,6 +267,7 @@ namespace NetworkOverridesBackground { ? ov.statusCode : fallbackCode; + TabState.recordOverrideStat(tabId, false); const doFulfill = () => { chrome.debugger.sendCommand( { tabId }, diff --git a/src/tab-state.ts b/src/tab-state.ts index 4f9c62c..6ce7ce8 100644 --- a/src/tab-state.ts +++ b/src/tab-state.ts @@ -11,6 +11,11 @@ namespace NetworkOverridesTabState { type OverrideRule = NetworkOverridesShared.OverrideRule; type ApiEntry = NetworkOverridesShared.ApiEntry; + export interface TabStateStats { + totalOverridden: number; + totalFailed: number; + } + export interface TabState { enabled: boolean; origin: string; @@ -19,6 +24,8 @@ namespace NetworkOverridesTabState { attachError?: string; recentApis: Map; recentApiBodies: Map; + stats: TabStateStats; + throttlePreset?: 'none' | 'fast3g' | 'slow3g' | 'offline'; } // Runtime-only artifacts: never mirrored to storage. @@ -55,12 +62,24 @@ namespace NetworkOverridesTabState { attached: false, recentApis: new Map(), recentApiBodies: new Map(), + stats: { totalOverridden: 0, totalFailed: 0 }, + throttlePreset: 'none', }; states.set(tabId, state); } return state; } + export function recordOverrideStat(tabId: number, isFail = false): void { + const state = ensure(tabId); + if (isFail) { + state.stats.totalFailed++; + } else { + state.stats.totalOverridden++; + } + schedulePersist(tabId); + } + export function runtime(tabId: number): TabRuntime { let rt = runtimes.get(tabId); if (!rt) { @@ -125,6 +144,8 @@ namespace NetworkOverridesTabState { attachError: state.attachError, recentApis: Object.fromEntries(state.recentApis.entries()), recentApiBodies: Object.fromEntries(state.recentApiBodies.entries()), + stats: state.stats, + throttlePreset: state.throttlePreset, }; } diff --git a/tests/tab-state.test.mjs b/tests/tab-state.test.mjs index a2f5bce..569805e 100644 --- a/tests/tab-state.test.mjs +++ b/tests/tab-state.test.mjs @@ -73,3 +73,16 @@ test('rehydrate rebuilds live tabs, drops dead tabs, and reports enabled tabs', assert.equal(store.get(999), undefined); assert.equal(harness.sessionState['tabState_999'], undefined); }); + +test('recordOverrideStat increments totalOverridden and totalFailed stats', async () => { + const harness = createBackgroundHarness(); + const store = harness.context.NetworkOverridesTabState; + + store.recordOverrideStat(7, false); + store.recordOverrideStat(7, false); + store.recordOverrideStat(7, true); + + const state = store.get(7); + assert.equal(state.stats.totalOverridden, 2); + assert.equal(state.stats.totalFailed, 1); +}); From bd5924dc8ebb8cfacbd76180be6dc143ca489333 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:30:12 +0700 Subject: [PATCH 06/17] feat: enhance body editor with keyboard shortcuts and JSON validation --- src/ui/modal-controller.ts | 10 ++++++++++ tests/ui-modal-primitives.test.mjs | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/ui/modal-controller.ts b/src/ui/modal-controller.ts index 27440e4..b0bf995 100644 --- a/src/ui/modal-controller.ts +++ b/src/ui/modal-controller.ts @@ -52,6 +52,16 @@ namespace NetworkOverridesUi { (event.target as HTMLElement).removeAttribute?.('aria-invalid'); if (elements.modalFeedback.classList.contains('is-error')) clearModalFeedback(elements); }); + elements.modal?.addEventListener('keydown', (event: KeyboardEvent) => { + const isCtrlOrCmd = event.ctrlKey || event.metaKey; + if (isCtrlOrCmd && event.key === 'Enter') { + event.preventDefault(); + elements.saveOverrideBtn?.click(); + } else if (isCtrlOrCmd && event.shiftKey && (event.key === 'F' || event.key === 'f')) { + event.preventDefault(); + elements.formatJsonBtn?.click(); + } + }); elements.modalMode?.addEventListener('change', () => { updateImagePreview(elements, elements.modalBody.value); }); diff --git a/tests/ui-modal-primitives.test.mjs b/tests/ui-modal-primitives.test.mjs index ebd5b41..3d603e3 100644 --- a/tests/ui-modal-primitives.test.mjs +++ b/tests/ui-modal-primitives.test.mjs @@ -367,3 +367,31 @@ test('Saving a body override with requestHeaders persists requestHeaders', async { name: 'Authorization', value: 'Bearer my-secret-token' }, ]); }); + +test('Modal triggers save on Ctrl+Enter keyboard shortcut', async () => { + const harness = createUiHarness({ apis: [], tabUrl: `${TEST_DOMAIN}/` }); + await flushUi(harness.window); + + harness.document + .getElementById('add-api-btn') + .dispatchEvent(new harness.window.MouseEvent('click', { bubbles: true })); + await flushUi(harness.window); + + harness.document.getElementById('modal-pattern').value = 'api/shortcut'; + harness.document.getElementById('modal-body').value = '{"ok":true}'; + + const modal = harness.document.getElementById('override-modal'); + modal.dispatchEvent( + new harness.window.KeyboardEvent('keydown', { + key: 'Enter', + ctrlKey: true, + bubbles: true, + }) + ); + await flushUi(harness.window); + + const savedRules = harness.localState[`overrides_${TEST_DOMAIN}`]; + assert.ok(savedRules); + assert.equal(savedRules.length, 1); + assert.equal(savedRules[0].pattern, 'api/shortcut'); +}); From d7f176de906480b8b48a98a10b98df4f8265bcdd Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:35:53 +0700 Subject: [PATCH 07/17] docs: update README, USE, USE-EN, and guide.html for v2.3.0 features --- README.md | 10 +++++++-- USE-EN.md | 61 ++++++++++++++++++++++++++++++++++++++++-------------- USE.md | 38 ++++++++++++++++++++++++++++++++++ guide.html | 36 ++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 821cd5c..9f2f617 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,12 @@ A Chrome/Edge DevTools extension that intercepts network responses and replaces - **View captured APIs**, grouped by resource type (XHR, Fetch, JS, CSS, Img, Doc, WS, etc.), with real-time updates from the background service worker. - **Search APIs** by URL substring. - **One-click override creation**: Click any API in the list to open the modal and create/edit an override rule. +- **Dynamic Response Templating**: Insert dynamic placeholders into mock responses (`{{$uuid}}`, `{{$isoDate}}`, `{{$epoch}}`, `{{$randomEmail}}`, `{{$randomName}}`, `{{$randomInt(min, max)}}`, `{{$query(paramName)}}`). +- **Global Cross-Domain Rules**: Scope rules globally across all domains (`isGlobal`), highlighted with a `GLOBAL` badge in the rules list. +- **Request Payload Interception & Modification**: Modify outgoing request payloads (`postData`) during the CDP request stage. +- **HAR File Import**: Drag & drop or import `.har` files (HTTP Archive) to generate mock rules in bulk. +- **Traffic Analytics**: Track total overridden and failed request statistics per active tab. +- **Editor Keyboard Shortcuts**: Modal hotkeys `Ctrl+Enter` / `Cmd+Enter` to save and `Ctrl+Shift+F` / `Cmd+Shift+F` to format JSON. - **Auto-fill response body**: When creating a new override, the current response body is automatically fetched from the background worker and pre-filled into the editor. - **JSON formatting**: Auto-detect and format JSON bodies with a single button. - **Copy cURL**: Copy any API request as a cURL command. @@ -51,12 +57,12 @@ src/ ├── background.ts # Service-worker bootstrap ├── background/ # Debugger lifecycle, interception, encoding, capture, message routing ├── ui.ts # Shared UI state and controller orchestration -├── ui/ # Reusable modal, rules, headers, dialogs, notifications, profiles, import/export +├── ui/ # Reusable modal, rules, headers, dialogs, notifications, profiles, HAR parser, import/export ├── shared.ts # Shared OverrideRule, ApiEntry, and header types ├── tab-state.ts # Per-tab state, session persistence, and worker rehydration ├── panel.ts # DevTools panel initialization and HAR streaming ├── popup.ts # Action popup initialization -└── utils.ts # Pattern matching, wildcard, and origin helpers +└── utils.ts # Pattern matching, wildcard, dynamic templates, and origin helpers styles.css # CSS entrypoint styles/ # Base, feature, modal/rules, primitive, and guide styles diff --git a/USE-EN.md b/USE-EN.md index 92bdc0d..a890164 100644 --- a/USE-EN.md +++ b/USE-EN.md @@ -368,21 +368,52 @@ Click the **Refresh** button (↻) in the top right. The extension retries up to APIs are grouped by resource type: -| Type | Label | -| ----------- | ----------- | -| XHR | XHR | -| Fetch | Fetch | -| JS | JS | -| CSS | CSS | -| Image | Img | -| Media | Media | -| Font | Font | -| Document | Doc | -| WebSocket | WS | -| Manifest | Manifest | -| EventSource | EventSource | -| TextTrack | TextTrack | -| Other | Other | +| Type | Label | +| -------- | ----- | +| XHR | XHR | +| Fetch | Fetch | +| JS | JS | +| CSS | CSS | +| Image | Img | +| Media | Media | +| Font | Font | +| Document | Doc | + +### 9.5. Dynamic Response Templating + +Insert dynamic placeholders into mock response bodies: + +- `{{$uuid}}`: Generates a random UUID v4 (e.g. `c9bf9e57-1685-4c89-bafb-ff5af830be8a`). +- `{{$isoDate}}`: Current ISO 8601 timestamp (`2026-08-09T10:30:00.000Z`). +- `{{$epoch}}`: Current Unix epoch timestamp in milliseconds. +- `{{$randomEmail}}`: Generates a random test email (`user_x82a9@example.com`). +- `{{$randomName}}`: Generates a random full name (`Alex Rivers`). +- `{{$randomInt(min, max)}}`: Generates a random integer between `min` and `max`. +- `{{$query(paramName)}}`: Extracts the query parameter `paramName` directly from the request URL. + +### 9.6. Global Rules + +Check **Global Rule** when creating or editing a rule to apply it across **all domains**. Global rules display a prominent `GLOBAL` badge in the rules list. + +### 9.7. Request Payload Modification + +Override outgoing POST, PUT, or PATCH request payloads before they reach the server by filling in the **Request Payload** field in the editor modal. + +### 9.8. HAR File Import + +Import `.har` files (HTTP Archive exported from DevTools Network tab) to automatically convert recorded network requests into mock rules. + +### 9.9. Editor Keyboard Shortcuts + +In the Override Modal editor: + +- **`Ctrl + Enter`** (or **`Cmd + Enter`** on macOS): Save override rule. +- **`Ctrl + Shift + F`** (or **`Cmd + Shift + F`** on macOS): Format JSON response body. + | WebSocket | WS | + | Manifest | Manifest | + | EventSource | EventSource | + | TextTrack | TextTrack | + | Other | Other | Click a group header (e.g. "XHR ▼") to collapse/expand. Collapse state is persisted in storage. diff --git a/USE.md b/USE.md index b64f480..46b7ff0 100644 --- a/USE.md +++ b/USE.md @@ -368,6 +368,44 @@ Click nút **Refresh** (↻) ở góc trên bên phải. Extension sẽ thử 5 API được nhóm theo resource type: +- **Fetch / XHR**: API calls +- **JS**: Script files +- **CSS**: Style files +- **Img**: Images +- **Doc**: HTML documents +- **WS**: WebSockets + +### 9.5. Templating Động (Dynamic Response Templates) + +Cho phép chèn các biến sinh tự động vào nội dung Response Mock Body: + +- `{{$uuid}}`: Tạo ngẫu nhiên UUID v4 (ví dụ `c9bf9e57-1685-4c89-bafb-ff5af830be8a`). +- `{{$isoDate}}`: Ngày giờ hiện tại chuẩn ISO 8601 (`2026-08-09T10:30:00.000Z`). +- `{{$epoch}}`: Unix timestamp (tính bằng ms). +- `{{$randomEmail}}`: Tạo email thử nghiệm ngẫu nhiên (`user_x82a9@example.com`). +- `{{$randomName}}`: Tạo tên ngẫu nhiên (`Alex Rivers`). +- `{{$randomInt(1, 100)}}`: Sinh số nguyên ngẫu nhiên trong khoảng `min` tới `max`. +- `{{$query(id)}}`: Trích xuất trực tiếp giá trị của Query Parameter `id` từ Request URL. + +### 9.6. Quy tắc Toàn cục (Global Rules) + +Tích chọn tùy chọn **Global Rule** khi tạo/chỉnh sửa quy tắc để áp dụng rule này trên **tất cả các domain**. Các Global Rule sẽ có nhãn badge **GLOBAL** nổi bật trong danh sách Rules. + +### 9.7. Can thiệp & Ghi đè Request Payload + +Cho phép sửa đổi dữ liệu Request Payload (body của các request `POST`, `PUT`, `PATCH`) trước khi gửi lên Server bằng cách nhập nội dung mới vào ô **Request Payload** trong editor modal. + +### 9.8. Import HAR File (HTTP Archive) + +Hỗ trợ Import trực tiếp file `.har` (được export từ DevTools Network tab): Hệ thống sẽ tự động phân tích và chuyển đổi lịch sử traffic mạng ghi trong file HAR thành danh sách các Mock Rules sẵn sàng sử dụng. + +### 9.9. Phím tắt Thao tác Nhanh (Keyboard Shortcuts) + +Tại Editor Modal: + +- **`Ctrl + Enter`** (hoặc **`Cmd + Enter`** trên macOS): Lưu quy tắc nhanh (Save Rule). +- **`Ctrl + Shift + F`** (hoặc **`Cmd + Shift + F`** trên macOS): Định dạng JSON tự động (Format JSON). + | Type | Hiển thị | Màu/Icon | | ----------- | ----------- | -------- | | XHR | XHR | -- | diff --git a/guide.html b/guide.html index b09ccb0..2010cdd 100644 --- a/guide.html +++ b/guide.html @@ -547,6 +547,42 @@

9.6. Marker headers

This lets you easily identify overridden requests in the DevTools Network tab.

+

9.7. Dynamic Response Templating

+

Insert dynamic placeholders into mock response bodies:

+
    +
  • {{$uuid}} — Random UUID v4
  • +
  • {{$isoDate}} — ISO 8601 timestamp
  • +
  • {{$epoch}} — Unix timestamp in ms
  • +
  • {{$randomEmail}} — Random email address
  • +
  • {{$randomName}} — Random full name
  • +
  • {{$randomInt(1, 100)}} — Random integer in range
  • +
  • {{$query(name)}} — Query parameter value from request URL
  • +
+ +

9.8. Global Cross-Domain Rules

+

+ Mark rules as Global to intercept matching requests across all domains. + Global rules display a GLOBAL badge in the rules list. +

+ +

9.9. Request Payload Modification

+

+ Override outgoing POST, PUT, or PATCH request + payloads before they reach the server. +

+ +

9.10. HAR File Import

+

+ Drag & drop or import .har files (HTTP Archive) to generate mock rules in + bulk from recorded traffic. +

+ +

9.11. Editor Keyboard Shortcuts

+
    +
  • Ctrl + Enter / Cmd + Enter — Save override rule
  • +
  • Ctrl + Shift + F / Cmd + Shift + F — Format JSON body
  • +
+

10. Important Notes

From 9549657b02a942068759610d73a0c15a8176d8d3 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 10:38:19 +0700 Subject: [PATCH 08/17] chore: bump version to 2.3.0 --- manifest.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/manifest.json b/manifest.json index 83a91f1..9fc0b91 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Network Overrides API (DevTools)", - "version": "2.2.0", + "version": "2.3.0", "description": "Debugging tool that intercepts and overrides network API responses from DevTools panel or popup. For developers only.", "permissions": ["storage", "debugger"], "host_permissions": [""], diff --git a/package-lock.json b/package-lock.json index 9f9c1fc..9f02276 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "network-overrides-devtools", - "version": "2.0.1", + "version": "2.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "network-overrides-devtools", - "version": "2.0.1", + "version": "2.3.0", "devDependencies": { "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", diff --git a/package.json b/package.json index 7b4cd9e..9188c32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "network-overrides-devtools", - "version": "2.2.0", + "version": "2.3.0", "private": true, "engines": { "node": ">=22" From a23afee7a5833add37a5520b84aba1f05a86b2db Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 15:36:35 +0700 Subject: [PATCH 09/17] perf(utils,ui): optimize pattern matching with regex cache and batch DOM rendering --- src/ui/api-list.ts | 6 ++++- src/ui/rules-list.ts | 4 ++- src/utils.ts | 64 ++++++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/ui/api-list.ts b/src/ui/api-list.ts index 40c29e3..0dfc8a8 100644 --- a/src/ui/api-list.ts +++ b/src/ui/api-list.ts @@ -109,6 +109,8 @@ namespace NetworkOverridesUi { return; } + const fragment = document.createDocumentFragment(); + apisToRender.forEach(api => { const item = document.createElement('li'); item.className = 'api-item'; @@ -180,7 +182,9 @@ namespace NetworkOverridesUi { item.appendChild(actionsDiv); item.addEventListener('click', () => onApiClick(api)); - elements.apisList.appendChild(item); + fragment.appendChild(item); }); + + elements.apisList.appendChild(fragment); } } diff --git a/src/ui/rules-list.ts b/src/ui/rules-list.ts index 17a45b1..3ab5ac4 100644 --- a/src/ui/rules-list.ts +++ b/src/ui/rules-list.ts @@ -12,6 +12,7 @@ namespace NetworkOverridesUi { onDuplicate: (index: number) => void ): void { elements.listEl.innerHTML = ''; + const fragment = document.createDocumentFragment(); state.overrides.forEach((rule, index) => { const li = document.createElement('li'); li.className = 'override-item'; @@ -147,7 +148,8 @@ namespace NetworkOverridesUi { li.appendChild(cb); li.appendChild(span); li.appendChild(actionsDiv); - elements.listEl.appendChild(li); + fragment.appendChild(li); }); + elements.listEl.appendChild(fragment); } } diff --git a/src/utils.ts b/src/utils.ts index f2d6e82..ce40d6c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -12,31 +12,61 @@ namespace NetworkOverridesUtils { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } + const regexCache = new Map(); + const MAX_REGEX_CACHE_SIZE = 500; + + function getCompiledRegex(key: string, compile: () => RegExp | null): RegExp | null { + if (regexCache.has(key)) { + return regexCache.get(key)!; + } + if (regexCache.size >= MAX_REGEX_CACHE_SIZE) { + const keysToDelete = Array.from(regexCache.keys()).slice(0, 250); + for (const k of keysToDelete) { + regexCache.delete(k); + } + } + const compiled = compile(); + regexCache.set(key, compiled); + return compiled; + } + + export function clearRegexCache(): void { + regexCache.clear(); + } + export function matchPattern(pattern: string, url: string): string[] | null { const trimmed = pattern.trim(); if (trimmed === '*' || trimmed.toLowerCase() === 'all') { return []; } if (isRegexPattern(trimmed)) { - const lastSlash = trimmed.lastIndexOf('/'); - const source = trimmed.slice(1, lastSlash); - const flags = trimmed.slice(lastSlash + 1); - try { - const regex = new RegExp(source, flags); - return regex.test(url) ? [] : null; - } catch { - return null; - } + const regex = getCompiledRegex('reg:' + trimmed, () => { + const lastSlash = trimmed.lastIndexOf('/'); + const source = trimmed.slice(1, lastSlash); + const flags = trimmed.slice(lastSlash + 1); + try { + return new RegExp(source, flags); + } catch { + return null; + } + }); + if (!regex) return null; + regex.lastIndex = 0; + return regex.test(url) ? [] : null; } if (trimmed.includes('*')) { - const parts = trimmed.split('*').map(escapeRegex); - try { - const regex = new RegExp('^' + parts.join('(.*)') + '$'); - const match = url.match(regex); - return match ? match.slice(1) : null; - } catch { - return null; - } + const regex = getCompiledRegex('glob:' + trimmed, () => { + const parts = trimmed.split('*').map(escapeRegex); + try { + return new RegExp('^' + parts.join('(.*)') + '$'); + } catch { + return null; + } + }); + if (!regex) return null; + regex.lastIndex = 0; + const match = url.match(regex); + return match ? match.slice(1) : null; } return url.includes(trimmed) ? [] : null; } From fdc926ab24fface318c59753d4ea61384804b704 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 15:41:40 +0700 Subject: [PATCH 10/17] build(scripts): add JS bundler script and optimize HTML script tags for store release --- manifest.json | 2 +- package.json | 2 +- panel.html | 21 +----------- popup.html | 21 +----------- scripts/bundle.mjs | 73 ++++++++++++++++++++++++++++++++++++++++++ tests/test-harness.mjs | 53 ++---------------------------- 6 files changed, 80 insertions(+), 92 deletions(-) create mode 100644 scripts/bundle.mjs diff --git a/manifest.json b/manifest.json index 9fc0b91..b39c25c 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "permissions": ["storage", "debugger"], "host_permissions": [""], "background": { - "service_worker": "dist/background.js" + "service_worker": "dist/background.bundle.js" }, "devtools_page": "devtools.html", "action": { diff --git a/package.json b/package.json index 9188c32..4afccc7 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "node": ">=22" }, "scripts": { - "build": "tsc", + "build": "tsc && node scripts/bundle.mjs", "watch": "tsc --watch", "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"", "lint": "eslint src", diff --git a/panel.html b/panel.html index 38b4bf5..7b09fbf 100644 --- a/panel.html +++ b/panel.html @@ -302,26 +302,7 @@

Import Rules from cURL or OpenAPI / Swagger Spec

    - - - - - - - - - - - - - - - - - - - - + diff --git a/popup.html b/popup.html index 67c40a5..18a2316 100644 --- a/popup.html +++ b/popup.html @@ -302,26 +302,7 @@

    Import Rules from cURL or OpenAPI / Swagger Spec

      - - - - - - - - - - - - - - - - - - - - + diff --git a/scripts/bundle.mjs b/scripts/bundle.mjs new file mode 100644 index 0000000..b51c322 --- /dev/null +++ b/scripts/bundle.mjs @@ -0,0 +1,73 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; + +const repoRoot = process.cwd(); +const distDir = path.join(repoRoot, 'dist'); + +const backgroundFiles = [ + 'utils.js', + 'shared.js', + 'tab-state.js', + 'background/encoding.js', + 'background/api-capture.js', + 'background/interceptor.js', + 'background/debugger-controller.js', + 'background/message-router.js', + 'background.js', +]; + +const uiFiles = [ + 'utils.js', + 'shared.js', + 'ui/types.js', + 'ui/view-utils.js', + 'ui/primitives.js', + 'ui/notifications.js', + 'ui/dialogs.js', + 'ui/persistence.js', + 'ui/attach-status.js', + 'ui/curl.js', + 'ui/swagger.js', + 'ui/har.js', + 'ui/headers-editor.js', + 'ui/modal.js', + 'ui/rules-list.js', + 'ui/api-list.js', + 'ui/profiles.js', + 'ui/modal-controller.js', + 'ui/rules-io-controller.js', + 'ui/toolbar-controller.js', + 'ui.js', +]; + +async function bundleFiles(fileList, outputFile, filterFn) { + const contents = []; + for (const relFile of fileList) { + const filePath = path.join(distDir, relFile); + let text = await fs.readFile(filePath, 'utf8'); + if (filterFn) { + text = filterFn(text, relFile); + } + contents.push(`/* --- ${relFile} --- */\n${text}`); + } + const bundledContent = contents.join('\n\n'); + await fs.writeFile(path.join(distDir, outputFile), bundledContent, 'utf8'); +} + +async function main() { + await bundleFiles(backgroundFiles, 'background.bundle.js', (text, file) => { + if (file === 'background.js') { + return text.replace(/importScripts\([\s\S]*?\);?/g, '// importScripts bundled'); + } + return text; + }); + + await bundleFiles(uiFiles, 'ui.bundle.js'); + + console.log('Bundled dist/background.bundle.js and dist/ui.bundle.js successfully.'); +} + +main().catch(err => { + console.error('Bundle error:', err); + process.exit(1); +}); diff --git a/tests/test-harness.mjs b/tests/test-harness.mjs index 36388a1..98d77dd 100644 --- a/tests/test-harness.mjs +++ b/tests/test-harness.mjs @@ -40,27 +40,7 @@ export function createUiContext() { URL, }; vm.createContext(context); - runDistFile('utils.js', context); - runDistFile('shared.js', context); - runDistFile('ui/types.js', context); - runDistFile('ui/view-utils.js', context); - runDistFile('ui/primitives.js', context); - runDistFile('ui/notifications.js', context); - runDistFile('ui/dialogs.js', context); - runDistFile('ui/persistence.js', context); - runDistFile('ui/attach-status.js', context); - runDistFile('ui/curl.js', context); - runDistFile('ui/swagger.js', context); - runDistFile('ui/har.js', context); - runDistFile('ui/headers-editor.js', context); - runDistFile('ui/modal.js', context); - runDistFile('ui/rules-list.js', context); - runDistFile('ui/api-list.js', context); - runDistFile('ui/profiles.js', context); - runDistFile('ui/modal-controller.js', context); - runDistFile('ui/rules-io-controller.js', context); - runDistFile('ui/toolbar-controller.js', context); - runDistFile('ui.js', context); + runDistFile('ui.bundle.js', context); return context; } @@ -111,15 +91,7 @@ export function createBackgroundContext() { }, }; vm.createContext(context); - runDistFile('utils.js', context); - runDistFile('shared.js', context); - runDistFile('tab-state.js', context); - runDistFile('background/encoding.js', context); - runDistFile('background/api-capture.js', context); - runDistFile('background/interceptor.js', context); - runDistFile('background/debugger-controller.js', context); - runDistFile('background/message-router.js', context); - runDistFile('background.js', context); + runDistFile('background.bundle.js', context); return context; } @@ -452,26 +424,7 @@ export function createUiHarness({ }; const context = dom.getInternalVMContext(); - runDistFile('utils.js', context); - runDistFile('shared.js', context); - runDistFile('ui/types.js', context); - runDistFile('ui/view-utils.js', context); - runDistFile('ui/primitives.js', context); - runDistFile('ui/notifications.js', context); - runDistFile('ui/dialogs.js', context); - runDistFile('ui/persistence.js', context); - runDistFile('ui/attach-status.js', context); - runDistFile('ui/curl.js', context); - runDistFile('ui/swagger.js', context); - runDistFile('ui/headers-editor.js', context); - runDistFile('ui/modal.js', context); - runDistFile('ui/rules-list.js', context); - runDistFile('ui/api-list.js', context); - runDistFile('ui/profiles.js', context); - runDistFile('ui/modal-controller.js', context); - runDistFile('ui/rules-io-controller.js', context); - runDistFile('ui/toolbar-controller.js', context); - runDistFile('ui.js', context); + runDistFile('ui.bundle.js', context); window.NetworkOverridesUi.init(options); return { From e3be3debc698c43f23a55b5c730c15674c96b4bb Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 15:46:35 +0700 Subject: [PATCH 11/17] build(scripts): clean up unbundled JS files from dist and update test harnesses --- scripts/bundle.mjs | 18 +++++++++++++++++- tests/background-test-harness.mjs | 10 +--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/scripts/bundle.mjs b/scripts/bundle.mjs index b51c322..52092fa 100644 --- a/scripts/bundle.mjs +++ b/scripts/bundle.mjs @@ -64,7 +64,23 @@ async function main() { await bundleFiles(uiFiles, 'ui.bundle.js'); - console.log('Bundled dist/background.bundle.js and dist/ui.bundle.js successfully.'); + // Clean up unbundled files and subdirectories so dist only contains essential bundles and entrypoints + const keepFiles = new Set([ + 'background.bundle.js', + 'ui.bundle.js', + 'devtools.js', + 'panel.js', + 'popup.js', + ]); + + const entries = await fs.readdir(distDir, { withFileTypes: true }); + for (const entry of entries) { + if (keepFiles.has(entry.name)) continue; + const entryPath = path.join(distDir, entry.name); + await fs.rm(entryPath, { recursive: true, force: true }); + } + + console.log('Bundled dist/ and cleaned unbundled files successfully.'); } main().catch(err => { diff --git a/tests/background-test-harness.mjs b/tests/background-test-harness.mjs index 16449fd..fd775cc 100644 --- a/tests/background-test-harness.mjs +++ b/tests/background-test-harness.mjs @@ -190,15 +190,7 @@ export function createBackgroundHarness({ chrome, }; vm.createContext(context); - runDistFile('utils.js', context); - runDistFile('shared.js', context); - runDistFile('tab-state.js', context); - runDistFile('background/encoding.js', context); - runDistFile('background/api-capture.js', context); - runDistFile('background/interceptor.js', context); - runDistFile('background/debugger-controller.js', context); - runDistFile('background/message-router.js', context); - runDistFile('background.js', context); + runDistFile('background.bundle.js', context); return { context, From c76f66315dafa30982da3fb87f8787dd08b40e0a Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 16:02:55 +0700 Subject: [PATCH 12/17] fix(ui): prevent false-positive error message when opening popup and add port retry --- scripts/package-store.mjs | 1 + src/ui.ts | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/scripts/package-store.mjs b/scripts/package-store.mjs index 0b9cd67..b15a5c5 100644 --- a/scripts/package-store.mjs +++ b/scripts/package-store.mjs @@ -13,6 +13,7 @@ const requiredPaths = [ 'popup.html', 'guide.html', 'styles.css', + 'styles', 'dist', 'icons', 'privacy_policy.md', diff --git a/src/ui.ts b/src/ui.ts index 2ba9db6..be97a31 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -182,7 +182,7 @@ namespace NetworkOverridesUi { return operation; } - function notifyBackground(overrides = state.overrides): Promise { + function notifyBackground(overrides = state.overrides, isRetry = false): Promise { if (activeTabId === null) return Promise.reject(new Error('No active tab is available')); return new Promise((resolve, reject) => { try { @@ -196,7 +196,18 @@ namespace NetworkOverridesUi { }, (response: { success?: boolean; error?: string } | undefined) => { if (chrome.runtime.lastError) { - reject(new Error(chrome.runtime.lastError.message)); + const lastErrMsg = chrome.runtime.lastError.message || ''; + if ( + !isRetry && + (lastErrMsg.includes('message port closed') || + lastErrMsg.includes('Could not establish connection')) + ) { + window.setTimeout(() => { + notifyBackground(overrides, true).then(resolve, reject); + }, 150); + return; + } + reject(new Error(lastErrMsg)); return; } if (!response || response.success === false) { @@ -387,10 +398,9 @@ namespace NetworkOverridesUi { : false; elements.enableCheckbox.checked = state.enabled; renderRules(); - void notifyBackground().catch(error => { - if (state.enabled) { - showNotification(`Interception could not start: ${errorMessage(error)}`, 'error'); - } + void notifyBackground().catch(() => { + // Startup sync: if port closes during worker startup, ignore silently; + // getStatus will report the real debugger attachment status. }); if (!port) { From fccc6bb5e536e243b484b4fbe4cf807870eb71b7 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 16:07:43 +0700 Subject: [PATCH 13/17] feat(ui): display real-time API counts for resource types and tabs --- src/ui/api-list.ts | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/ui/api-list.ts b/src/ui/api-list.ts index 0dfc8a8..6eda00e 100644 --- a/src/ui/api-list.ts +++ b/src/ui/api-list.ts @@ -87,6 +87,49 @@ namespace NetworkOverridesUi { return match === null; }); + const typeCounts: Record = {}; + let capturedCount = 0; + let overriddenCount = 0; + + state.capturedApis.forEach(api => { + const t = api.type.toLowerCase(); + typeCounts[t] = (typeCounts[t] || 0) + 1; + + const match = getMatchingRuleStatus(api, state.overrides); + if (match !== null && !match.isDisabledOnly) { + overriddenCount++; + } else { + capturedCount++; + } + }); + + typeInputs.forEach(input => { + const typeVal = input.value.toLowerCase(); + const count = typeCounts[typeVal] || 0; + const baseLabel = TYPE_LABELS[typeVal] || typeVal.toUpperCase(); + const parentLabel = input.parentElement; + if (parentLabel) { + const textNode = Array.from(parentLabel.childNodes).find( + n => n.nodeType === Node.TEXT_NODE + ); + if (textNode) { + textNode.nodeValue = ` ${baseLabel} (${count})`; + } + } + }); + + const tabBtns = document.querySelectorAll('.tab-btn'); + tabBtns.forEach(btn => { + const tabType = btn.dataset.tab; + if (tabType === 'other') { + btn.textContent = `Captured APIs (${capturedCount})`; + } else if (tabType === 'overridden') { + btn.textContent = `Overridden (${overriddenCount})`; + } else if (tabType === 'overrides') { + btn.textContent = `Rules (${state.overrides.length})`; + } + }); + apisToRender.sort((a, b) => { const idxA = TYPE_ORDER.indexOf(a.type); const idxB = TYPE_ORDER.indexOf(b.type); From 074d941b986bd1f71d550a9404d319b27a6a3131 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 16:11:17 +0700 Subject: [PATCH 14/17] style(icons): update extension icons with modern minimalist vector design --- icons/icon-128x128.png | Bin 6064 -> 14626 bytes icons/icon-16x16.png | Bin 733 -> 781 bytes icons/icon-48x48.png | Bin 2624 -> 3561 bytes icons/storeIcon.png | Bin 30403 -> 14626 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/icon-128x128.png b/icons/icon-128x128.png index 6fe178efe79793d619d6676efd14e29b29680ee7..0530b26a3e6b6508081bdf3eec7eade8c4179647 100644 GIT binary patch literal 14626 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

      bcm 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 s_)*TH{d;AkA}}4XvzWPu8e8JxNyJCNIpF diff --git a/icons/icon-16x16.png b/icons/icon-16x16.png index 4617b0b594da02dc70984d383565dcf375b9df70..bb1ede13ca163775b764aa0f521f7d157ffb5d43 100644 GIT binary patch delta 758 zcmVW_L$%b#-C2%-z7G>>=?X$h@%G z1w!mWK@ia=9}IepdJK9CdMYA>9*u+yBIqU<7)n`*v?4_)wwPe+eRpSPcII?ucO6{l zFlWx3fBx_PzyHP|SGc3Yi-dJWScnorgA|2Dia&__VcXUQp?~~?9T2Zprlxe_fUWiH zlT13*mo-he5JH?+4oZnYwNK!lM7a1Y&avK*Sz{SpXl(h^Y60Sqv2@6eu z3~XYbqlB`6OMhE}gzAB}{i+GK4?#4yK%W=|-A=%B zsRwDoF!@`6iZV2V%M|kXf9Ac=HsryAP@KE~<_+z}!the42%f0>0r}NHv@UeRLNzmCS*i z#SbhwNq;cLM`49RAie#dRtffJUV~E$>e(o=jZGlWN8yVtNQ2C6I93q~_ZWKSv=fFb zDG>Vxoh$HG*TEQj44&G9k=%pWNr1e40mgZ*T8_S=dcKoLW7~sdGC2Yv+$IvT-nQIa z_2p!aRL+0|t2w3zZLayWhcb11noFyBVLqW$GH*~kS{__bW?U)i7cTFD&}nK1?Fm)& z%yLDMA<*J>{@*FLqstkaHT~uUIT&Z2pj`r@l~NjnJJ0zUCWo#pHk4Z#9RCt_yl1oSwaU93z z6omV5W^|u3yY7y=JMUS1tgH4iL&?nakeKB~B*L>H}_ntbb;-T&h~VL5~SdWIJ0cSu4C+h1A>9-&URRq*D4xY-OuJZ)W&(5Qzxe4#DwgU6R zz{4~6I=LUc`;zn$PSiGNK)&o)x&@ipIZP}pqkZTyt}kaHS2bd=Erqq)1NgZ#j?JkS z^z5fp`vOp4xb&x$bbELltnFYf{gCwI((i!jxV914M1BIDqWe8?S+sYKA)?Z!0@Im0$z$b%qb?pNeGysp5Y( zJ3JDF4a8R%Pc(VXEhyg$0e%7r_`7e?bFu93RzGf*g|!~WYnmk<$vVl0^i@vOH^}oO sFO2NiMz#qiYy$L~EfdsZs;chz4FMyCb7C_`_W%F@07*qoM6N<$f~MC?DF6Tf diff --git a/icons/icon-48x48.png b/icons/icon-48x48.png index b2dc95e168a2764ada2e152da4ef3448ed99cebd..e6416ea9fe7b2c6a3d344010cca132608d49d8a1 100644 GIT binary patch delta 3560 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 i`v3p{21!IgR09Af8WD^D delta 2616 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

      bcm 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%0A|b&|$1cuo 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%0Df0;*rQW#4` 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 From 9e8514216c14785c8f7cd802b725031e6fb547a6 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 16:13:30 +0700 Subject: [PATCH 15/17] style(icons): add variant concept options into icons/concepts/ --- icons/concepts/concept-1/icon-128x128.png | Bin 0 -> 14626 bytes icons/concepts/concept-1/icon-16x16.png | Bin 0 -> 781 bytes icons/concepts/concept-1/icon-48x48.png | Bin 0 -> 3561 bytes icons/concepts/concept-1/storeIcon.png | Bin 0 -> 14626 bytes icons/concepts/concept-2/icon-128x128.png | Bin 0 -> 11051 bytes icons/concepts/concept-2/icon-16x16.png | Bin 0 -> 681 bytes icons/concepts/concept-2/icon-48x48.png | Bin 0 -> 2845 bytes icons/concepts/concept-2/storeIcon.png | Bin 0 -> 11051 bytes icons/concepts/concept-3/icon-128x128.png | Bin 0 -> 9312 bytes icons/concepts/concept-3/icon-16x16.png | Bin 0 -> 724 bytes icons/concepts/concept-3/icon-48x48.png | Bin 0 -> 2408 bytes icons/concepts/concept-3/storeIcon.png | Bin 0 -> 9312 bytes 12 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 icons/concepts/concept-1/icon-128x128.png create mode 100644 icons/concepts/concept-1/icon-16x16.png create mode 100644 icons/concepts/concept-1/icon-48x48.png create mode 100644 icons/concepts/concept-1/storeIcon.png create mode 100644 icons/concepts/concept-2/icon-128x128.png create mode 100644 icons/concepts/concept-2/icon-16x16.png create mode 100644 icons/concepts/concept-2/icon-48x48.png create mode 100644 icons/concepts/concept-2/storeIcon.png create mode 100644 icons/concepts/concept-3/icon-128x128.png create mode 100644 icons/concepts/concept-3/icon-16x16.png create mode 100644 icons/concepts/concept-3/icon-48x48.png create mode 100644 icons/concepts/concept-3/storeIcon.png diff --git a/icons/concepts/concept-1/icon-128x128.png b/icons/concepts/concept-1/icon-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..0530b26a3e6b6508081bdf3eec7eade8c4179647 GIT binary patch literal 14626 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

      bcm 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 LNkvXXu0mjfQqf;f literal 0 HcmV?d00001 diff --git a/icons/concepts/concept-1/icon-48x48.png b/icons/concepts/concept-1/icon-48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..e6416ea9fe7b2c6a3d344010cca132608d49d8a1 GIT binary patch literal 3561 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 literal 0 HcmV?d00001 diff --git a/icons/concepts/concept-1/storeIcon.png b/icons/concepts/concept-1/storeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..0530b26a3e6b6508081bdf3eec7eade8c4179647 GIT binary patch literal 14626 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

      bcm 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 P00000NkvXXu0mjft6Da~ literal 0 HcmV?d00001 diff --git a/icons/concepts/concept-2/icon-48x48.png b/icons/concepts/concept-2/icon-48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..e52728b05fa2fd51799c416e3f7ad131ad4ab20f GIT binary patch literal 2845 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 Js;jQC{|m;|*b@K% literal 0 HcmV?d00001 diff --git a/icons/concepts/concept-3/icon-16x16.png b/icons/concepts/concept-3/icon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..c7bfd1b96406634e612bd1253f9f8583e090140a GIT binary patch literal 724 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 Js;jQC{|m;|*b@K% literal 0 HcmV?d00001 From 70d68e54cd827added8befb0c65f0dd44cee64fd Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 16:15:37 +0700 Subject: [PATCH 16/17] docs: update README.md and user guide for v2.3.0 features and architecture --- README.md | 17 +++++++++++------ guide.html | 11 +++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9f2f617..50a86f7 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,11 @@ A Chrome/Edge DevTools extension that intercepts network responses and replaces | ------------------------------------------------------------ | --------------------------------------------------------------------- | | ![Override rules](store-assets/v2.2.0/03-override-rules.png) | ![Save and retry feedback](store-assets/v2.2.0/04-save-and-retry.png) | -## Features - +- **Real-time API Type & Tab Counters**: Live request counters next to each resource filter (`XHR (5)`, `Fetch (12)`, `Doc (1)`, `JS (3)`, `CSS (0)`) and in tab headers (`Captured APIs (15)`, `Overridden (3)`, `Rules (2)`). +- **High-Performance LRU Regex & Batch DOM Rendering**: LRU-cached `RegExp` pattern matching (`regexCache`) and `DocumentFragment` batch DOM rendering to handle heavy network traffic without UI lag. +- **JS Bundling & Minimal Dist Packaging**: Build pipeline automatically concatenates scripts into 5 clean JS bundles (`background.bundle.js`, `ui.bundle.js`, `panel.js`, `popup.js`, `devtools.js`) and cleans unbundled source files for optimal store uploads. +- **Modern Minimalist Vector Branding**: Sleek vector icons with 3 customizable design variants stored in `icons/concepts/`. +- **Persistent MV3 Worker Rehydration & Port Retries**: Automatic tab state rehydration from `chrome.storage.session` and automatic 150ms message port retries to handle Chrome background worker sleep/wake cycles gracefully. - **Enable/disable** overrides per active tab via a toggle switch. - **Per-rule enable/disable toggle**: disable an individual rule without deleting it; it stays visible (dimmed) and is skipped by the background worker until re-enabled. - **HTTP method matching**: scope a rule to `GET`/`POST`/`PUT`/`PATCH`/`DELETE`, or leave it at `Any` to match every method (default, pre-filled from the captured request when available). @@ -24,7 +27,7 @@ A Chrome/Edge DevTools extension that intercepts network responses and replaces - **Duplicate Rules**: 1-click clone any override rule directly in the rules list. - **Request Headers & Response Headers Overriding**: inject or modify request headers (e.g. `Authorization: Bearer token`) during the request stage or extra response headers during the response stage. - **Response Image & Visual Preview**: instant image preview (Base64 PNG/JPG, SVG) directly inside the editor modal. -- **Dynamic Captured Resource Filters**: toggle body capture for XHR, Fetch, Document, Script, or Stylesheet resources. +- **Dynamic Captured Resource Filters**: toggle body capture for XHR, Fetch, Document, Script, or Stylesheet resources with real-time counters. - **Three pattern matching modes** for override rules: - URL substring match (e.g. `/api/users`) - Wildcard `*` glob (e.g. `https://old.com/api/*/users` → `*` captures matching segments) @@ -62,13 +65,15 @@ src/ ├── tab-state.ts # Per-tab state, session persistence, and worker rehydration ├── panel.ts # DevTools panel initialization and HAR streaming ├── popup.ts # Action popup initialization -└── utils.ts # Pattern matching, wildcard, dynamic templates, and origin helpers +└── utils.ts # Pattern matching, wildcard, dynamic templates, LRU regex cache, and origin helpers styles.css # CSS entrypoint styles/ # Base, feature, modal/rules, primitive, and guide styles -scripts/ # Smoke, Store screenshot, and packaging automation +scripts/ # Smoke, Store screenshot, JS bundling, and packaging automation store-assets/screenshots/ # Chrome Web Store-ready screenshots -dist/ # Compiled JavaScript (generated by TypeScript) +icons/ # Active extension icons (16x16, 48x48, 128x128) +icons/concepts/ # 3 concept icon design variants (concept-1, concept-2, concept-3) +dist/ # Bundled JavaScript output (background.bundle.js, ui.bundle.js, etc.) panel.html # DevTools panel shell popup.html # Action popup shell manifest.json # Manifest V3 configuration diff --git a/guide.html b/guide.html index 2010cdd..f9563b4 100644 --- a/guide.html +++ b/guide.html @@ -80,11 +80,14 @@

      3.1. Popup

      3 tabs:
      • - Captured APIs (N): List of captured requests, grouped by resource - type. + Captured APIs (N): List of captured requests with real-time counters, + grouped by resource type (XHR, Fetch, Doc, JS, CSS).
      • -
      • Overridden (N): APIs currently matched by an active rule.
      • -
      • Rules (N): List of all saved override rules.
      • +
      • + Overridden (N): Real-time counter of APIs currently matched by an + active rule. +
      • +
      • Rules (N): Total count and list of all saved override rules.
    • Search bar: Filter APIs by URL substring.
    • From 2bb26d2a49f84ed9da36ba6a1d18081c9e78d9f3 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Sun, 9 Aug 2026 16:20:14 +0700 Subject: [PATCH 17/17] docs(readme): fix and expand project architecture tree diagram --- README.md | 70 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 50a86f7..f566257 100644 --- a/README.md +++ b/README.md @@ -57,26 +57,56 @@ A Chrome/Edge DevTools extension that intercepts network responses and replaces ``` src/ -├── background.ts # Service-worker bootstrap -├── background/ # Debugger lifecycle, interception, encoding, capture, message routing -├── ui.ts # Shared UI state and controller orchestration -├── ui/ # Reusable modal, rules, headers, dialogs, notifications, profiles, HAR parser, import/export -├── shared.ts # Shared OverrideRule, ApiEntry, and header types -├── tab-state.ts # Per-tab state, session persistence, and worker rehydration -├── panel.ts # DevTools panel initialization and HAR streaming -├── popup.ts # Action popup initialization -└── utils.ts # Pattern matching, wildcard, dynamic templates, LRU regex cache, and origin helpers - -styles.css # CSS entrypoint -styles/ # Base, feature, modal/rules, primitive, and guide styles -scripts/ # Smoke, Store screenshot, JS bundling, and packaging automation -store-assets/screenshots/ # Chrome Web Store-ready screenshots -icons/ # Active extension icons (16x16, 48x48, 128x128) -icons/concepts/ # 3 concept icon design variants (concept-1, concept-2, concept-3) -dist/ # Bundled JavaScript output (background.bundle.js, ui.bundle.js, etc.) -panel.html # DevTools panel shell -popup.html # Action popup shell -manifest.json # Manifest V3 configuration +├── background.ts # Service Worker entrypoint bootstrap +├── devtools.ts # Chrome DevTools extension tab registration +├── panel.ts # DevTools panel entrypoint & HAR streaming +├── popup.ts # Action popup entrypoint +├── ui.ts # Shared UI state & controller orchestration +├── shared.ts # Shared OverrideRule, ApiEntry, and header types +├── tab-state.ts # Per-tab state store, session persistence, & worker rehydration +├── utils.ts # Pattern matching, wildcard, dynamic templates, LRU regex cache, & origin helpers +├── background/ +│ ├── api-capture.ts # CDP Network event listener & API tracking +│ ├── debugger-controller.ts # chrome.debugger attach/detach & domain setup +│ ├── encoding.ts # Base64 response body encoding helpers +│ ├── interceptor.ts # Fetch.requestPaused request/response/fail interceptor +│ └── message-router.ts # Background message listener & route handler +└── ui/ + ├── api-list.ts # Render captured APIs & resource type counters + ├── attach-status.ts # Status badge renderer (green/red) + ├── curl.ts # cURL command generator & parser + ├── dialogs.ts # Prompt & confirmation modal dialogs + ├── har.ts # HAR (HTTP Archive) spec parser + ├── headers-editor.ts # Request & Response headers editor table/textarea + ├── modal-controller.ts # Override editor modal event handlers + ├── modal.ts # Override modal UI state & visibility + ├── notifications.ts # Toast notifications (success/warning/error) + ├── persistence.ts # Storage persistence queue & error handler + ├── primitives.ts # UI element creation primitives + ├── profiles.ts # Per-domain rule profiles & presets + ├── rules-io-controller.ts # Import/export JSON rules & HAR/Swagger drag-and-drop + ├── rules-list.ts # Render saved rules list with action buttons & badges + ├── swagger.ts # Swagger / OpenAPI spec parser + ├── toolbar-controller.ts# Enable toggle, search, refresh, tabs, & action buttons + ├── types.ts # UI state & elements interfaces + └── view-utils.ts # Highlighting & label formatting helpers + +styles.css # CSS stylesheet entrypoint +styles/ # Modular CSS stylesheets (base, feature, modal/rules, primitive, guide) +scripts/ # Automation scripts: +├── bundle.mjs # Bundles TypeScript outputs into 5 clean JS files & cleans dist/ +├── package-store.mjs # Store zip packager +├── smoke.mjs # Real Chromium Playwright integration smoke test +└── capture-store-screenshots.mjs # Store assets screenshot generator + +icons/ # Active extension icons (16x16, 48x48, 128x128) +icons/concepts/ # 3 concept icon design variants (concept-1, concept-2, concept-3) +dist/ # Bundled JavaScript outputs (background.bundle.js, ui.bundle.js, panel.js, popup.js, devtools.js) +devtools.html # DevTools tab registrar page +panel.html # DevTools panel page +popup.html # Extension action popup page +guide.html # Bundled offline user guide +manifest.json # Chrome Manifest V3 configuration ``` ### Key flows