browser-debug-mcp-bridge 1.10.0 → 1.11.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/README.md +267 -195
- package/apps/mcp-server/dist/db/events-repository.js +61 -9
- package/apps/mcp-server/dist/db/events-repository.js.map +1 -1
- package/apps/mcp-server/dist/db/migrations.js +470 -70
- package/apps/mcp-server/dist/db/migrations.js.map +1 -1
- package/apps/mcp-server/dist/db/schema.js +134 -1
- package/apps/mcp-server/dist/db/schema.js.map +1 -1
- package/apps/mcp-server/dist/document-response-rewriter.js +196 -0
- package/apps/mcp-server/dist/document-response-rewriter.js.map +1 -0
- package/apps/mcp-server/dist/json-rewrite.js +189 -0
- package/apps/mcp-server/dist/json-rewrite.js.map +1 -0
- package/apps/mcp-server/dist/main.js +339 -2
- package/apps/mcp-server/dist/main.js.map +1 -1
- package/apps/mcp-server/dist/mcp/server.js +2146 -176
- package/apps/mcp-server/dist/mcp/server.js.map +1 -1
- package/apps/mcp-server/dist/next-asset-mapper.js +701 -0
- package/apps/mcp-server/dist/next-asset-mapper.js.map +1 -0
- package/apps/mcp-server/dist/next-source-override-planner.js +601 -0
- package/apps/mcp-server/dist/next-source-override-planner.js.map +1 -0
- package/apps/mcp-server/dist/override-audit-contract.js +51 -0
- package/apps/mcp-server/dist/override-audit-contract.js.map +1 -0
- package/apps/mcp-server/dist/override-audit.js +740 -0
- package/apps/mcp-server/dist/override-audit.js.map +1 -0
- package/apps/mcp-server/dist/override-capabilities.js +136 -0
- package/apps/mcp-server/dist/override-capabilities.js.map +1 -0
- package/apps/mcp-server/dist/override-observed-assets.js +179 -0
- package/apps/mcp-server/dist/override-observed-assets.js.map +1 -0
- package/apps/mcp-server/dist/override-poc.js +336 -0
- package/apps/mcp-server/dist/override-poc.js.map +1 -0
- package/apps/mcp-server/dist/override-profile-generator.js +403 -0
- package/apps/mcp-server/dist/override-profile-generator.js.map +1 -0
- package/apps/mcp-server/dist/override-response-planner.js +557 -0
- package/apps/mcp-server/dist/override-response-planner.js.map +1 -0
- package/apps/mcp-server/dist/override-rule-types.js +32 -0
- package/apps/mcp-server/dist/override-rule-types.js.map +1 -0
- package/apps/mcp-server/dist/retention.js +4 -3
- package/apps/mcp-server/dist/retention.js.map +1 -1
- package/apps/mcp-server/dist/rsc-flight-patch-safety.js +269 -0
- package/apps/mcp-server/dist/rsc-flight-patch-safety.js.map +1 -0
- package/apps/mcp-server/dist/websocket/messages.js +5 -0
- package/apps/mcp-server/dist/websocket/messages.js.map +1 -1
- package/apps/mcp-server/dist/websocket/websocket-server.js +10 -0
- package/apps/mcp-server/dist/websocket/websocket-server.js.map +1 -1
- package/apps/mcp-server/package.json +1 -0
- package/package.json +12 -1
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import { OVERRIDE_POC_FAILURE_CODES, OVERRIDE_PLAN_AUDIT_KINDS, OVERRIDE_POC_REQUEST_STATUSES, OVERRIDE_POC_RUN_STATUSES, } from '../override-audit-contract.js';
|
|
2
|
+
export const SCHEMA_VERSION = 14;
|
|
3
|
+
const OVERRIDE_POC_RUN_STATUS_SQL = OVERRIDE_POC_RUN_STATUSES.map((value) => `'${value}'`).join(', ');
|
|
4
|
+
const OVERRIDE_POC_REQUEST_STATUS_SQL = OVERRIDE_POC_REQUEST_STATUSES.map((value) => `'${value}'`).join(', ');
|
|
5
|
+
const OVERRIDE_POC_FAILURE_CODE_SQL = OVERRIDE_POC_FAILURE_CODES.map((value) => `'${value}'`).join(', ');
|
|
6
|
+
const OVERRIDE_PLAN_AUDIT_KIND_SQL = OVERRIDE_PLAN_AUDIT_KINDS.map((value) => `'${value}'`).join(', ');
|
|
2
7
|
export const CREATE_TABLES_SQL = `
|
|
3
8
|
-- Sessions table
|
|
4
9
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
5
10
|
session_id TEXT PRIMARY KEY,
|
|
6
11
|
created_at INTEGER NOT NULL,
|
|
12
|
+
last_seen_at INTEGER NOT NULL DEFAULT 0,
|
|
7
13
|
paused_at INTEGER,
|
|
8
14
|
ended_at INTEGER,
|
|
9
15
|
tab_id INTEGER,
|
|
@@ -212,6 +218,129 @@ CREATE INDEX IF NOT EXISTS idx_automation_steps_run_order ON automation_steps(ru
|
|
|
212
218
|
CREATE INDEX IF NOT EXISTS idx_automation_steps_session_started ON automation_steps(session_id, started_at);
|
|
213
219
|
CREATE INDEX IF NOT EXISTS idx_automation_steps_trace_id ON automation_steps(trace_id);
|
|
214
220
|
|
|
221
|
+
CREATE TABLE IF NOT EXISTS override_runs (
|
|
222
|
+
run_id TEXT PRIMARY KEY,
|
|
223
|
+
session_id TEXT NOT NULL,
|
|
224
|
+
started_at INTEGER NOT NULL,
|
|
225
|
+
ended_at INTEGER,
|
|
226
|
+
run_status TEXT NOT NULL CHECK(run_status IN (${OVERRIDE_POC_RUN_STATUS_SQL})),
|
|
227
|
+
tab_id INTEGER NOT NULL,
|
|
228
|
+
selected_tab_id INTEGER,
|
|
229
|
+
target_asset_url TEXT NOT NULL,
|
|
230
|
+
local_file_path TEXT NOT NULL,
|
|
231
|
+
resolved_local_file_path TEXT NOT NULL,
|
|
232
|
+
content_type TEXT NOT NULL,
|
|
233
|
+
auto_reload INTEGER NOT NULL DEFAULT 0,
|
|
234
|
+
config_path TEXT NOT NULL,
|
|
235
|
+
file_exists INTEGER NOT NULL DEFAULT 0,
|
|
236
|
+
file_size_bytes INTEGER,
|
|
237
|
+
matched_requests INTEGER NOT NULL DEFAULT 0,
|
|
238
|
+
fulfilled_requests INTEGER NOT NULL DEFAULT 0,
|
|
239
|
+
last_matched_at INTEGER,
|
|
240
|
+
last_fulfilled_at INTEGER,
|
|
241
|
+
last_error_code TEXT CHECK(last_error_code IN (${OVERRIDE_POC_FAILURE_CODE_SQL})),
|
|
242
|
+
last_error_message TEXT,
|
|
243
|
+
created_at INTEGER NOT NULL,
|
|
244
|
+
updated_at INTEGER NOT NULL,
|
|
245
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
CREATE INDEX IF NOT EXISTS idx_override_runs_session_started_at ON override_runs(session_id, started_at);
|
|
249
|
+
CREATE INDEX IF NOT EXISTS idx_override_runs_session_status_started_at ON override_runs(session_id, run_status, started_at);
|
|
250
|
+
|
|
251
|
+
CREATE TABLE IF NOT EXISTS override_requests (
|
|
252
|
+
request_log_id TEXT PRIMARY KEY,
|
|
253
|
+
run_id TEXT NOT NULL,
|
|
254
|
+
session_id TEXT NOT NULL,
|
|
255
|
+
request_id TEXT NOT NULL,
|
|
256
|
+
ts INTEGER NOT NULL,
|
|
257
|
+
request_url TEXT NOT NULL,
|
|
258
|
+
request_status TEXT NOT NULL CHECK(request_status IN (${OVERRIDE_POC_REQUEST_STATUS_SQL})),
|
|
259
|
+
failure_code TEXT CHECK(failure_code IN (${OVERRIDE_POC_FAILURE_CODE_SQL})),
|
|
260
|
+
error_message TEXT,
|
|
261
|
+
response_code INTEGER,
|
|
262
|
+
created_at INTEGER NOT NULL,
|
|
263
|
+
updated_at INTEGER NOT NULL,
|
|
264
|
+
FOREIGN KEY (run_id) REFERENCES override_runs(run_id) ON DELETE CASCADE,
|
|
265
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
CREATE INDEX IF NOT EXISTS idx_override_requests_session_ts ON override_requests(session_id, ts);
|
|
269
|
+
CREATE INDEX IF NOT EXISTS idx_override_requests_run_ts ON override_requests(run_id, ts);
|
|
270
|
+
CREATE INDEX IF NOT EXISTS idx_override_requests_status_ts ON override_requests(request_status, ts);
|
|
271
|
+
|
|
272
|
+
CREATE TABLE IF NOT EXISTS override_plan_audits (
|
|
273
|
+
plan_id TEXT PRIMARY KEY,
|
|
274
|
+
session_id TEXT,
|
|
275
|
+
created_at INTEGER NOT NULL,
|
|
276
|
+
planner_kind TEXT NOT NULL CHECK(planner_kind IN (${OVERRIDE_PLAN_AUDIT_KIND_SQL})),
|
|
277
|
+
tool_name TEXT NOT NULL,
|
|
278
|
+
profile_id TEXT,
|
|
279
|
+
rule_id TEXT NOT NULL,
|
|
280
|
+
rule_type TEXT NOT NULL,
|
|
281
|
+
request_method TEXT NOT NULL,
|
|
282
|
+
match_mode TEXT NOT NULL,
|
|
283
|
+
target_asset_url TEXT NOT NULL,
|
|
284
|
+
local_file_path TEXT,
|
|
285
|
+
config_path TEXT,
|
|
286
|
+
content_type TEXT NOT NULL,
|
|
287
|
+
original_sha256 TEXT,
|
|
288
|
+
patched_sha256 TEXT,
|
|
289
|
+
original_bytes INTEGER,
|
|
290
|
+
patched_bytes INTEGER,
|
|
291
|
+
patch_summary_json TEXT NOT NULL,
|
|
292
|
+
preview_json TEXT,
|
|
293
|
+
warnings_json TEXT NOT NULL,
|
|
294
|
+
blockers_json TEXT NOT NULL,
|
|
295
|
+
captured_from_live_session_json TEXT,
|
|
296
|
+
rollback_json TEXT NOT NULL,
|
|
297
|
+
updated_at INTEGER NOT NULL,
|
|
298
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE SET NULL
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
CREATE INDEX IF NOT EXISTS idx_override_plan_audits_session_created_at ON override_plan_audits(session_id, created_at);
|
|
302
|
+
CREATE INDEX IF NOT EXISTS idx_override_plan_audits_target_url ON override_plan_audits(target_asset_url);
|
|
303
|
+
CREATE INDEX IF NOT EXISTS idx_override_plan_audits_planner_kind ON override_plan_audits(planner_kind);
|
|
304
|
+
|
|
305
|
+
CREATE TABLE IF NOT EXISTS override_observed_assets (
|
|
306
|
+
observed_asset_id TEXT PRIMARY KEY,
|
|
307
|
+
session_id TEXT NOT NULL,
|
|
308
|
+
observed_at INTEGER NOT NULL,
|
|
309
|
+
last_seen_at INTEGER NOT NULL,
|
|
310
|
+
tab_id INTEGER,
|
|
311
|
+
page_url TEXT,
|
|
312
|
+
base_url TEXT,
|
|
313
|
+
page_title TEXT,
|
|
314
|
+
service_worker_controlled INTEGER NOT NULL DEFAULT 0,
|
|
315
|
+
csp_meta_json TEXT,
|
|
316
|
+
asset_url TEXT NOT NULL,
|
|
317
|
+
rule_type TEXT NOT NULL DEFAULT 'asset',
|
|
318
|
+
request_method TEXT NOT NULL DEFAULT 'GET',
|
|
319
|
+
resource_type TEXT,
|
|
320
|
+
content_type TEXT,
|
|
321
|
+
status_code INTEGER,
|
|
322
|
+
asset_path TEXT,
|
|
323
|
+
pathname TEXT,
|
|
324
|
+
kind TEXT,
|
|
325
|
+
initiator_type TEXT,
|
|
326
|
+
rel TEXT,
|
|
327
|
+
as_attr TEXT,
|
|
328
|
+
integrity TEXT,
|
|
329
|
+
from_dom INTEGER NOT NULL DEFAULT 0,
|
|
330
|
+
from_performance INTEGER NOT NULL DEFAULT 0,
|
|
331
|
+
from_navigation INTEGER NOT NULL DEFAULT 0,
|
|
332
|
+
from_fetch INTEGER NOT NULL DEFAULT 0,
|
|
333
|
+
payload_json TEXT NOT NULL,
|
|
334
|
+
created_at INTEGER NOT NULL,
|
|
335
|
+
updated_at INTEGER NOT NULL,
|
|
336
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_override_observed_assets_session_method_url ON override_observed_assets(session_id, request_method, asset_url);
|
|
340
|
+
CREATE INDEX IF NOT EXISTS idx_override_observed_assets_session_seen ON override_observed_assets(session_id, last_seen_at);
|
|
341
|
+
CREATE INDEX IF NOT EXISTS idx_override_observed_assets_asset_path ON override_observed_assets(asset_path);
|
|
342
|
+
CREATE INDEX IF NOT EXISTS idx_override_observed_assets_rule_type ON override_observed_assets(rule_type);
|
|
343
|
+
|
|
215
344
|
-- Schema version tracking
|
|
216
345
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
217
346
|
version INTEGER PRIMARY KEY,
|
|
@@ -240,6 +369,10 @@ export function clearDatabase(db) {
|
|
|
240
369
|
DELETE FROM snapshots;
|
|
241
370
|
DELETE FROM automation_steps;
|
|
242
371
|
DELETE FROM automation_runs;
|
|
372
|
+
DELETE FROM override_observed_assets;
|
|
373
|
+
DELETE FROM override_plan_audits;
|
|
374
|
+
DELETE FROM override_requests;
|
|
375
|
+
DELETE FROM override_runs;
|
|
243
376
|
DELETE FROM events;
|
|
244
377
|
DELETE FROM sessions;
|
|
245
378
|
DELETE FROM server_settings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtG,MAAM,+BAA+B,GAAG,6BAA6B,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9G,MAAM,6BAA6B,GAAG,0BAA0B,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzG,MAAM,4BAA4B,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEvG,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDA2NiB,2BAA2B;;;;;;;;;;;;;;;mDAe1B,6BAA6B;;;;;;;;;;;;;;;;;0DAiBtB,+BAA+B;6CAC5C,6BAA6B;;;;;;;;;;;;;;;;;sDAiBpB,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyEjF,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,EAAY;IAC3C,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAY;IAC3C,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAG9B,CAAC,CAAC,GAAG,EAAE,CAAC;IAET,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,EAAqC,CAAC;IACvI,OAAO,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAY;IACxC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;GAeP,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { load } from 'cheerio';
|
|
2
|
+
import { applyJsonPatches, assertJsonSerializableValue, } from './json-rewrite.js';
|
|
3
|
+
function normalizeOptionalString(value) {
|
|
4
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
5
|
+
}
|
|
6
|
+
function countOccurrences(source, search) {
|
|
7
|
+
return source.split(search).length - 1;
|
|
8
|
+
}
|
|
9
|
+
function normalizeExpectedCount(value, fieldName) {
|
|
10
|
+
if (value === undefined) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || Math.floor(value) < 0) {
|
|
14
|
+
throw new Error(`${fieldName} must be a non-negative finite number when provided`);
|
|
15
|
+
}
|
|
16
|
+
return Math.floor(value);
|
|
17
|
+
}
|
|
18
|
+
export function normalizeDocumentPatches(value) {
|
|
19
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
20
|
+
throw new Error('documentPatches must include at least one patch');
|
|
21
|
+
}
|
|
22
|
+
return value.map((entry, index) => {
|
|
23
|
+
if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
|
|
24
|
+
throw new Error(`documentPatches[${index}] must be an object`);
|
|
25
|
+
}
|
|
26
|
+
const patch = entry;
|
|
27
|
+
const operation = normalizeOptionalString(patch.operation);
|
|
28
|
+
if (!operation) {
|
|
29
|
+
throw new Error(`documentPatches[${index}].operation is required`);
|
|
30
|
+
}
|
|
31
|
+
const selector = normalizeOptionalString(patch.selector);
|
|
32
|
+
if (!selector) {
|
|
33
|
+
throw new Error(`documentPatches[${index}].selector must be a non-empty string`);
|
|
34
|
+
}
|
|
35
|
+
switch (operation) {
|
|
36
|
+
case 'replaceText': {
|
|
37
|
+
const search = normalizeOptionalString(patch.search);
|
|
38
|
+
if (!search) {
|
|
39
|
+
throw new Error(`documentPatches[${index}].search must be a non-empty string`);
|
|
40
|
+
}
|
|
41
|
+
if (typeof patch.replacement !== 'string') {
|
|
42
|
+
throw new Error(`documentPatches[${index}].replacement must be a string`);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
operation,
|
|
46
|
+
selector,
|
|
47
|
+
search,
|
|
48
|
+
replacement: patch.replacement,
|
|
49
|
+
expectedCount: normalizeExpectedCount(patch.expectedCount, `documentPatches[${index}].expectedCount`),
|
|
50
|
+
required: patch.required !== false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
case 'removeElement':
|
|
54
|
+
return {
|
|
55
|
+
operation,
|
|
56
|
+
selector,
|
|
57
|
+
expectedCount: normalizeExpectedCount(patch.expectedCount, `documentPatches[${index}].expectedCount`),
|
|
58
|
+
required: patch.required !== false,
|
|
59
|
+
};
|
|
60
|
+
case 'replaceJsonValue': {
|
|
61
|
+
const path = normalizeOptionalString(patch.path);
|
|
62
|
+
if (!path || path === '/' || !path.startsWith('/')) {
|
|
63
|
+
throw new Error(`documentPatches[${index}].path must be a non-root JSON Pointer path starting with /`);
|
|
64
|
+
}
|
|
65
|
+
if (!Object.prototype.hasOwnProperty.call(patch, 'value')) {
|
|
66
|
+
throw new Error(`documentPatches[${index}].value is required`);
|
|
67
|
+
}
|
|
68
|
+
assertJsonSerializableValue(patch.value, `documentPatches[${index}].value`);
|
|
69
|
+
if (Object.prototype.hasOwnProperty.call(patch, 'expectedValue')) {
|
|
70
|
+
assertJsonSerializableValue(patch.expectedValue, `documentPatches[${index}].expectedValue`);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
operation,
|
|
74
|
+
selector,
|
|
75
|
+
path,
|
|
76
|
+
value: patch.value,
|
|
77
|
+
expectedValue: Object.prototype.hasOwnProperty.call(patch, 'expectedValue') ? patch.expectedValue : undefined,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`documentPatches[${index}].operation must be replaceText, removeElement, or replaceJsonValue`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function applyTextPatchToNode(node, patch) {
|
|
86
|
+
let matchedTextCount = 0;
|
|
87
|
+
if (node.type === 'text' && typeof node.data === 'string') {
|
|
88
|
+
const localMatches = countOccurrences(node.data, patch.search);
|
|
89
|
+
if (localMatches > 0) {
|
|
90
|
+
node.data = node.data.split(patch.search).join(patch.replacement);
|
|
91
|
+
matchedTextCount += localMatches;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const child of node.children ?? []) {
|
|
95
|
+
matchedTextCount += applyTextPatchToNode(child, patch);
|
|
96
|
+
}
|
|
97
|
+
return matchedTextCount;
|
|
98
|
+
}
|
|
99
|
+
export function applyDocumentPatches(body, patches) {
|
|
100
|
+
const $ = load(body, { scriptingEnabled: false });
|
|
101
|
+
const applied = [];
|
|
102
|
+
const warnings = [];
|
|
103
|
+
for (const patch of patches) {
|
|
104
|
+
const selection = $(patch.selector);
|
|
105
|
+
const matchedElementCount = selection.length;
|
|
106
|
+
switch (patch.operation) {
|
|
107
|
+
case 'replaceText': {
|
|
108
|
+
if (matchedElementCount === 0 && patch.required) {
|
|
109
|
+
throw new Error(`Document patch selector did not match any elements: ${patch.selector}`);
|
|
110
|
+
}
|
|
111
|
+
if (matchedElementCount === 0) {
|
|
112
|
+
warnings.push(`Optional document patch selector did not match any elements: ${patch.selector}`);
|
|
113
|
+
applied.push({
|
|
114
|
+
...patch,
|
|
115
|
+
matchedElementCount: 0,
|
|
116
|
+
matchedTextCount: 0,
|
|
117
|
+
});
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
let matchedTextCount = 0;
|
|
121
|
+
selection.each((_index, node) => {
|
|
122
|
+
matchedTextCount += applyTextPatchToNode(node, patch);
|
|
123
|
+
});
|
|
124
|
+
if (patch.expectedCount !== undefined && matchedTextCount !== patch.expectedCount) {
|
|
125
|
+
throw new Error(`Document patch ${patch.selector} matched ${matchedTextCount} text occurrence(s), expected ${patch.expectedCount}`);
|
|
126
|
+
}
|
|
127
|
+
if (matchedTextCount === 0 && patch.required) {
|
|
128
|
+
throw new Error(`Document patch text was not found within selector ${patch.selector}: ${JSON.stringify(patch.search)}`);
|
|
129
|
+
}
|
|
130
|
+
if (matchedTextCount === 0) {
|
|
131
|
+
warnings.push(`Optional document patch text was not found within selector ${patch.selector}: ${JSON.stringify(patch.search)}`);
|
|
132
|
+
}
|
|
133
|
+
if (matchedTextCount > 0 && patch.search === patch.replacement) {
|
|
134
|
+
warnings.push(`Document patch ${patch.selector} is a no-op replacement.`);
|
|
135
|
+
}
|
|
136
|
+
applied.push({
|
|
137
|
+
...patch,
|
|
138
|
+
matchedElementCount,
|
|
139
|
+
matchedTextCount,
|
|
140
|
+
});
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
case 'removeElement': {
|
|
144
|
+
if (patch.expectedCount !== undefined && matchedElementCount !== patch.expectedCount) {
|
|
145
|
+
throw new Error(`Document patch ${patch.selector} matched ${matchedElementCount} element(s), expected ${patch.expectedCount}`);
|
|
146
|
+
}
|
|
147
|
+
if (matchedElementCount === 0 && patch.required) {
|
|
148
|
+
throw new Error(`Document patch selector did not match any elements: ${patch.selector}`);
|
|
149
|
+
}
|
|
150
|
+
if (matchedElementCount === 0) {
|
|
151
|
+
warnings.push(`Optional document patch selector did not match any elements: ${patch.selector}`);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
selection.remove();
|
|
155
|
+
}
|
|
156
|
+
applied.push({
|
|
157
|
+
...patch,
|
|
158
|
+
removedCount: matchedElementCount,
|
|
159
|
+
});
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
case 'replaceJsonValue': {
|
|
163
|
+
if (matchedElementCount !== 1) {
|
|
164
|
+
throw new Error(`Document JSON patch selector ${patch.selector} matched ${matchedElementCount} element(s), expected exactly 1`);
|
|
165
|
+
}
|
|
166
|
+
const currentJson = selection.html();
|
|
167
|
+
if (typeof currentJson !== 'string' || currentJson.trim().length === 0) {
|
|
168
|
+
throw new Error(`Document JSON patch selector ${patch.selector} does not contain JSON text`);
|
|
169
|
+
}
|
|
170
|
+
const jsonResult = applyJsonPatches(currentJson, [{
|
|
171
|
+
operation: 'replace',
|
|
172
|
+
path: patch.path,
|
|
173
|
+
value: patch.value,
|
|
174
|
+
expectedValue: patch.expectedValue,
|
|
175
|
+
}]);
|
|
176
|
+
selection.text(jsonResult.patchedBody.trimEnd());
|
|
177
|
+
warnings.push(...jsonResult.warnings.map((warning) => `Document JSON patch ${patch.selector}: ${warning}`));
|
|
178
|
+
applied.push({
|
|
179
|
+
...patch,
|
|
180
|
+
matchedElementCount,
|
|
181
|
+
appliedJsonPatches: jsonResult.applied,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const patchedBody = $.html();
|
|
187
|
+
if (patchedBody === body) {
|
|
188
|
+
throw new Error('No document patch changed the body');
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
patchedBody,
|
|
192
|
+
applied,
|
|
193
|
+
warnings,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=document-response-rewriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-response-rewriter.js","sourceRoot":"","sources":["../src/document-response-rewriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
function normalizeOptionalString(value) {
|
|
2
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
3
|
+
}
|
|
4
|
+
function hasOwnProperty(value, key) {
|
|
5
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
6
|
+
}
|
|
7
|
+
function isJsonRecord(value) {
|
|
8
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
export function assertJsonSerializableValue(value, fieldName) {
|
|
11
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean') {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (typeof value === 'number') {
|
|
15
|
+
if (!Number.isFinite(value)) {
|
|
16
|
+
throw new Error(`${fieldName} must be a finite JSON number`);
|
|
17
|
+
}
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
value.forEach((entry, index) => assertJsonSerializableValue(entry, `${fieldName}[${index}]`));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === 'object' && value !== null) {
|
|
25
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
26
|
+
assertJsonSerializableValue(entry, `${fieldName}.${key}`);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
throw new Error(`${fieldName} must be a JSON-serializable value`);
|
|
31
|
+
}
|
|
32
|
+
export function normalizeJsonPatches(value) {
|
|
33
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
34
|
+
throw new Error('jsonPatches must include at least one patch');
|
|
35
|
+
}
|
|
36
|
+
return value.map((entry, index) => {
|
|
37
|
+
if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
|
|
38
|
+
throw new Error(`jsonPatches[${index}] must be an object`);
|
|
39
|
+
}
|
|
40
|
+
const patch = entry;
|
|
41
|
+
const operation = normalizeOptionalString(patch.operation ?? patch.op) ?? 'replace';
|
|
42
|
+
if (operation !== 'replace') {
|
|
43
|
+
throw new Error(`jsonPatches[${index}].operation must be replace`);
|
|
44
|
+
}
|
|
45
|
+
const path = normalizeOptionalString(patch.path);
|
|
46
|
+
if (!path || path === '/' || !path.startsWith('/')) {
|
|
47
|
+
throw new Error(`jsonPatches[${index}].path must be a non-root JSON Pointer path starting with /`);
|
|
48
|
+
}
|
|
49
|
+
if (!hasOwnProperty(patch, 'value')) {
|
|
50
|
+
throw new Error(`jsonPatches[${index}].value is required`);
|
|
51
|
+
}
|
|
52
|
+
assertJsonSerializableValue(patch.value, `jsonPatches[${index}].value`);
|
|
53
|
+
const normalized = {
|
|
54
|
+
operation,
|
|
55
|
+
path,
|
|
56
|
+
value: patch.value,
|
|
57
|
+
};
|
|
58
|
+
if (hasOwnProperty(patch, 'expectedValue')) {
|
|
59
|
+
assertJsonSerializableValue(patch.expectedValue, `jsonPatches[${index}].expectedValue`);
|
|
60
|
+
normalized.expectedValue = patch.expectedValue;
|
|
61
|
+
}
|
|
62
|
+
return normalized;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function decodeJsonPointer(path) {
|
|
66
|
+
return path.slice(1).split('/').map((segment) => {
|
|
67
|
+
if (/~(?![01])/u.test(segment)) {
|
|
68
|
+
throw new Error(`JSON patch path contains an invalid JSON Pointer escape: ${path}`);
|
|
69
|
+
}
|
|
70
|
+
const decoded = segment.replace(/~1/gu, '/').replace(/~0/gu, '~');
|
|
71
|
+
if (decoded === '__proto__' || decoded === 'prototype' || decoded === 'constructor') {
|
|
72
|
+
throw new Error(`JSON patch path contains an unsafe segment: ${decoded}`);
|
|
73
|
+
}
|
|
74
|
+
return decoded;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function parseArrayIndex(segment, length, path) {
|
|
78
|
+
if (!/^(0|[1-9]\d*)$/u.test(segment)) {
|
|
79
|
+
throw new Error(`JSON patch path ${path} expected an array index, got ${JSON.stringify(segment)}`);
|
|
80
|
+
}
|
|
81
|
+
const index = Number(segment);
|
|
82
|
+
if (!Number.isSafeInteger(index) || index < 0 || index >= length) {
|
|
83
|
+
throw new Error(`JSON patch path ${path} array index ${segment} does not exist`);
|
|
84
|
+
}
|
|
85
|
+
return index;
|
|
86
|
+
}
|
|
87
|
+
function readJsonChild(parent, segment, path) {
|
|
88
|
+
if (Array.isArray(parent)) {
|
|
89
|
+
return parent[parseArrayIndex(segment, parent.length, path)];
|
|
90
|
+
}
|
|
91
|
+
if (isJsonRecord(parent)) {
|
|
92
|
+
if (!hasOwnProperty(parent, segment)) {
|
|
93
|
+
throw new Error(`JSON patch path does not exist: ${path}`);
|
|
94
|
+
}
|
|
95
|
+
return parent[segment];
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`JSON patch path cannot traverse non-container value: ${path}`);
|
|
98
|
+
}
|
|
99
|
+
function writeJsonChild(parent, segment, path, value) {
|
|
100
|
+
if (Array.isArray(parent)) {
|
|
101
|
+
const index = parseArrayIndex(segment, parent.length, path);
|
|
102
|
+
const previous = parent[index];
|
|
103
|
+
parent[index] = cloneJsonValue(value);
|
|
104
|
+
return previous;
|
|
105
|
+
}
|
|
106
|
+
if (isJsonRecord(parent)) {
|
|
107
|
+
if (!hasOwnProperty(parent, segment)) {
|
|
108
|
+
throw new Error(`JSON patch path does not exist: ${path}`);
|
|
109
|
+
}
|
|
110
|
+
const previous = parent[segment];
|
|
111
|
+
parent[segment] = cloneJsonValue(value);
|
|
112
|
+
return previous;
|
|
113
|
+
}
|
|
114
|
+
throw new Error(`JSON patch path cannot replace non-container value: ${path}`);
|
|
115
|
+
}
|
|
116
|
+
function cloneJsonValue(value) {
|
|
117
|
+
return JSON.parse(JSON.stringify(value));
|
|
118
|
+
}
|
|
119
|
+
function jsonValuesEqual(left, right) {
|
|
120
|
+
if (left === right) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
124
|
+
return Array.isArray(left)
|
|
125
|
+
&& Array.isArray(right)
|
|
126
|
+
&& left.length === right.length
|
|
127
|
+
&& left.every((entry, index) => jsonValuesEqual(entry, right[index]));
|
|
128
|
+
}
|
|
129
|
+
if (isJsonRecord(left) || isJsonRecord(right)) {
|
|
130
|
+
if (!isJsonRecord(left) || !isJsonRecord(right)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
const leftKeys = Object.keys(left);
|
|
134
|
+
const rightKeys = Object.keys(right);
|
|
135
|
+
return leftKeys.length === rightKeys.length
|
|
136
|
+
&& leftKeys.every((key) => hasOwnProperty(right, key) && jsonValuesEqual(left[key], right[key]));
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
function resolveJsonPatchParent(root, path) {
|
|
141
|
+
const segments = decodeJsonPointer(path);
|
|
142
|
+
if (segments.length === 0) {
|
|
143
|
+
throw new Error(`JSON patch path must not target the root document: ${path}`);
|
|
144
|
+
}
|
|
145
|
+
let current = root;
|
|
146
|
+
for (const segment of segments.slice(0, -1)) {
|
|
147
|
+
current = readJsonChild(current, segment, path);
|
|
148
|
+
}
|
|
149
|
+
return { parent: current, leaf: segments[segments.length - 1] };
|
|
150
|
+
}
|
|
151
|
+
export function applyJsonPatches(body, patches) {
|
|
152
|
+
let parsed;
|
|
153
|
+
try {
|
|
154
|
+
parsed = JSON.parse(body);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new Error(`Original response body must remain valid JSON: ${error instanceof Error ? error.message : 'invalid JSON'}`);
|
|
158
|
+
}
|
|
159
|
+
const applied = [];
|
|
160
|
+
const warnings = [];
|
|
161
|
+
let changed = false;
|
|
162
|
+
for (const patch of patches) {
|
|
163
|
+
const { parent, leaf } = resolveJsonPatchParent(parsed, patch.path);
|
|
164
|
+
const previousValue = readJsonChild(parent, leaf, patch.path);
|
|
165
|
+
if (patch.expectedValue !== undefined && !jsonValuesEqual(previousValue, patch.expectedValue)) {
|
|
166
|
+
throw new Error(`JSON patch ${patch.path} expected value did not match the response body`);
|
|
167
|
+
}
|
|
168
|
+
writeJsonChild(parent, leaf, patch.path, patch.value);
|
|
169
|
+
if (jsonValuesEqual(previousValue, patch.value)) {
|
|
170
|
+
warnings.push(`JSON patch ${patch.path} is a no-op replacement.`);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
changed = true;
|
|
174
|
+
}
|
|
175
|
+
applied.push({
|
|
176
|
+
...patch,
|
|
177
|
+
previousValue: cloneJsonValue(previousValue),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (!changed) {
|
|
181
|
+
throw new Error('No JSON response patch changed the body');
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
patchedBody: `${JSON.stringify(parsed)}\n`,
|
|
185
|
+
applied,
|
|
186
|
+
warnings,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=json-rewrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-rewrite.js","sourceRoot":"","sources":["../src/json-rewrite.ts"],"names":[],"mappings":"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"}
|