@wenathlan/extension 1.1.45 → 1.1.47
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 +6 -4
- package/dist/cdpbus.d.ts +104 -0
- package/dist/cdpbus.d.ts.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1065 -9
- package/dist/index.js.map +4 -4
- package/dist/memory.d.ts +88 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +34 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/profilers.d.ts +167 -0
- package/dist/profilers.d.ts.map +1 -0
- package/dist/protocol.d.ts +65 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/runtimeline.d.ts +1 -1
- package/dist/runtimeline.d.ts.map +1 -1
- package/dist/types.d.ts +270 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +1672 -11
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +376 -3
- package/extension/dist/pagebridge.js.map +4 -4
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +15 -7
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +287 -3
- package/extension/dist/sidepanel.js.map +2 -2
- package/extension/dist/style.css +2 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -196,6 +196,143 @@ function annotationplanof(input) {
|
|
|
196
196
|
return plan;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
// cdpbus.ts
|
|
200
|
+
var cdpkinds = ["attachcdp", "detachcdp", "cdpcmd", "watchcdp", "setbreakpoint", "stepcode", "watchexpr", "overridescript"];
|
|
201
|
+
var cdpdomains = ["Runtime", "Log", "Debugger", "DOM", "Network", "Page"];
|
|
202
|
+
function methoddomain(method) {
|
|
203
|
+
const match = /^([A-Z][A-Za-z]*)\.([a-zA-Z][A-Za-z0-9]*)$/.exec(method.trim());
|
|
204
|
+
return match?.[1];
|
|
205
|
+
}
|
|
206
|
+
function cdpallowlistof(value) {
|
|
207
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
208
|
+
const entry = value;
|
|
209
|
+
const domains = Array.isArray(entry.domains) ? entry.domains.filter((domain) => typeof domain === "string" && cdpdomains.includes(domain)) : [];
|
|
210
|
+
if (domains.length === 0) return void 0;
|
|
211
|
+
if (entry.methods === void 0) return { domains };
|
|
212
|
+
const methods = Array.isArray(entry.methods) ? entry.methods.filter((method) => typeof method === "string" && methoddomain(method) !== void 0 && domains.includes(methoddomain(method))) : [];
|
|
213
|
+
if (methods.length === 0) return void 0;
|
|
214
|
+
return { domains, methods };
|
|
215
|
+
}
|
|
216
|
+
function allowlistcovers(allowlist, method) {
|
|
217
|
+
const domain = methoddomain(method);
|
|
218
|
+
if (domain === void 0) return false;
|
|
219
|
+
if (!allowlist.domains.includes(domain)) return false;
|
|
220
|
+
if (allowlist.methods !== void 0 && !allowlist.methods.includes(method)) return false;
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
function attachcdpsession(input) {
|
|
224
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, tabid: input.tabid, origin: input.origin, attachedat: input.now, domains: [...new Set(input.domains)], debuggerversion: input.debuggerversion };
|
|
225
|
+
}
|
|
226
|
+
function detachcdpsession(session, at, userdetached = false) {
|
|
227
|
+
return { ...session, detachedat: at, ...userdetached ? { userdetached: true } : {} };
|
|
228
|
+
}
|
|
229
|
+
function sendcdpcommand(input) {
|
|
230
|
+
const domain = methoddomain(input.method);
|
|
231
|
+
if (domain === void 0) return { ...input, method: input.method.trim(), domain: "", duration: input.duration, ...input.errorclass !== void 0 ? { errorclass: input.errorclass } : { errorclass: "malformedmethod" }, at: input.at };
|
|
232
|
+
return { ...input, method: input.method.trim(), domain, duration: input.duration, ...input.errorclass !== void 0 ? { errorclass: input.errorclass } : {}, at: input.at };
|
|
233
|
+
}
|
|
234
|
+
function serializecdpcommand(queue, command) {
|
|
235
|
+
return [...queue, command];
|
|
236
|
+
}
|
|
237
|
+
function cdpeventruleof(value) {
|
|
238
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
239
|
+
const entry = value;
|
|
240
|
+
const domain = typeof entry.domain === "string" && cdpdomains.includes(entry.domain) ? entry.domain : void 0;
|
|
241
|
+
const event = typeof entry.event === "string" && entry.event.trim() ? entry.event.trim() : void 0;
|
|
242
|
+
if (domain === void 0 || event === void 0) return void 0;
|
|
243
|
+
const match = typeof entry.match === "string" && entry.match.trim() ? entry.match.trim() : void 0;
|
|
244
|
+
return { domain, event, ...match !== void 0 ? { match } : {} };
|
|
245
|
+
}
|
|
246
|
+
function watchcdpevents(rules, events) {
|
|
247
|
+
const matched = [];
|
|
248
|
+
const counts = {};
|
|
249
|
+
for (const domain of cdpdomains) counts[domain] = 0;
|
|
250
|
+
for (const event of events) {
|
|
251
|
+
for (const rule of rules) {
|
|
252
|
+
if (rule.domain !== event.domain || rule.event !== event.event) continue;
|
|
253
|
+
if (rule.match !== void 0 && !(event.payload ?? "").includes(rule.match)) continue;
|
|
254
|
+
matched.push({ ruleid: rule.id, domain: event.domain, event: event.event, ...event.payload !== void 0 ? { payload: event.payload } : {} });
|
|
255
|
+
counts[event.domain] = (counts[event.domain] ?? 0) + 1;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return { matched, counts };
|
|
259
|
+
}
|
|
260
|
+
function breakpointinputof(value) {
|
|
261
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
262
|
+
const entry = value;
|
|
263
|
+
const url = typeof entry.url === "string" && entry.url.trim() ? entry.url.trim() : void 0;
|
|
264
|
+
const line = typeof entry.line === "number" && Number.isInteger(entry.line) && entry.line >= 0 ? entry.line : void 0;
|
|
265
|
+
if (url === void 0 || line === void 0) return void 0;
|
|
266
|
+
const column = typeof entry.column === "number" && Number.isInteger(entry.column) && entry.column >= 0 ? entry.column : void 0;
|
|
267
|
+
const condition = typeof entry.condition === "string" && entry.condition.trim() ? entry.condition.trim() : void 0;
|
|
268
|
+
return { url, line, ...column !== void 0 ? { column } : {}, ...condition !== void 0 ? { condition } : {} };
|
|
269
|
+
}
|
|
270
|
+
function capturepause(input) {
|
|
271
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, reason: input.reason, callframes: [...input.callframes], ...input.hitbreakpoint !== void 0 ? { hitbreakpoint: input.hitbreakpoint } : {}, ...input.domsnapshotid !== void 0 ? { domsnapshotid: input.domsnapshotid } : {}, at: input.at };
|
|
272
|
+
}
|
|
273
|
+
function stepmodeof(value) {
|
|
274
|
+
const modes = ["stepover", "stepinto", "stepout", "resume"];
|
|
275
|
+
return typeof value === "string" && modes.includes(value) ? value : void 0;
|
|
276
|
+
}
|
|
277
|
+
function watchexpressionof(value) {
|
|
278
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
279
|
+
const entry = value;
|
|
280
|
+
const expression = typeof entry.expression === "string" && entry.expression.trim() ? entry.expression.trim() : void 0;
|
|
281
|
+
if (expression === void 0) return void 0;
|
|
282
|
+
const scope = typeof entry.scope === "string" && entry.scope.trim() ? entry.scope.trim() : "topframe";
|
|
283
|
+
return { expression, scope };
|
|
284
|
+
}
|
|
285
|
+
function recordwatchvalue(expression, pauseid, value, at) {
|
|
286
|
+
return { ...expression, values: [...expression.values, { pauseid, value, at }] };
|
|
287
|
+
}
|
|
288
|
+
function overrideinputof(value) {
|
|
289
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
290
|
+
const entry = value;
|
|
291
|
+
const urlpattern = typeof entry.urlpattern === "string" && entry.urlpattern.trim() ? entry.urlpattern.trim() : void 0;
|
|
292
|
+
const source = typeof entry.source === "string" ? entry.source : void 0;
|
|
293
|
+
if (urlpattern === void 0 || source === void 0 || source.trim().length === 0) return void 0;
|
|
294
|
+
return { urlpattern, source };
|
|
295
|
+
}
|
|
296
|
+
function overridematches(urlpattern, url) {
|
|
297
|
+
const patternmatch = /^(https:\/\/[^/]+)(\/.*)?$/.exec(urlpattern);
|
|
298
|
+
const urlmatch = /^(https:\/\/[^/]+)(\/.*)?$/.exec(url);
|
|
299
|
+
if (!patternmatch || !urlmatch) return false;
|
|
300
|
+
if (patternmatch[1] !== urlmatch[1]) return false;
|
|
301
|
+
const patternpath = (patternmatch[2] ?? "/").split("/").filter((segment) => segment.length > 0);
|
|
302
|
+
const urlpath = (urlmatch[2] ?? "/").split("/").filter((segment) => segment.length > 0);
|
|
303
|
+
const walk = (patternindex, urlindex) => {
|
|
304
|
+
if (patternindex >= patternpath.length) return urlindex >= urlpath.length;
|
|
305
|
+
const segment = patternpath[patternindex];
|
|
306
|
+
if (segment === "**") return walk(patternindex + 1, urlindex) || urlindex < urlpath.length && walk(patternindex, urlindex + 1);
|
|
307
|
+
if (urlindex >= urlpath.length) return false;
|
|
308
|
+
if (segment !== "*" && segment !== urlpath[urlindex]) return false;
|
|
309
|
+
return walk(patternindex + 1, urlindex + 1);
|
|
310
|
+
};
|
|
311
|
+
return walk(0, 0);
|
|
312
|
+
}
|
|
313
|
+
function teardownplanof(value) {
|
|
314
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
315
|
+
const entry = value;
|
|
316
|
+
const revertsteps = Array.isArray(entry.revertsteps) ? entry.revertsteps.filter((step) => typeof step === "string" && step.trim().length > 0) : [];
|
|
317
|
+
const policy = entry.resumepolicy;
|
|
318
|
+
if (revertsteps.length === 0) return void 0;
|
|
319
|
+
if (policy !== void 0 && policy !== "resume" && policy !== "pause" && policy !== "ask") return void 0;
|
|
320
|
+
return { revertsteps, resumepolicy: policy ?? "ask" };
|
|
321
|
+
}
|
|
322
|
+
function teardowncdpsession(input) {
|
|
323
|
+
const revertedbreakpoints = input.breakpoints.filter((spec) => spec.revertedat === void 0).map((spec) => spec.id);
|
|
324
|
+
const revertedoverrides = input.overrides.filter((spec) => spec.revertedat === void 0).map((spec) => spec.id);
|
|
325
|
+
const resumepolicy = input.userdetached ? "pause" : input.plan?.resumepolicy ?? "ask";
|
|
326
|
+
return {
|
|
327
|
+
session: detachcdpsession(input.session, input.at, input.userdetached),
|
|
328
|
+
revertedbreakpoints,
|
|
329
|
+
revertedoverrides,
|
|
330
|
+
resumepolicy,
|
|
331
|
+
paused: input.userdetached || resumepolicy === "pause",
|
|
332
|
+
keepsalive: input.userdetached
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
199
336
|
// httpclient.ts
|
|
200
337
|
var httpkinds = ["fetchurl", "parsejson", "parsehtml", "callrest", "callgraphql"];
|
|
201
338
|
var redirectstatuses = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
@@ -784,6 +921,232 @@ function streamsummaries(raw) {
|
|
|
784
921
|
});
|
|
785
922
|
}
|
|
786
923
|
|
|
924
|
+
// profilers.ts
|
|
925
|
+
var profilerkinds = ["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "annotatetrace", "replaytrace", "capturesourcemaps"];
|
|
926
|
+
var flowmetricnames = ["navigation", "paint", "lcp", "fid", "interaction", "blocking"];
|
|
927
|
+
var tracecategories = ["navigation", "scripting", "rendering", "painting", "loading", "network"];
|
|
928
|
+
function attachtargetof(value) {
|
|
929
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
930
|
+
const entry = value;
|
|
931
|
+
const kinds = ["page", "iframe", "worker", "serviceworker"];
|
|
932
|
+
const kind = typeof entry.kind === "string" && kinds.includes(entry.kind) ? entry.kind : void 0;
|
|
933
|
+
const url = typeof entry.url === "string" && entry.url.trim() ? entry.url.trim() : void 0;
|
|
934
|
+
if (kind === void 0 || url === void 0) return void 0;
|
|
935
|
+
if (kind !== "page" && !/^https:\/\//.test(url)) return void 0;
|
|
936
|
+
return { kind, url };
|
|
937
|
+
}
|
|
938
|
+
function flowspecof(value) {
|
|
939
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
940
|
+
const entry = value;
|
|
941
|
+
const prefix = typeof entry.prefix === "string" && entry.prefix.trim() ? entry.prefix.trim() : void 0;
|
|
942
|
+
const steps = Array.isArray(entry.steps) ? entry.steps.filter((step) => typeof step === "string" && step.trim().length > 0) : [];
|
|
943
|
+
const metrics = Array.isArray(entry.metrics) ? entry.metrics.filter((metric) => typeof metric === "string" && flowmetricnames.includes(metric)) : [];
|
|
944
|
+
if (prefix === void 0 || steps.length === 0 || metrics.length === 0) return void 0;
|
|
945
|
+
return { prefix, steps, metrics };
|
|
946
|
+
}
|
|
947
|
+
function stepwindows(spec, marks) {
|
|
948
|
+
const windows = [];
|
|
949
|
+
for (const stepid of spec.steps) {
|
|
950
|
+
const start = marks.find((mark) => mark.type === "mark" && mark.name === `${spec.prefix}:${stepid}:start`);
|
|
951
|
+
const end = marks.find((mark) => mark.type === "mark" && mark.name === `${spec.prefix}:${stepid}:end`);
|
|
952
|
+
if (start === void 0 || end === void 0) continue;
|
|
953
|
+
windows.push({ stepid, start: start.start, end: Math.max(end.start, start.start) });
|
|
954
|
+
}
|
|
955
|
+
return windows;
|
|
956
|
+
}
|
|
957
|
+
function measure(input) {
|
|
958
|
+
const metrics = [];
|
|
959
|
+
const windows = stepwindows(input.spec, input.entries.filter((entry) => entry.type === "mark"));
|
|
960
|
+
const stepsof = (start, end) => windows.filter((window) => window.end >= start && window.start <= end).map((window) => window.stepid);
|
|
961
|
+
const push = (name, start, end, steps) => {
|
|
962
|
+
if (!input.spec.metrics.includes(name)) return;
|
|
963
|
+
metrics.push({ id: `${input.runid}-${input.stepid}-${name}-${metrics.length}`, runid: input.runid, stepid: input.stepid, name, start, end, duration: Math.max(0, end - start), steps, at: input.now });
|
|
964
|
+
};
|
|
965
|
+
const navigation = input.entries.find((entry) => entry.type === "navigation");
|
|
966
|
+
if (navigation !== void 0) push("navigation", navigation.start, navigation.start + navigation.duration, stepsof(navigation.start, navigation.start + navigation.duration));
|
|
967
|
+
for (const paint of input.entries.filter((entry) => entry.type === "paint")) {
|
|
968
|
+
if (!input.spec.metrics.includes("paint")) break;
|
|
969
|
+
push("paint", paint.start, paint.start + paint.duration, stepsof(paint.start, paint.start + paint.duration));
|
|
970
|
+
}
|
|
971
|
+
const lcps = input.entries.filter((entry) => entry.type === "largest-contentful-paint");
|
|
972
|
+
const lcp = lcps.length > 0 ? lcps.reduce((largest, entry) => entry.start > largest.start ? entry : largest) : void 0;
|
|
973
|
+
if (lcp !== void 0) push("lcp", lcp.start, lcp.start + lcp.duration, stepsof(lcp.start, lcp.start + lcp.duration));
|
|
974
|
+
const firstinput = input.entries.find((entry) => entry.type === "first-input");
|
|
975
|
+
if (firstinput !== void 0) push("fid", firstinput.start, firstinput.start + firstinput.duration, stepsof(firstinput.start, firstinput.start + firstinput.duration));
|
|
976
|
+
const interactions = input.entries.filter((entry) => entry.type === "event");
|
|
977
|
+
if (interactions.length > 0) {
|
|
978
|
+
const start = interactions.reduce((earliest, entry) => entry.start < earliest.start ? entry : earliest).start;
|
|
979
|
+
const end = interactions.reduce((latest, entry) => entry.start + entry.duration > latest ? entry.start + entry.duration : latest, start);
|
|
980
|
+
push("interaction", start, end, stepsof(start, end));
|
|
981
|
+
}
|
|
982
|
+
for (const window of windows) {
|
|
983
|
+
if (!input.spec.metrics.includes("blocking")) break;
|
|
984
|
+
const blocking = input.entries.filter((entry) => entry.type === "longtask" && entry.start >= window.start && entry.start <= window.end).reduce((total, entry) => total + Math.max(0, entry.duration - 50), 0);
|
|
985
|
+
metrics.push({ id: `${input.runid}-${input.stepid}-blocking-${window.stepid}`, runid: input.runid, stepid: input.stepid, name: "blocking", start: window.start, end: window.end, duration: blocking, steps: [window.stepid], at: input.now });
|
|
986
|
+
}
|
|
987
|
+
return metrics;
|
|
988
|
+
}
|
|
989
|
+
function heapintervalallowed(lastcapturedat, interval, now) {
|
|
990
|
+
if (interval === void 0 || lastcapturedat === void 0) return true;
|
|
991
|
+
return now - lastcapturedat >= interval;
|
|
992
|
+
}
|
|
993
|
+
function heapsnap(input) {
|
|
994
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, origin: input.origin, bytesize: input.usedbytes, nodecount: input.nodecount, capturedat: input.now };
|
|
995
|
+
}
|
|
996
|
+
function growsampleof(input) {
|
|
997
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, usedbytes: input.usedbytes, limitbytes: input.limitbytes, at: input.now };
|
|
998
|
+
}
|
|
999
|
+
function growthtrend(input) {
|
|
1000
|
+
const ordered = [...input.samples].sort((left, right) => left.at - right.at);
|
|
1001
|
+
const first = ordered[0];
|
|
1002
|
+
const last = ordered[ordered.length - 1];
|
|
1003
|
+
const computed = first !== void 0 && last !== void 0 && last.at > first.at ? (last.usedbytes - first.usedbytes) / (last.at - first.at) : 0;
|
|
1004
|
+
const flaggedsteps = [];
|
|
1005
|
+
for (let index = 1; index < ordered.length; index += 1) {
|
|
1006
|
+
const previous = ordered[index - 1];
|
|
1007
|
+
const current = ordered[index];
|
|
1008
|
+
if (previous === void 0 || current === void 0) continue;
|
|
1009
|
+
const growth = current.at > previous.at ? (current.usedbytes - previous.usedbytes) / (current.at - previous.at) : 0;
|
|
1010
|
+
if (growth > input.slope && !flaggedsteps.includes(current.stepid)) flaggedsteps.push(current.stepid);
|
|
1011
|
+
}
|
|
1012
|
+
return { runid: input.runid, slope: computed, samples: ordered.length, flaggedsteps, at: input.now };
|
|
1013
|
+
}
|
|
1014
|
+
function cpusnap(input) {
|
|
1015
|
+
const ranked = /* @__PURE__ */ new Map();
|
|
1016
|
+
for (const sample of input.samples) ranked.set(sample.name, (ranked.get(sample.name) ?? 0) + sample.time);
|
|
1017
|
+
const hotfunctions = [...ranked.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])).map((entry) => entry[0]);
|
|
1018
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, origin: input.origin, duration: input.duration, samplecount: input.samples.length, hotfunctions, at: input.now };
|
|
1019
|
+
}
|
|
1020
|
+
function shiftentryof(value) {
|
|
1021
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1022
|
+
const entry = value;
|
|
1023
|
+
const score = typeof entry.score === "number" && Number.isFinite(entry.score) && entry.score >= 0 ? entry.score : void 0;
|
|
1024
|
+
const starttime = typeof entry.starttime === "number" && Number.isFinite(entry.starttime) ? entry.starttime : void 0;
|
|
1025
|
+
if (score === void 0 || starttime === void 0) return void 0;
|
|
1026
|
+
const selectors = Array.isArray(entry.selectors) ? entry.selectors.filter((selector) => typeof selector === "string" && selector.trim().length > 0) : [];
|
|
1027
|
+
return { id: typeof entry.id === "string" ? entry.id : "", runid: typeof entry.runid === "string" ? entry.runid : "", stepid: typeof entry.stepid === "string" ? entry.stepid : "", score, starttime, selectors, at: typeof entry.at === "number" ? entry.at : starttime };
|
|
1028
|
+
}
|
|
1029
|
+
function tracestart(input) {
|
|
1030
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, origin: input.origin, categories: [...new Set(input.categories)], bytesize: 0, events: 0, annotations: [], startedat: input.now, endedat: input.now };
|
|
1031
|
+
}
|
|
1032
|
+
function tracetofile(trace, events) {
|
|
1033
|
+
const payload = { devthinktrace: "1.1.47", runid: trace.runid, origin: trace.origin, categories: trace.categories, startedat: trace.startedat, endedat: trace.endedat, annotations: trace.annotations, traceevents: events.map((event) => ({ name: event.name, cat: event.category, offset: event.offset })) };
|
|
1034
|
+
const content = JSON.stringify(payload);
|
|
1035
|
+
return { content, bytesize: content.length, events: events.length };
|
|
1036
|
+
}
|
|
1037
|
+
function annotationof(value) {
|
|
1038
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1039
|
+
const entry = value;
|
|
1040
|
+
const stepid = typeof entry.stepid === "string" && entry.stepid.trim() ? entry.stepid.trim() : void 0;
|
|
1041
|
+
const label = typeof entry.label === "string" && entry.label.trim() ? entry.label.trim() : void 0;
|
|
1042
|
+
if (stepid === void 0 || label === void 0) return void 0;
|
|
1043
|
+
const offset = typeof entry.offset === "number" && Number.isFinite(entry.offset) && entry.offset >= 0 ? entry.offset : 0;
|
|
1044
|
+
return { stepid, label, offset };
|
|
1045
|
+
}
|
|
1046
|
+
function annotatetrace(input) {
|
|
1047
|
+
const aligned = input.annotations.map((annotation) => {
|
|
1048
|
+
const entry = input.timeline.find((item) => item.stepid === annotation.stepid);
|
|
1049
|
+
if (entry === void 0) return annotation;
|
|
1050
|
+
return { ...annotation, offset: Math.max(0, entry.time - input.trace.startedat) };
|
|
1051
|
+
});
|
|
1052
|
+
return { ...input.trace, annotations: aligned, endedat: Math.max(input.trace.endedat, input.now) };
|
|
1053
|
+
}
|
|
1054
|
+
function replaytrace(content) {
|
|
1055
|
+
let parsed;
|
|
1056
|
+
try {
|
|
1057
|
+
parsed = JSON.parse(content);
|
|
1058
|
+
} catch {
|
|
1059
|
+
throw new Error("The trace file is not valid json.");
|
|
1060
|
+
}
|
|
1061
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("The trace file is not a json object.");
|
|
1062
|
+
const record2 = parsed;
|
|
1063
|
+
const runid = typeof record2.runid === "string" ? record2.runid : "";
|
|
1064
|
+
const annotations = Array.isArray(record2.annotations) ? record2.annotations.flatMap((item) => {
|
|
1065
|
+
const annotation = annotationof(item);
|
|
1066
|
+
return annotation !== void 0 ? [annotation] : [];
|
|
1067
|
+
}) : [];
|
|
1068
|
+
const rawevents = Array.isArray(record2.traceevents) ? record2.traceevents : [];
|
|
1069
|
+
const categories = {};
|
|
1070
|
+
const events = rawevents.flatMap((item) => {
|
|
1071
|
+
if (!item || typeof item !== "object") return [];
|
|
1072
|
+
const entry = item;
|
|
1073
|
+
if (typeof entry.name !== "string" || typeof entry.cat !== "string" || typeof entry.offset !== "number") return [];
|
|
1074
|
+
const offset = entry.offset;
|
|
1075
|
+
categories[entry.cat] = (categories[entry.cat] ?? 0) + 1;
|
|
1076
|
+
const annotation = annotations.find((candidate) => Math.abs(candidate.offset - offset) < 1);
|
|
1077
|
+
return [{ name: entry.name, category: entry.cat, offset, ...annotation !== void 0 ? { stepid: annotation.stepid } : {} }];
|
|
1078
|
+
});
|
|
1079
|
+
return { traceid: typeof record2.id === "string" ? record2.id : "", runid, categories, events, annotations };
|
|
1080
|
+
}
|
|
1081
|
+
function mapurlof(scripturl, source) {
|
|
1082
|
+
const match = /[#@]\s*sourceMappingURL=(\S+)/.exec(source);
|
|
1083
|
+
if (match === null || match[1] === void 0) return void 0;
|
|
1084
|
+
try {
|
|
1085
|
+
return new URL(match[1], scripturl).toString();
|
|
1086
|
+
} catch {
|
|
1087
|
+
return void 0;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
function capturesourcemaps(input) {
|
|
1091
|
+
return input.scripts.flatMap((script) => {
|
|
1092
|
+
const mapurl = mapurlof(script.url, script.source);
|
|
1093
|
+
if (mapurl === void 0) return [];
|
|
1094
|
+
return [{ id: `${input.runid}-${script.url}`, runid: input.runid, stepid: input.stepid, origin: input.origin, scripturl: script.url, mapurl, parsed: false, at: input.now }];
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
function decodevlq(segment) {
|
|
1098
|
+
const values = [];
|
|
1099
|
+
let shift = 0;
|
|
1100
|
+
let value = 0;
|
|
1101
|
+
for (const character of segment) {
|
|
1102
|
+
const digit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(character);
|
|
1103
|
+
if (digit < 0) return void 0;
|
|
1104
|
+
value += (digit & 31) << shift;
|
|
1105
|
+
shift += 5;
|
|
1106
|
+
if ((digit & 32) === 0) {
|
|
1107
|
+
const negative = (value & 1) === 1;
|
|
1108
|
+
values.push(negative ? -(value >>> 1) : value >>> 1);
|
|
1109
|
+
value = 0;
|
|
1110
|
+
shift = 0;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
return values.length > 0 ? values : void 0;
|
|
1114
|
+
}
|
|
1115
|
+
function rewritesourcelocation(input, map) {
|
|
1116
|
+
const sources = Array.isArray(map.sources) ? map.sources.filter((source2) => typeof source2 === "string") : [];
|
|
1117
|
+
if (sources.length === 0 || typeof map.mappings !== "string" || map.mappings.length === 0) return void 0;
|
|
1118
|
+
const lines = map.mappings.split(";");
|
|
1119
|
+
if (input.line >= lines.length) return void 0;
|
|
1120
|
+
let sourceindex = 0;
|
|
1121
|
+
let sourceline = 0;
|
|
1122
|
+
for (let line = 0; line <= input.line; line += 1) {
|
|
1123
|
+
const linemappings = lines[line];
|
|
1124
|
+
if (linemappings === void 0) continue;
|
|
1125
|
+
const first = linemappings.split(",")[0] ?? "";
|
|
1126
|
+
if (first.length === 0) continue;
|
|
1127
|
+
const values = decodevlq(first);
|
|
1128
|
+
if (values === void 0 || values.length < 4) continue;
|
|
1129
|
+
sourceindex = Math.max(0, sourceindex + (values[1] ?? 0));
|
|
1130
|
+
sourceline = Math.max(0, sourceline + (values[2] ?? 0));
|
|
1131
|
+
}
|
|
1132
|
+
const targetmappings = lines[input.line];
|
|
1133
|
+
const target = targetmappings !== void 0 ? targetmappings.split(",")[0] ?? "" : "";
|
|
1134
|
+
if (target.length === 0) return void 0;
|
|
1135
|
+
const source = sources[Math.min(sources.length - 1, sourceindex)];
|
|
1136
|
+
if (source === void 0) return void 0;
|
|
1137
|
+
return { url: source, line: sourceline };
|
|
1138
|
+
}
|
|
1139
|
+
function expireprofilerecords(input) {
|
|
1140
|
+
const retention = input.retention;
|
|
1141
|
+
if (retention === void 0) return { heaps: input.heaps, profiles: input.profiles, traces: input.traces };
|
|
1142
|
+
const expired = (at) => input.now - at > retention;
|
|
1143
|
+
return {
|
|
1144
|
+
heaps: input.heaps.map((heap) => expired(heap.capturedat) && heap.bytesexpired !== true ? { ...heap, bytesexpired: true } : heap),
|
|
1145
|
+
profiles: input.profiles.map((profile) => expired(profile.at) && profile.samplesexpired !== true ? { ...profile, samplesexpired: true } : profile),
|
|
1146
|
+
traces: input.traces.map((trace) => expired(trace.endedat) && trace.bytesexpired !== true ? { ...trace, bytesexpired: true } : trace)
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
|
|
787
1150
|
// memory.ts
|
|
788
1151
|
var sessionmemory = class {
|
|
789
1152
|
constructor(adapter) {
|
|
@@ -1912,6 +2275,108 @@ var sessionmemory = class {
|
|
|
1912
2275
|
async getconsoleconsents() {
|
|
1913
2276
|
return await this.adapter.get("consoleconsents") ?? [];
|
|
1914
2277
|
}
|
|
2278
|
+
/** Stores one devtools session record with its enabled domains and detach state, replacing the previous record of its id. */
|
|
2279
|
+
async setcdpsession(session) {
|
|
2280
|
+
const records = (await this.adapter.get("cdpsessions") ?? []).filter((item) => item.id !== session.id);
|
|
2281
|
+
await this.adapter.set("cdpsessions", [session, ...records]);
|
|
2282
|
+
}
|
|
2283
|
+
/** Returns every stored devtools session record, newest first. */
|
|
2284
|
+
async getcdpsessions() {
|
|
2285
|
+
return await this.adapter.get("cdpsessions") ?? [];
|
|
2286
|
+
}
|
|
2287
|
+
/** Stores one raw command outcome with its duration and error class. */
|
|
2288
|
+
async addcdpcommand(command) {
|
|
2289
|
+
const records = await this.adapter.get("cdpcommands") ?? [];
|
|
2290
|
+
await this.adapter.set("cdpcommands", [command, ...records]);
|
|
2291
|
+
}
|
|
2292
|
+
/** Returns every stored raw command outcome, newest first. */
|
|
2293
|
+
async getcdpcommands() {
|
|
2294
|
+
return await this.adapter.get("cdpcommands") ?? [];
|
|
2295
|
+
}
|
|
2296
|
+
/** Stores one domain event rule with its match filter, replacing the previous rule of its id. */
|
|
2297
|
+
async setcdpeventrule(rule) {
|
|
2298
|
+
const records = (await this.adapter.get("cdpeventrules") ?? []).filter((item) => item.id !== rule.id);
|
|
2299
|
+
await this.adapter.set("cdpeventrules", [rule, ...records]);
|
|
2300
|
+
}
|
|
2301
|
+
/** Returns every stored domain event rule, newest first. */
|
|
2302
|
+
async getcdpeventrules() {
|
|
2303
|
+
return await this.adapter.get("cdpeventrules") ?? [];
|
|
2304
|
+
}
|
|
2305
|
+
/** Stores one breakpoint record with its condition and hit counter, replacing the previous record of its id. */
|
|
2306
|
+
async addbreakpoint(spec) {
|
|
2307
|
+
const records = (await this.adapter.get("breakpoints") ?? []).filter((item) => item.id !== spec.id);
|
|
2308
|
+
await this.adapter.set("breakpoints", [spec, ...records]);
|
|
2309
|
+
}
|
|
2310
|
+
/** Returns every stored breakpoint record, newest first. */
|
|
2311
|
+
async getbreakpoints() {
|
|
2312
|
+
return await this.adapter.get("breakpoints") ?? [];
|
|
2313
|
+
}
|
|
2314
|
+
/** Stores one pause state capture; the user configured pause retention window expires the call frames and the dom snapshot reference of the oldest captures while the pause reason and hit breakpoint survive. */
|
|
2315
|
+
async addpause(pause) {
|
|
2316
|
+
const records = await this.getpauses();
|
|
2317
|
+
const combined = [pause, ...records.filter((item) => item.id !== pause.id)];
|
|
2318
|
+
const retention = (await this.getsettings())?.pauseretention;
|
|
2319
|
+
if (retention === void 0) {
|
|
2320
|
+
await this.adapter.set("pauses", combined);
|
|
2321
|
+
return;
|
|
2322
|
+
}
|
|
2323
|
+
const kept = combined.slice(0, retention);
|
|
2324
|
+
const expired = combined.slice(retention).map((item) => {
|
|
2325
|
+
if (item.framesexpired === true) return item;
|
|
2326
|
+
const faded = { ...item, callframes: [], framesexpired: true };
|
|
2327
|
+
delete faded.domsnapshotid;
|
|
2328
|
+
return faded;
|
|
2329
|
+
});
|
|
2330
|
+
await this.adapter.set("pauses", [...kept, ...expired]);
|
|
2331
|
+
}
|
|
2332
|
+
/** Returns every stored pause state capture, newest first. */
|
|
2333
|
+
async getpauses() {
|
|
2334
|
+
return await this.adapter.get("pauses") ?? [];
|
|
2335
|
+
}
|
|
2336
|
+
/** Returns the pause state captures of one run, newest first. */
|
|
2337
|
+
async listpauses(runid) {
|
|
2338
|
+
const records = await this.getpauses();
|
|
2339
|
+
return records.filter((item) => item.runid === runid);
|
|
2340
|
+
}
|
|
2341
|
+
/** Stores one watch expression with its per pause values, replacing the previous expression of its id. */
|
|
2342
|
+
async setwatchexpression(expression) {
|
|
2343
|
+
const records = (await this.adapter.get("watchexpressions") ?? []).filter((item) => item.id !== expression.id);
|
|
2344
|
+
await this.adapter.set("watchexpressions", [expression, ...records]);
|
|
2345
|
+
}
|
|
2346
|
+
/** Returns every stored watch expression, newest first. */
|
|
2347
|
+
async getwatchexpressions() {
|
|
2348
|
+
return await this.adapter.get("watchexpressions") ?? [];
|
|
2349
|
+
}
|
|
2350
|
+
/** Stores one script override with its review provenance, replacing the previous override of its id. */
|
|
2351
|
+
async addscriptoverride(spec) {
|
|
2352
|
+
const records = (await this.adapter.get("scriptoverrides") ?? []).filter((item) => item.id !== spec.id);
|
|
2353
|
+
await this.adapter.set("scriptoverrides", [spec, ...records]);
|
|
2354
|
+
}
|
|
2355
|
+
/** Returns every stored script override, newest first. */
|
|
2356
|
+
async getscriptoverrides() {
|
|
2357
|
+
return await this.adapter.get("scriptoverrides") ?? [];
|
|
2358
|
+
}
|
|
2359
|
+
/** Stores one debugger consent decision per origin with the consented domain list, replacing the previous decision of its id. */
|
|
2360
|
+
async setdebuggergrant(grant) {
|
|
2361
|
+
const records = (await this.adapter.get("debuggergrants") ?? []).filter((item) => item.id !== grant.id);
|
|
2362
|
+
await this.adapter.set("debuggergrants", [grant, ...records]);
|
|
2363
|
+
}
|
|
2364
|
+
/** Returns every debugger consent decision, newest first. */
|
|
2365
|
+
async getdebuggergrants() {
|
|
2366
|
+
return await this.adapter.get("debuggergrants") ?? [];
|
|
2367
|
+
}
|
|
2368
|
+
/** Revokes every approved debugger consent of one origin: the revoke time stamps the records so the next attach needs a new reviewed prompt. */
|
|
2369
|
+
async revokedebuggergrants(origin, at) {
|
|
2370
|
+
const records = await this.getdebuggergrants();
|
|
2371
|
+
let revoked = 0;
|
|
2372
|
+
const updated = records.map((grant) => {
|
|
2373
|
+
if (grant.origin !== origin || grant.revokedat !== void 0) return grant;
|
|
2374
|
+
revoked += 1;
|
|
2375
|
+
return { ...grant, revokedat: at };
|
|
2376
|
+
});
|
|
2377
|
+
await this.adapter.set("debuggergrants", updated);
|
|
2378
|
+
return revoked;
|
|
2379
|
+
}
|
|
1915
2380
|
/** Merges expired entry counts into the per run level count summary that survives the retention window. */
|
|
1916
2381
|
async mergelevelsummary(runid, counts, now) {
|
|
1917
2382
|
const records = await this.getlevelsummaries();
|
|
@@ -1925,6 +2390,133 @@ var sessionmemory = class {
|
|
|
1925
2390
|
async getlevelsummaries() {
|
|
1926
2391
|
return await this.adapter.get("levelsummaries") ?? [];
|
|
1927
2392
|
}
|
|
2393
|
+
/** Stores one measured flow metric of the run beside its step span; the flow series stays per run. */
|
|
2394
|
+
async addflowmetric(metric) {
|
|
2395
|
+
const records = await this.getflowmetrics();
|
|
2396
|
+
await this.adapter.set("flowmetrics", [metric, ...records]);
|
|
2397
|
+
}
|
|
2398
|
+
/** Returns every stored flow metric, newest first. */
|
|
2399
|
+
async getflowmetrics() {
|
|
2400
|
+
return await this.adapter.get("flowmetrics") ?? [];
|
|
2401
|
+
}
|
|
2402
|
+
/** Returns the flow metrics of one run, newest first. */
|
|
2403
|
+
async listflowmetrics(runid) {
|
|
2404
|
+
const records = await this.getflowmetrics();
|
|
2405
|
+
return records.filter((metric) => metric.runid === runid);
|
|
2406
|
+
}
|
|
2407
|
+
/** Stores one heap snapshot record with its byte and node counts; the user configured profile retention window expires the heavy snapshot bytes while the counts survive. */
|
|
2408
|
+
async setheaprecord(heap) {
|
|
2409
|
+
const records = (await this.adapter.get("heaprecords") ?? []).filter((item) => item.id !== heap.id);
|
|
2410
|
+
const retention = (await this.getsettings())?.profileretention;
|
|
2411
|
+
const { heaps } = expireprofilerecords({ heaps: [heap, ...records], profiles: [], traces: [], retention, now: Date.now() });
|
|
2412
|
+
await this.adapter.set("heaprecords", heaps);
|
|
2413
|
+
}
|
|
2414
|
+
/** Returns every stored heap snapshot record, newest first. */
|
|
2415
|
+
async getheaprecords() {
|
|
2416
|
+
return await this.adapter.get("heaprecords") ?? [];
|
|
2417
|
+
}
|
|
2418
|
+
/** Stores one heap growth sample taken beside a step. */
|
|
2419
|
+
async addgrowsample(sample) {
|
|
2420
|
+
const records = await this.adapter.get("growsamples") ?? [];
|
|
2421
|
+
await this.adapter.set("growsamples", [sample, ...records]);
|
|
2422
|
+
}
|
|
2423
|
+
/** Returns every stored heap growth sample, newest first. */
|
|
2424
|
+
async getgrowsamples() {
|
|
2425
|
+
return await this.adapter.get("growsamples") ?? [];
|
|
2426
|
+
}
|
|
2427
|
+
/** Returns the heap growth samples of one run, newest first. */
|
|
2428
|
+
async listgrowsamples(runid) {
|
|
2429
|
+
const records = await this.getgrowsamples();
|
|
2430
|
+
return records.filter((sample) => sample.runid === runid);
|
|
2431
|
+
}
|
|
2432
|
+
/** Stores one computed heap growth trend of a run with its slope and flagged steps, replacing the previous trend of the run. */
|
|
2433
|
+
async settrend(trend) {
|
|
2434
|
+
const records = await this.adapter.get("memorytrends") ?? [];
|
|
2435
|
+
await this.adapter.set("memorytrends", [trend, ...records.filter((item) => item.runid !== trend.runid)]);
|
|
2436
|
+
}
|
|
2437
|
+
/** Returns every stored heap growth trend, newest first. */
|
|
2438
|
+
async gettrends() {
|
|
2439
|
+
return await this.adapter.get("memorytrends") ?? [];
|
|
2440
|
+
}
|
|
2441
|
+
/** Stores one cpu profile record with its sample count and hot function list; the profile retention window expires the heavy sample payload while the counts and hot functions survive. */
|
|
2442
|
+
async setcpuprofile(profile) {
|
|
2443
|
+
const records = (await this.adapter.get("cpuprofiles") ?? []).filter((item) => item.id !== profile.id);
|
|
2444
|
+
const retention = (await this.getsettings())?.profileretention;
|
|
2445
|
+
const { profiles } = expireprofilerecords({ heaps: [], profiles: [profile, ...records], traces: [], retention, now: Date.now() });
|
|
2446
|
+
await this.adapter.set("cpuprofiles", profiles);
|
|
2447
|
+
}
|
|
2448
|
+
/** Returns every stored cpu profile record, newest first. */
|
|
2449
|
+
async getcpuprofiles() {
|
|
2450
|
+
return await this.adapter.get("cpuprofiles") ?? [];
|
|
2451
|
+
}
|
|
2452
|
+
/** Stores one layout shift entry with its score and impacted selectors. */
|
|
2453
|
+
async addshiftentry(entry) {
|
|
2454
|
+
const records = await this.adapter.get("shiftentries") ?? [];
|
|
2455
|
+
await this.adapter.set("shiftentries", [entry, ...records]);
|
|
2456
|
+
}
|
|
2457
|
+
/** Returns every stored layout shift entry, newest first. */
|
|
2458
|
+
async getshiftentries() {
|
|
2459
|
+
return await this.adapter.get("shiftentries") ?? [];
|
|
2460
|
+
}
|
|
2461
|
+
/** Stores one trace record with its category list, byte size and step annotations; the profile retention window expires the heavy trace bytes while the metadata and annotations survive. */
|
|
2462
|
+
async settracerecord(trace) {
|
|
2463
|
+
const records = (await this.adapter.get("tracerecords") ?? []).filter((item) => item.id !== trace.id);
|
|
2464
|
+
const retention = (await this.getsettings())?.profileretention;
|
|
2465
|
+
const { traces } = expireprofilerecords({ heaps: [], profiles: [], traces: [trace, ...records], retention, now: Date.now() });
|
|
2466
|
+
await this.adapter.set("tracerecords", traces);
|
|
2467
|
+
}
|
|
2468
|
+
/** Returns every stored trace record, newest first. */
|
|
2469
|
+
async gettracerecords() {
|
|
2470
|
+
return await this.adapter.get("tracerecords") ?? [];
|
|
2471
|
+
}
|
|
2472
|
+
/** Returns the trace records filtered by run and applied categories. */
|
|
2473
|
+
async listtraces(filter) {
|
|
2474
|
+
const records = await this.gettracerecords();
|
|
2475
|
+
return records.filter((trace) => (filter.runid === void 0 || trace.runid === filter.runid) && (filter.categories === void 0 || filter.categories.every((category) => trace.categories.includes(category))));
|
|
2476
|
+
}
|
|
2477
|
+
/** Stores the exported file content of one trace beside its record; the retention window drops the file bytes of expired traces while the record survives. */
|
|
2478
|
+
async settracefile(traceid, content) {
|
|
2479
|
+
const records = (await this.adapter.get("tracefiles") ?? []).filter((item) => item.traceid !== traceid);
|
|
2480
|
+
const trace = (await this.gettracerecords()).find((item) => item.id === traceid);
|
|
2481
|
+
const retention = (await this.getsettings())?.profileretention;
|
|
2482
|
+
const kept = retention === void 0 || trace === void 0 || Date.now() - trace.endedat <= retention ? [{ traceid, content, savedat: Date.now() }, ...records] : records;
|
|
2483
|
+
await this.adapter.set("tracefiles", kept);
|
|
2484
|
+
}
|
|
2485
|
+
/** Returns the exported file content of one trace, or undefined when the retention window dropped the bytes. */
|
|
2486
|
+
async gettracefile(traceid) {
|
|
2487
|
+
const records = await this.adapter.get("tracefiles") ?? [];
|
|
2488
|
+
return records.find((item) => item.traceid === traceid)?.content;
|
|
2489
|
+
}
|
|
2490
|
+
/** Stores one source map reference of a run with its script url, map url and parsed state. */
|
|
2491
|
+
async setsourcemapref(ref) {
|
|
2492
|
+
const records = (await this.adapter.get("sourcemaprefs") ?? []).filter((item) => item.id !== ref.id);
|
|
2493
|
+
await this.adapter.set("sourcemaprefs", [ref, ...records]);
|
|
2494
|
+
}
|
|
2495
|
+
/** Returns every stored source map reference, newest first. */
|
|
2496
|
+
async getsourcemaps() {
|
|
2497
|
+
return await this.adapter.get("sourcemaprefs") ?? [];
|
|
2498
|
+
}
|
|
2499
|
+
/** Stores one source map capture consent decision per origin, replacing the previous decision of its id. */
|
|
2500
|
+
async setsourcemapconsent(consent) {
|
|
2501
|
+
const records = (await this.adapter.get("sourcemapconsents") ?? []).filter((item) => item.id !== consent.id);
|
|
2502
|
+
await this.adapter.set("sourcemapconsents", [consent, ...records]);
|
|
2503
|
+
}
|
|
2504
|
+
/** Returns every source map capture consent decision, newest first. */
|
|
2505
|
+
async getsourcemapconsents() {
|
|
2506
|
+
return await this.adapter.get("sourcemapconsents") ?? [];
|
|
2507
|
+
}
|
|
2508
|
+
/** Revokes every approved source map consent of one origin so the next capture needs a new reviewed prompt. */
|
|
2509
|
+
async revokesourcemapconsents(origin, at) {
|
|
2510
|
+
const records = await this.getsourcemapconsents();
|
|
2511
|
+
let revoked = 0;
|
|
2512
|
+
const updated = records.map((consent) => {
|
|
2513
|
+
if (consent.origin !== origin || consent.revokedat !== void 0) return consent;
|
|
2514
|
+
revoked += 1;
|
|
2515
|
+
return { ...consent, revokedat: at };
|
|
2516
|
+
});
|
|
2517
|
+
await this.adapter.set("sourcemapconsents", updated);
|
|
2518
|
+
return revoked;
|
|
2519
|
+
}
|
|
1928
2520
|
};
|
|
1929
2521
|
function mediakindof(record2) {
|
|
1930
2522
|
if ("pages" in record2) return "pdf";
|
|
@@ -2464,7 +3056,7 @@ function extractvalues(body, paths) {
|
|
|
2464
3056
|
// runtimeline.ts
|
|
2465
3057
|
var timelinekinds = ["watchconsole", "watcherrors", "watchtasks"];
|
|
2466
3058
|
var loglevels = ["error", "warn", "info", "log", "debug", "trace"];
|
|
2467
|
-
var timelinesources = ["console", "error", "rejection", "resource", "longtask", "network"];
|
|
3059
|
+
var timelinesources = ["console", "error", "rejection", "resource", "longtask", "network", "cdp"];
|
|
2468
3060
|
function levelrank(level) {
|
|
2469
3061
|
return loglevels.indexOf(level);
|
|
2470
3062
|
}
|
|
@@ -2871,9 +3463,9 @@ function polldecision(input) {
|
|
|
2871
3463
|
}
|
|
2872
3464
|
|
|
2873
3465
|
// policy.ts
|
|
2874
|
-
var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles"]);
|
|
2875
|
-
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction", "capturebodies"]);
|
|
2876
|
-
var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks"]);
|
|
3466
|
+
var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps"]);
|
|
3467
|
+
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction", "capturebodies", "setbreakpoint", "stepcode", "watchexpr"]);
|
|
3468
|
+
var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace"]);
|
|
2877
3469
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
2878
3470
|
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
|
|
2879
3471
|
var targetactions = /* @__PURE__ */ new Set(["inspect", "focus", "click", "type", "scroll", "select", "hover", "clickdeep", "rightclick", "doubleclick", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "highlight", "setattribute", "removeattribute", "waitfor", "shiftclick", "typetime", "appendtext", "setvalue", "typeedit", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "expanddetails", "verifyvisible", "verifyenabled", "pierceshadow", "deriveselector", "fingerprintsection", "submitform", "retryform", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "scrapetable", "paginateextract", "shotelement", "captureframe", "shotcanvas"]);
|
|
@@ -2890,6 +3482,8 @@ var socketactions = /* @__PURE__ */ new Set(["opensocket", "sendmessage", "waitm
|
|
|
2890
3482
|
var netwatchactions = /* @__PURE__ */ new Set(["watchrequests", "readheaders", "capturebodies", "mapapi", "extractapi"]);
|
|
2891
3483
|
var controlactions = /* @__PURE__ */ new Set(["blockrequest", "mockresponse", "rewriteheaders", "setcookies", "readcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles"]);
|
|
2892
3484
|
var debugactions = /* @__PURE__ */ new Set(["watchconsole", "watcherrors", "watchtasks"]);
|
|
3485
|
+
var cdpactions = /* @__PURE__ */ new Set(["attachcdp", "detachcdp", "cdpcmd", "watchcdp", "setbreakpoint", "stepcode", "watchexpr", "overridescript"]);
|
|
3486
|
+
var profileractions = /* @__PURE__ */ new Set(["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "annotatetrace", "replaytrace", "capturesourcemaps"]);
|
|
2893
3487
|
var credentialheaders = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2", "set-cookie", "api-key", "x-api-key", "x-auth-token", "x-session-token", "proxy-authorization"]);
|
|
2894
3488
|
var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
|
|
2895
3489
|
var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
|
|
@@ -2911,8 +3505,14 @@ function iswatchkind(kind) {
|
|
|
2911
3505
|
function isdebugkind(kind) {
|
|
2912
3506
|
return debugactions.has(kind);
|
|
2913
3507
|
}
|
|
3508
|
+
function iscdpkind(kind) {
|
|
3509
|
+
return cdpactions.has(kind);
|
|
3510
|
+
}
|
|
3511
|
+
function isprofilekind(kind) {
|
|
3512
|
+
return profileractions.has(kind);
|
|
3513
|
+
}
|
|
2914
3514
|
function observationmodeof(kind) {
|
|
2915
|
-
if (watchactions.has(kind) || debugactions.has(kind) || kind === "waitquiet") return "watching";
|
|
3515
|
+
if (watchactions.has(kind) || debugactions.has(kind) || profileractions.has(kind) && kind !== "heapshot" && kind !== "replaytrace" && kind !== "annotatetrace" && kind !== "capturesourcemaps" && kind !== "profilecpu" || cdpactions.has(kind) && kind === "watchcdp" || kind === "waitquiet") return "watching";
|
|
2916
3516
|
if (kind === "diffsnapshots") return "diffing";
|
|
2917
3517
|
return "passive";
|
|
2918
3518
|
}
|
|
@@ -4126,6 +4726,215 @@ function rotationruleof(value) {
|
|
|
4126
4726
|
if (maxentries === void 0 || overflowtarget === void 0) return void 0;
|
|
4127
4727
|
return { maxentries, overflowtarget };
|
|
4128
4728
|
}
|
|
4729
|
+
function debuggate(session, tabid, origin, now) {
|
|
4730
|
+
if (!session || session.stoppedat) return { allowed: false, reason: "No active browser session exists for the devtools protocol step." };
|
|
4731
|
+
if (session.expiresat <= now) return { allowed: false, reason: "The browser session has expired and cannot run a devtools protocol step." };
|
|
4732
|
+
if (session.pausedat) return { allowed: false, reason: "The browser session is paused and cannot run a devtools protocol step." };
|
|
4733
|
+
if (session.tabid !== tabid) return { allowed: false, reason: `The devtools protocol step needs the run tab ${session.tabid} and refuses tab ${tabid}.` };
|
|
4734
|
+
if (!origingranted(session, origin)) return { allowed: false, reason: `The devtools protocol step on ${origin} needs the session origin grants first.` };
|
|
4735
|
+
return { allowed: true };
|
|
4736
|
+
}
|
|
4737
|
+
function debuggerconsentcovers(origin, domains, grants) {
|
|
4738
|
+
const needed = [...new Set(domains)];
|
|
4739
|
+
const covering = grants.find((grant) => grant.origin === origin && grant.approved === true && grant.revokedat === void 0 && needed.every((domain) => grant.domains.includes(domain)));
|
|
4740
|
+
if (covering) return { allowed: true };
|
|
4741
|
+
if (grants.some((grant) => grant.origin === origin && grant.revokedat !== void 0)) return { allowed: false, reason: `The debugger consent on ${origin} was revoked; approve a new prompt before the devtools protocol runs again.` };
|
|
4742
|
+
return { allowed: false, reason: `The devtools protocol on ${origin} needs the reviewed debugger consent for ${needed.join(", ")} first; approve the prompt with the domain allowlist shown in the review panel.` };
|
|
4743
|
+
}
|
|
4744
|
+
function targetgate(input) {
|
|
4745
|
+
const base = debuggate(input.session, input.tabid, input.origin, input.now);
|
|
4746
|
+
if (!base.allowed) return base;
|
|
4747
|
+
for (const target of input.targets) {
|
|
4748
|
+
if (target.kind === "page") continue;
|
|
4749
|
+
const origincheckresult = origincheck(input.session, target.url);
|
|
4750
|
+
if (!origincheckresult.allowed) return { allowed: false, reason: `The ${target.kind} target ${target.url} stays outside the granted origins; profiling refuses to attach.` };
|
|
4751
|
+
}
|
|
4752
|
+
if (input.grants === void 0) return { allowed: true };
|
|
4753
|
+
const consent = debuggerconsentcovers(input.origin, [], input.grants);
|
|
4754
|
+
if (!consent.allowed) return { allowed: false, reason: `The profiling step on ${input.origin} needs the reviewed debugger grant of the origin first; approve the prompt with the profiling derivation shown in the review panel.` };
|
|
4755
|
+
return { allowed: true };
|
|
4756
|
+
}
|
|
4757
|
+
function sourcemapconsentcovers(origin, consents) {
|
|
4758
|
+
const covering = consents.find((consent) => consent.origin === origin && consent.approved === true && consent.revokedat === void 0);
|
|
4759
|
+
if (covering) return { allowed: true };
|
|
4760
|
+
if (consents.some((consent) => consent.origin === origin && consent.revokedat !== void 0)) return { allowed: false, reason: `The source map capture consent on ${origin} was revoked; approve a new prompt before another map file is fetched.` };
|
|
4761
|
+
return { allowed: false, reason: `The source map capture on ${origin} needs the reviewed per origin consent first; approve the prompt shown in the review panel.` };
|
|
4762
|
+
}
|
|
4763
|
+
function profileretentionwindow(settings) {
|
|
4764
|
+
return settings?.profileretention;
|
|
4765
|
+
}
|
|
4766
|
+
function traceceilingof(settings) {
|
|
4767
|
+
return settings?.traceceiling;
|
|
4768
|
+
}
|
|
4769
|
+
function validatebreakpointcondition(condition) {
|
|
4770
|
+
const expression = condition.trim();
|
|
4771
|
+
if (expression.length === 0) return { allowed: false, reason: "The breakpoint condition must not be empty." };
|
|
4772
|
+
if (/(?<![=!<>])=(?!=)/.test(expression)) return { allowed: false, reason: "Breakpoint conditions refuse assignment because the reviewed grammar is comparison only." };
|
|
4773
|
+
if (/[A-Za-z_$][\w$]*\s*\(/.test(expression)) return { allowed: false, reason: "Breakpoint conditions refuse calls because the reviewed grammar is comparison only." };
|
|
4774
|
+
const literal = /^(?:-?\d+(?:\.\d+)?|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|true|false|null)$/;
|
|
4775
|
+
const tokens = expression.match(/(?:[A-Za-z_$][\w$]*|-?\d+(?:\.\d+)?|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|===|!==|==|!=|>=|<=|&&|\|\||[!.<>()+\-*\/%])/g);
|
|
4776
|
+
if (tokens === null || tokens.join("") !== expression.replace(/\s+/g, "")) return { allowed: false, reason: "The breakpoint condition must use the reviewed expression grammar of member chains, literals, comparisons, logic operators, negation and parentheses." };
|
|
4777
|
+
const identifierlike = /^(?:true|false|null)$/;
|
|
4778
|
+
for (const token of tokens) {
|
|
4779
|
+
if (literal.test(token) || identifierlike.test(token)) continue;
|
|
4780
|
+
if (["===", "!==", "==", "!=", ">=", "<=", "&&", "||", "!", ".", "(", ")", "<", ">", "+", "-", "*", "/", "%"].includes(token)) continue;
|
|
4781
|
+
if (/^[A-Za-z_$][\w$]*$/.test(token)) continue;
|
|
4782
|
+
return { allowed: false, reason: `The token ${token} of the breakpoint condition stays outside the reviewed expression grammar.` };
|
|
4783
|
+
}
|
|
4784
|
+
return { allowed: true };
|
|
4785
|
+
}
|
|
4786
|
+
function breakpointbudgetallowed(active, ceiling) {
|
|
4787
|
+
if (ceiling === void 0) return { allowed: true };
|
|
4788
|
+
if (typeof ceiling !== "number" || !Number.isInteger(ceiling) || ceiling < 0) return { allowed: false, reason: "The reviewed breakpoint ceiling must be zero or a positive integer of user configured value with no code ceiling." };
|
|
4789
|
+
if (active >= ceiling) return { allowed: false, reason: `The run already holds ${active} active breakpoint${active === 1 ? "" : "s"} and the reviewed breakpoint ceiling is ${ceiling}; revert one or review a wider ceiling.` };
|
|
4790
|
+
return { allowed: true };
|
|
4791
|
+
}
|
|
4792
|
+
function pauseretentionwindow(settings) {
|
|
4793
|
+
return settings?.pauseretention;
|
|
4794
|
+
}
|
|
4795
|
+
function breakpointceilingof(settings) {
|
|
4796
|
+
return settings?.breakpointceiling;
|
|
4797
|
+
}
|
|
4798
|
+
function validatecdpgrammar(step, options) {
|
|
4799
|
+
const kind = step.kind;
|
|
4800
|
+
if (kind === "attachcdp") {
|
|
4801
|
+
if (!Array.isArray(options.domains) || options.domains.length === 0 || !options.domains.every((domain) => typeof domain === "string" && cdpdomains.includes(domain))) return { allowed: false, reason: `The attach needs a non-empty enabled domain list of the reviewed domain grammar: ${cdpdomains.join(", ")}.` };
|
|
4802
|
+
if (teardownplanof(options.teardown) === void 0) return { allowed: false, reason: "Every attach needs a reviewed teardown plan with its revert steps and resume policy before approval." };
|
|
4803
|
+
if (options.allowlist !== void 0) {
|
|
4804
|
+
const allowlist = cdpallowlistof(options.allowlist);
|
|
4805
|
+
if (!allowlist || !allowlist.domains.every((domain) => options.domains.includes(domain))) return { allowed: false, reason: "The reviewed method allowlist must stay inside the enabled domains of the attach." };
|
|
4806
|
+
}
|
|
4807
|
+
const budgetcheck = debugwaitbudgetallowed(typeof options.wait === "number" ? options.wait : void 0, void 0);
|
|
4808
|
+
if (!budgetcheck.allowed) return budgetcheck;
|
|
4809
|
+
return { allowed: true };
|
|
4810
|
+
}
|
|
4811
|
+
if (kind === "detachcdp") return { allowed: true };
|
|
4812
|
+
if (kind === "cdpcmd") {
|
|
4813
|
+
const command = options.command && typeof options.command === "object" && !Array.isArray(options.command) ? options.command : void 0;
|
|
4814
|
+
if (!command || typeof command.method !== "string" || methoddomain(command.method) === void 0) return { allowed: false, reason: "The raw command needs a reviewed method of the Domain.method form." };
|
|
4815
|
+
if (command.params !== void 0 && (typeof command.params !== "object" || Array.isArray(command.params))) return { allowed: false, reason: "The raw command params must be a JSON object." };
|
|
4816
|
+
if (command.resultpath !== void 0 && typeof command.resultpath !== "string") return { allowed: false, reason: "The reviewed result path must be a dotted path string." };
|
|
4817
|
+
return { allowed: true };
|
|
4818
|
+
}
|
|
4819
|
+
if (kind === "watchcdp") {
|
|
4820
|
+
if (!Array.isArray(options.events) || options.events.length === 0 || !options.events.every((rule) => cdpeventruleof(rule) !== void 0)) return { allowed: false, reason: "The event watch needs a non-empty reviewed list of domain event rules of the reviewed domain grammar." };
|
|
4821
|
+
let watchwindow;
|
|
4822
|
+
if (options.watch !== void 0) {
|
|
4823
|
+
const watch = options.watch;
|
|
4824
|
+
if (!watch || typeof watch !== "object" || Array.isArray(watch)) return { allowed: false, reason: "The reviewed event watch window must be an object." };
|
|
4825
|
+
const reviewed = watch;
|
|
4826
|
+
if (reviewed.window !== void 0) {
|
|
4827
|
+
if (typeof reviewed.window !== "number" || !Number.isFinite(reviewed.window) || reviewed.window < 0) return { allowed: false, reason: "The reviewed event watch window must be zero or a positive number of milliseconds." };
|
|
4828
|
+
watchwindow = reviewed.window;
|
|
4829
|
+
}
|
|
4830
|
+
}
|
|
4831
|
+
if (watchwindow === void 0) return { allowed: false, reason: "The event watch needs a reviewed lifetime window before any domain event is observed." };
|
|
4832
|
+
const budgetcheck = debugwaitbudgetallowed(watchwindow, typeof options.wait === "number" ? options.wait : void 0);
|
|
4833
|
+
if (!budgetcheck.allowed) return budgetcheck;
|
|
4834
|
+
return { allowed: true };
|
|
4835
|
+
}
|
|
4836
|
+
if (kind === "setbreakpoint") {
|
|
4837
|
+
const breakpoint = breakpointinputof(options.breakpoint);
|
|
4838
|
+
if (!breakpoint) return { allowed: false, reason: "The breakpoint needs a reviewed script url and a zero based line." };
|
|
4839
|
+
if (!ishttpsurl(breakpoint.url)) return { allowed: false, reason: "The breakpoint script url must be a reviewed HTTPS url." };
|
|
4840
|
+
if (breakpoint.condition !== void 0) {
|
|
4841
|
+
const conditioncheck = validatebreakpointcondition(breakpoint.condition);
|
|
4842
|
+
if (!conditioncheck.allowed) return conditioncheck;
|
|
4843
|
+
}
|
|
4844
|
+
return { allowed: true };
|
|
4845
|
+
}
|
|
4846
|
+
if (kind === "stepcode") {
|
|
4847
|
+
if (stepmodeof(options.mode) === void 0) return { allowed: false, reason: "The step code mode must be one of stepover, stepinto, stepout or resume." };
|
|
4848
|
+
return { allowed: true };
|
|
4849
|
+
}
|
|
4850
|
+
if (kind === "watchexpr") {
|
|
4851
|
+
if (watchexpressionof(options.expression) === void 0) return { allowed: false, reason: "The watch expression needs the reviewed expression text." };
|
|
4852
|
+
if (options.reviewed !== true) return { allowed: false, reason: "Watch expressions must be reviewed before evaluation; set the explicit reviewed flag on the step." };
|
|
4853
|
+
return { allowed: true };
|
|
4854
|
+
}
|
|
4855
|
+
if (kind === "overridescript") {
|
|
4856
|
+
const override = overrideinputof(options.override);
|
|
4857
|
+
if (!override) return { allowed: false, reason: "The script override needs a reviewed url pattern and its full fixture source." };
|
|
4858
|
+
if (patternorigin(override.urlpattern) === void 0) return { allowed: false, reason: "Script overrides without a named https origin pattern are refused." };
|
|
4859
|
+
if (options.reviewed !== true) return { allowed: false, reason: "The full fixture source must be reviewed before the script override runs; set the explicit reviewed flag on the step." };
|
|
4860
|
+
return { allowed: true };
|
|
4861
|
+
}
|
|
4862
|
+
return { allowed: true };
|
|
4863
|
+
}
|
|
4864
|
+
function validateprofilegrammar(step, options) {
|
|
4865
|
+
const kind = step.kind;
|
|
4866
|
+
if (kind === "measureflow") {
|
|
4867
|
+
if (flowspecof(options.flow) === void 0) return { allowed: false, reason: `The flow measurement needs a reviewed flow spec with its mark prefix, step window and metric list of the reviewed metric set: navigation, paint, lcp, fid, interaction, blocking.` };
|
|
4868
|
+
const watch = options.watch && typeof options.watch === "object" && !Array.isArray(options.watch) ? options.watch : {};
|
|
4869
|
+
if (typeof watch.window !== "number" || !Number.isFinite(watch.window) || watch.window < 0) return { allowed: false, reason: "The flow measurement needs a reviewed watch window of zero or more milliseconds." };
|
|
4870
|
+
const budgetcheck = debugwaitbudgetallowed(watch.window, typeof options.wait === "number" ? options.wait : void 0);
|
|
4871
|
+
if (!budgetcheck.allowed) return budgetcheck;
|
|
4872
|
+
return { allowed: true };
|
|
4873
|
+
}
|
|
4874
|
+
if (kind === "heapshot") {
|
|
4875
|
+
const heap = options.heap && typeof options.heap === "object" && !Array.isArray(options.heap) ? options.heap : {};
|
|
4876
|
+
if (heap.interval !== void 0 && (typeof heap.interval !== "number" || !Number.isFinite(heap.interval) || heap.interval < 0)) return { allowed: false, reason: "The reviewed heap snapshot interval must be zero or a positive number of milliseconds and stays a user choice with no code ceiling." };
|
|
4877
|
+
return { allowed: true };
|
|
4878
|
+
}
|
|
4879
|
+
if (kind === "trackmemory") {
|
|
4880
|
+
const growth = options.growth && typeof options.growth === "object" && !Array.isArray(options.growth) ? options.growth : void 0;
|
|
4881
|
+
if (!growth || typeof growth.slope !== "number" || !Number.isFinite(growth.slope) || growth.slope < 0) return { allowed: false, reason: "Memory growth tracking needs the reviewed slope in bytes per millisecond before any sample is flagged." };
|
|
4882
|
+
if (growth.interval !== void 0 && (typeof growth.interval !== "number" || !Number.isFinite(growth.interval) || growth.interval < 0)) return { allowed: false, reason: "The reviewed sampling interval must be zero or a positive number of milliseconds and stays a user choice with no code ceiling." };
|
|
4883
|
+
return { allowed: true };
|
|
4884
|
+
}
|
|
4885
|
+
if (kind === "profilecpu") {
|
|
4886
|
+
const profile = options.profile && typeof options.profile === "object" && !Array.isArray(options.profile) ? options.profile : void 0;
|
|
4887
|
+
if (!profile || typeof profile.duration !== "number" || !Number.isFinite(profile.duration) || profile.duration < 0) return { allowed: false, reason: "The cpu profile needs a reviewed duration of zero or more milliseconds." };
|
|
4888
|
+
const budgetcheck = debugwaitbudgetallowed(profile.duration, typeof options.wait === "number" ? options.wait : void 0);
|
|
4889
|
+
if (!budgetcheck.allowed) return budgetcheck;
|
|
4890
|
+
return { allowed: true };
|
|
4891
|
+
}
|
|
4892
|
+
if (kind === "watchshifts") {
|
|
4893
|
+
const watch = options.watch && typeof options.watch === "object" && !Array.isArray(options.watch) ? options.watch : {};
|
|
4894
|
+
if (typeof watch.window !== "number" || !Number.isFinite(watch.window) || watch.window < 0) return { allowed: false, reason: "The layout shift watch needs a reviewed observation window of zero or more milliseconds; the window stays a user choice with no code ceiling." };
|
|
4895
|
+
if (options.threshold !== void 0 && (typeof options.threshold !== "number" || !Number.isFinite(options.threshold) || options.threshold < 0)) return { allowed: false, reason: "The reviewed shift score threshold must be zero or a positive number." };
|
|
4896
|
+
const budgetcheck = debugwaitbudgetallowed(watch.window, typeof options.wait === "number" ? options.wait : void 0);
|
|
4897
|
+
if (!budgetcheck.allowed) return budgetcheck;
|
|
4898
|
+
return { allowed: true };
|
|
4899
|
+
}
|
|
4900
|
+
if (kind === "traceload") {
|
|
4901
|
+
const trace = options.trace && typeof options.trace === "object" && !Array.isArray(options.trace) ? options.trace : void 0;
|
|
4902
|
+
if (!trace || !Array.isArray(trace.categories) || trace.categories.length === 0 || !trace.categories.every((category) => typeof category === "string" && tracecategories.includes(category))) return { allowed: false, reason: `The trace record needs a non-empty reviewed category list of the reviewed category grammar: ${tracecategories.join(", ")}.` };
|
|
4903
|
+
if (typeof trace.window !== "number" || !Number.isFinite(trace.window) || trace.window < 0) return { allowed: false, reason: "The trace record needs a reviewed window of zero or more milliseconds and stops at the reviewed window end." };
|
|
4904
|
+
if (trace.exporttarget !== void 0 && trace.exporttarget !== "memory" && trace.exporttarget !== "download") return { allowed: false, reason: "The trace export target must be memory or download." };
|
|
4905
|
+
const budgetcheck = debugwaitbudgetallowed(trace.window, typeof options.wait === "number" ? options.wait : void 0);
|
|
4906
|
+
if (!budgetcheck.allowed) return budgetcheck;
|
|
4907
|
+
return { allowed: true };
|
|
4908
|
+
}
|
|
4909
|
+
if (kind === "annotatetrace" || kind === "replaytrace") {
|
|
4910
|
+
const trace = options.trace && typeof options.trace === "object" && !Array.isArray(options.trace) ? options.trace : void 0;
|
|
4911
|
+
if (!trace || typeof trace.traceid !== "string" || !trace.traceid.trim()) return { allowed: false, reason: `The ${kind === "annotatetrace" ? "trace annotation" : "trace replay"} needs the stored trace id of a recorded trace.` };
|
|
4912
|
+
if (kind === "replaytrace") return { allowed: true };
|
|
4913
|
+
if (!Array.isArray(options.annotations) || options.annotations.length === 0 || !options.annotations.every((annotation) => annotationof(annotation) !== void 0)) return { allowed: false, reason: "Exported traces carry their step annotations: every annotation needs a step id, a label and an optional offset from the trace start." };
|
|
4914
|
+
return { allowed: true };
|
|
4915
|
+
}
|
|
4916
|
+
if (kind === "capturesourcemaps") {
|
|
4917
|
+
if (options.scripts !== void 0) {
|
|
4918
|
+
if (!Array.isArray(options.scripts) || options.scripts.length === 0 || !options.scripts.every((url) => typeof url === "string" && ishttpsurl(url))) return { allowed: false, reason: "The source map capture scripts must be a non-empty list of reviewed HTTPS urls." };
|
|
4919
|
+
}
|
|
4920
|
+
return { allowed: true };
|
|
4921
|
+
}
|
|
4922
|
+
return { allowed: true };
|
|
4923
|
+
}
|
|
4924
|
+
function planallowlist(steps) {
|
|
4925
|
+
const attach = steps.find((step) => step.kind === "attachcdp");
|
|
4926
|
+
if (!attach) return void 0;
|
|
4927
|
+
let options = {};
|
|
4928
|
+
try {
|
|
4929
|
+
options = parseoptions(attach);
|
|
4930
|
+
} catch {
|
|
4931
|
+
options = {};
|
|
4932
|
+
}
|
|
4933
|
+
const domains = Array.isArray(options.domains) ? options.domains.filter((domain) => typeof domain === "string" && cdpdomains.includes(domain)) : [];
|
|
4934
|
+
if (domains.length === 0) return void 0;
|
|
4935
|
+
const gated = cdpallowlistof(options.allowlist);
|
|
4936
|
+
return { domains, ...gated?.methods !== void 0 ? { methods: gated.methods } : {} };
|
|
4937
|
+
}
|
|
4129
4938
|
function controltarget(step) {
|
|
4130
4939
|
let options = {};
|
|
4131
4940
|
try {
|
|
@@ -4535,6 +5344,14 @@ function validatestep(step, origin) {
|
|
|
4535
5344
|
const timelinecheck = validatetimelinegrammar(step, options);
|
|
4536
5345
|
if (!timelinecheck.allowed) return timelinecheck;
|
|
4537
5346
|
}
|
|
5347
|
+
if (iscdpkind(step.kind)) {
|
|
5348
|
+
const cdpcheck = validatecdpgrammar(step, options);
|
|
5349
|
+
if (!cdpcheck.allowed) return cdpcheck;
|
|
5350
|
+
}
|
|
5351
|
+
if (isprofilekind(step.kind)) {
|
|
5352
|
+
const profilecheck = validateprofilegrammar(step, options);
|
|
5353
|
+
if (!profilecheck.allowed) return profilecheck;
|
|
5354
|
+
}
|
|
4538
5355
|
if (step.kind === "tabcreate") {
|
|
4539
5356
|
if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
|
|
4540
5357
|
if (options.window !== void 0 && (typeof options.window !== "number" || !Number.isInteger(options.window) || options.window < 0)) return { allowed: false, reason: "The reviewed target window id must be a non-negative integer." };
|
|
@@ -4640,6 +5457,70 @@ function canexecute(input) {
|
|
|
4640
5457
|
const timelinegatecheck = timelinegate(input.session, input.tabid, input.origin, now);
|
|
4641
5458
|
if (!timelinegatecheck.allowed) return timelinegatecheck;
|
|
4642
5459
|
}
|
|
5460
|
+
if (iscdpkind(input.step.kind)) {
|
|
5461
|
+
const debuggatecheck = debuggate(input.session, input.tabid, input.origin, now);
|
|
5462
|
+
if (!debuggatecheck.allowed) return debuggatecheck;
|
|
5463
|
+
if (!input.plan) return { allowed: false, reason: "The devtools protocol steps need an approved plan." };
|
|
5464
|
+
const allowlist = planallowlist(input.plan.steps);
|
|
5465
|
+
if (input.step.kind !== "attachcdp") {
|
|
5466
|
+
if (allowlist === void 0) return { allowed: false, reason: "The devtools protocol step needs the attachcdp step of the same plan with its enabled domains first." };
|
|
5467
|
+
if (input.step.kind === "cdpcmd") {
|
|
5468
|
+
let cdpoptions2 = {};
|
|
5469
|
+
try {
|
|
5470
|
+
cdpoptions2 = parseoptions(input.step);
|
|
5471
|
+
} catch {
|
|
5472
|
+
cdpoptions2 = {};
|
|
5473
|
+
}
|
|
5474
|
+
const command = cdpoptions2.command && typeof cdpoptions2.command === "object" && !Array.isArray(cdpoptions2.command) ? cdpoptions2.command : void 0;
|
|
5475
|
+
const method = typeof command?.method === "string" ? command.method : "";
|
|
5476
|
+
if (methoddomain(method) === void 0 || !allowlistcovers(allowlist, method)) return { allowed: false, reason: `The raw command ${method || ""} stays outside the enabled domain allowlist of the plan attach; review the attach domains or the method gates.` };
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
let cdpoptions = {};
|
|
5480
|
+
try {
|
|
5481
|
+
cdpoptions = parseoptions(input.step);
|
|
5482
|
+
} catch {
|
|
5483
|
+
cdpoptions = {};
|
|
5484
|
+
}
|
|
5485
|
+
if (input.step.kind === "setbreakpoint") {
|
|
5486
|
+
const breakpoint = breakpointinputof(cdpoptions.breakpoint);
|
|
5487
|
+
if (breakpoint) {
|
|
5488
|
+
const targetgate2 = origincheck(input.session, breakpoint.url);
|
|
5489
|
+
if (!targetgate2.allowed) return targetgate2;
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
if (input.step.kind === "overridescript") {
|
|
5493
|
+
const override = overrideinputof(cdpoptions.override);
|
|
5494
|
+
if (override) {
|
|
5495
|
+
const targetgate2 = origincheck(input.session, override.urlpattern);
|
|
5496
|
+
if (!targetgate2.allowed) return targetgate2;
|
|
5497
|
+
}
|
|
5498
|
+
}
|
|
5499
|
+
}
|
|
5500
|
+
if (isprofilekind(input.step.kind)) {
|
|
5501
|
+
let profileoptions = {};
|
|
5502
|
+
try {
|
|
5503
|
+
profileoptions = parseoptions(input.step);
|
|
5504
|
+
} catch {
|
|
5505
|
+
profileoptions = {};
|
|
5506
|
+
}
|
|
5507
|
+
const targets = [
|
|
5508
|
+
...attachtargetof(profileoptions.target) !== void 0 ? [attachtargetof(profileoptions.target)] : [],
|
|
5509
|
+
...Array.isArray(profileoptions.attachtargets) ? profileoptions.attachtargets.flatMap((target) => {
|
|
5510
|
+
const parsed = attachtargetof(target);
|
|
5511
|
+
return parsed !== void 0 ? [parsed] : [];
|
|
5512
|
+
}) : []
|
|
5513
|
+
];
|
|
5514
|
+
const targetgatecheck = targetgate({ session: input.session, tabid: input.tabid, origin: input.origin, targets, grants: void 0, now });
|
|
5515
|
+
if (!targetgatecheck.allowed) return targetgatecheck;
|
|
5516
|
+
if (input.step.kind === "capturesourcemaps") {
|
|
5517
|
+
for (const url of Array.isArray(profileoptions.scripts) ? profileoptions.scripts : []) {
|
|
5518
|
+
if (typeof url !== "string") continue;
|
|
5519
|
+
const scriptgate = origincheck(input.session, url);
|
|
5520
|
+
if (!scriptgate.allowed) return scriptgate;
|
|
5521
|
+
}
|
|
5522
|
+
}
|
|
5523
|
+
}
|
|
4643
5524
|
if (iscontrolkind(input.step.kind)) {
|
|
4644
5525
|
const controlgate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: "control the network" });
|
|
4645
5526
|
if (!controlgate.allowed) return controlgate;
|
|
@@ -4685,8 +5566,8 @@ function canexecute(input) {
|
|
|
4685
5566
|
}
|
|
4686
5567
|
const target = controltarget(input.step);
|
|
4687
5568
|
if (target !== void 0) {
|
|
4688
|
-
const
|
|
4689
|
-
if (!
|
|
5569
|
+
const targetgate2 = origincheck(input.session, target);
|
|
5570
|
+
if (!targetgate2.allowed) return targetgate2;
|
|
4690
5571
|
}
|
|
4691
5572
|
}
|
|
4692
5573
|
if (input.step.kind === "extractapi") {
|
|
@@ -4723,7 +5604,7 @@ function canexecute(input) {
|
|
|
4723
5604
|
}
|
|
4724
5605
|
|
|
4725
5606
|
// version.ts
|
|
4726
|
-
var packageversion = "1.1.
|
|
5607
|
+
var packageversion = "1.1.47";
|
|
4727
5608
|
|
|
4728
5609
|
// types.ts
|
|
4729
5610
|
var protocolversion = packageversion;
|
|
@@ -4748,6 +5629,20 @@ function parseproposal(value, origin, grants) {
|
|
|
4748
5629
|
const expiresat = typeof planinput.expiresat === "number" ? planinput.expiresat : createdat + 10 * 60 * 1e3;
|
|
4749
5630
|
if (expiresat <= createdat) throw new Error("Plan expiry must be in the future.");
|
|
4750
5631
|
const planwindow = expiresat - createdat;
|
|
5632
|
+
const attachinput = stepsinput.map((input) => record(input)).find((candidate) => candidate.kind === "attachcdp");
|
|
5633
|
+
let planallowlist2;
|
|
5634
|
+
if (attachinput !== void 0) {
|
|
5635
|
+
const attachoptions = (() => {
|
|
5636
|
+
try {
|
|
5637
|
+
return parseoptions({ id: "attach", kind: "attachcdp", summary: "attach", risk: "sensitive", ...typeof attachinput.options === "string" ? { options: attachinput.options } : {} });
|
|
5638
|
+
} catch {
|
|
5639
|
+
return {};
|
|
5640
|
+
}
|
|
5641
|
+
})();
|
|
5642
|
+
const domains = Array.isArray(attachoptions.domains) ? attachoptions.domains.filter((domain) => typeof domain === "string" && cdpdomains.includes(domain)) : [];
|
|
5643
|
+
const gated = cdpallowlistof(attachoptions.allowlist);
|
|
5644
|
+
planallowlist2 = domains.length > 0 ? { domains, ...gated?.methods !== void 0 ? { methods: gated.methods } : {} } : void 0;
|
|
5645
|
+
}
|
|
4751
5646
|
const steps = stepsinput.map((input, index) => {
|
|
4752
5647
|
const candidate = record(input);
|
|
4753
5648
|
const kind = text(candidate.kind, `step ${index + 1} kind`);
|
|
@@ -4798,6 +5693,89 @@ function parseproposal(value, origin, grants) {
|
|
|
4798
5693
|
if (!granted) throw new Error(`The ${step.kind} capture of ${origin} targets an origin outside the grants.`);
|
|
4799
5694
|
if (debugoptions.level !== void 0 && !loglevels.includes(debugoptions.level)) throw new Error(`The reviewed level floor must be one of ${loglevels.join(", ")}.`);
|
|
4800
5695
|
}
|
|
5696
|
+
if (iscdpkind(step.kind)) {
|
|
5697
|
+
const granted = covered.some((pattern) => {
|
|
5698
|
+
try {
|
|
5699
|
+
return new URL(origin).origin === new URL(pattern).origin;
|
|
5700
|
+
} catch {
|
|
5701
|
+
return false;
|
|
5702
|
+
}
|
|
5703
|
+
});
|
|
5704
|
+
if (!granted) throw new Error(`The ${step.kind} step of ${origin} targets an origin outside the grants.`);
|
|
5705
|
+
let cdpoptions = {};
|
|
5706
|
+
try {
|
|
5707
|
+
cdpoptions = parseoptions(step);
|
|
5708
|
+
} catch {
|
|
5709
|
+
cdpoptions = {};
|
|
5710
|
+
}
|
|
5711
|
+
if (step.kind === "attachcdp") {
|
|
5712
|
+
if (teardownplanof(cdpoptions.teardown) === void 0) throw new Error("Attach steps without a reviewed teardown plan are refused.");
|
|
5713
|
+
const domains = Array.isArray(cdpoptions.domains) ? cdpoptions.domains.filter((domain) => typeof domain === "string" && cdpdomains.includes(domain)) : [];
|
|
5714
|
+
if (domains.length === 0) throw new Error("Attach steps need a non-empty enabled domain list of the reviewed domain grammar.");
|
|
5715
|
+
const gated = cdpallowlistof(cdpoptions.allowlist);
|
|
5716
|
+
if (cdpoptions.allowlist !== void 0 && (!gated || !gated.domains.every((domain) => domains.includes(domain)))) throw new Error("The reviewed method allowlist must stay inside the enabled domains of the attach.");
|
|
5717
|
+
}
|
|
5718
|
+
if (step.kind === "cdpcmd") {
|
|
5719
|
+
const command = cdpoptions.command && typeof cdpoptions.command === "object" && !Array.isArray(cdpoptions.command) ? cdpoptions.command : void 0;
|
|
5720
|
+
const method = typeof command?.method === "string" ? command.method : "";
|
|
5721
|
+
if (methoddomain(method) === void 0) throw new Error("Raw commands need a reviewed method of the Domain.method form.");
|
|
5722
|
+
if (planallowlist2 === void 0) throw new Error("Raw command steps need the attachcdp step of the same plan with its enabled domains first.");
|
|
5723
|
+
if (!allowlistcovers(planallowlist2, method)) throw new Error(`The raw command ${method} stays outside the enabled domain allowlist of the plan attach.`);
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
if (isprofilekind(step.kind)) {
|
|
5727
|
+
const granted = covered.some((pattern) => {
|
|
5728
|
+
try {
|
|
5729
|
+
return new URL(origin).origin === new URL(pattern).origin;
|
|
5730
|
+
} catch {
|
|
5731
|
+
return false;
|
|
5732
|
+
}
|
|
5733
|
+
});
|
|
5734
|
+
if (!granted) throw new Error(`The ${step.kind} step of ${origin} targets an origin outside the grants.`);
|
|
5735
|
+
let profileoptions = {};
|
|
5736
|
+
try {
|
|
5737
|
+
profileoptions = parseoptions(step);
|
|
5738
|
+
} catch {
|
|
5739
|
+
profileoptions = {};
|
|
5740
|
+
}
|
|
5741
|
+
const targets = [
|
|
5742
|
+
...attachtargetof(profileoptions.target) !== void 0 ? [attachtargetof(profileoptions.target)] : [],
|
|
5743
|
+
...Array.isArray(profileoptions.attachtargets) ? profileoptions.attachtargets.flatMap((target2) => {
|
|
5744
|
+
const parsed = attachtargetof(target2);
|
|
5745
|
+
return parsed !== void 0 ? [parsed] : [];
|
|
5746
|
+
}) : []
|
|
5747
|
+
];
|
|
5748
|
+
for (const target2 of targets) {
|
|
5749
|
+
if (target2.kind === "page") continue;
|
|
5750
|
+
const targetgranted = covered.some((pattern) => {
|
|
5751
|
+
try {
|
|
5752
|
+
return new URL(target2.url).origin === new URL(pattern).origin;
|
|
5753
|
+
} catch {
|
|
5754
|
+
return false;
|
|
5755
|
+
}
|
|
5756
|
+
});
|
|
5757
|
+
if (!targetgranted) throw new Error(`The ${target2.kind} target ${target2.url} of the ${step.kind} step stays outside the granted origins.`);
|
|
5758
|
+
}
|
|
5759
|
+
if (step.kind === "traceload") {
|
|
5760
|
+
const trace = profileoptions.trace && typeof profileoptions.trace === "object" && !Array.isArray(profileoptions.trace) ? profileoptions.trace : void 0;
|
|
5761
|
+
const categories = trace !== void 0 && Array.isArray(trace.categories) ? trace.categories : [];
|
|
5762
|
+
if (categories.some((category) => typeof category !== "string" || !tracecategories.includes(category))) throw new Error(`Trace categories outside the reviewed list are refused: ${tracecategories.join(", ")}.`);
|
|
5763
|
+
}
|
|
5764
|
+
if (step.kind === "capturesourcemaps") {
|
|
5765
|
+
for (const url of Array.isArray(profileoptions.scripts) ? profileoptions.scripts : []) {
|
|
5766
|
+
if (typeof url !== "string") continue;
|
|
5767
|
+
const scriptgranted = covered.some((pattern) => {
|
|
5768
|
+
try {
|
|
5769
|
+
return new URL(url).origin === new URL(pattern).origin;
|
|
5770
|
+
} catch {
|
|
5771
|
+
return false;
|
|
5772
|
+
}
|
|
5773
|
+
});
|
|
5774
|
+
if (!scriptgranted) throw new Error(`The source map capture of ${url} targets an origin outside the grants.`);
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5777
|
+
if (step.kind === "annotatetrace" && (!Array.isArray(profileoptions.annotations) || profileoptions.annotations.length === 0 || !profileoptions.annotations.every((annotation) => annotationof(annotation) !== void 0))) throw new Error("Trace annotation steps without reviewed step annotations are refused.");
|
|
5778
|
+
}
|
|
4801
5779
|
const evaluation = validatestep(step, origin);
|
|
4802
5780
|
if (!evaluation.allowed) throw new Error(evaluation.reason);
|
|
4803
5781
|
const target = outboundtarget(step);
|
|
@@ -4872,7 +5850,7 @@ function requestbody(input) {
|
|
|
4872
5850
|
return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
|
|
4873
5851
|
}
|
|
4874
5852
|
function outcomeresponse(input) {
|
|
4875
|
-
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {} });
|
|
5853
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {}, ...input.profile ? { profile: input.profile } : {} });
|
|
4876
5854
|
}
|
|
4877
5855
|
function mapresponse(input) {
|
|
4878
5856
|
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
|
|
@@ -4989,7 +5967,31 @@ function timelinereport(input) {
|
|
|
4989
5967
|
function consolediffreport(input) {
|
|
4990
5968
|
return { version: protocolversion, diff: input.diff };
|
|
4991
5969
|
}
|
|
5970
|
+
function cdpreport(input) {
|
|
5971
|
+
const overrides = input.overrides.map((spec) => {
|
|
5972
|
+
const { source, ...metadata } = spec;
|
|
5973
|
+
void source;
|
|
5974
|
+
return metadata;
|
|
5975
|
+
});
|
|
5976
|
+
const grants = input.grants.map((grant) => {
|
|
5977
|
+
const { prompt, ...metadata } = grant;
|
|
5978
|
+
void prompt;
|
|
5979
|
+
return metadata;
|
|
5980
|
+
});
|
|
5981
|
+
return { version: protocolversion, sessions: input.sessions, commands: input.commands, events: input.events, breakpoints: input.breakpoints, pauses: input.pauses, watches: input.watches, overrides, grants };
|
|
5982
|
+
}
|
|
5983
|
+
function profilereport(input) {
|
|
5984
|
+
const consents = input.consents.map((consent) => {
|
|
5985
|
+
const { prompt, ...metadata } = consent;
|
|
5986
|
+
void prompt;
|
|
5987
|
+
return metadata;
|
|
5988
|
+
});
|
|
5989
|
+
return { version: protocolversion, flows: input.flows, heaps: input.heaps, samples: input.samples, trends: input.trends, profiles: input.profiles, shifts: input.shifts, traces: input.traces, sourcemaps: input.sourcemaps, consents };
|
|
5990
|
+
}
|
|
4992
5991
|
export {
|
|
5992
|
+
allowlistcovers,
|
|
5993
|
+
annotatetrace,
|
|
5994
|
+
annotationof,
|
|
4993
5995
|
annotationplanof,
|
|
4994
5996
|
apientries,
|
|
4995
5997
|
apikeyconsentgranted,
|
|
@@ -4997,6 +5999,8 @@ export {
|
|
|
4997
5999
|
applyheaderules,
|
|
4998
6000
|
argkind,
|
|
4999
6001
|
assetentries,
|
|
6002
|
+
attachcdpsession,
|
|
6003
|
+
attachtargetof,
|
|
5000
6004
|
attachtimeline,
|
|
5001
6005
|
authconsentgranted,
|
|
5002
6006
|
authorizeurl,
|
|
@@ -5007,6 +6011,9 @@ export {
|
|
|
5007
6011
|
blockruleof,
|
|
5008
6012
|
bodyfilterof,
|
|
5009
6013
|
bodymatches,
|
|
6014
|
+
breakpointbudgetallowed,
|
|
6015
|
+
breakpointceilingof,
|
|
6016
|
+
breakpointinputof,
|
|
5010
6017
|
buildname,
|
|
5011
6018
|
buildpdf,
|
|
5012
6019
|
buildsheet,
|
|
@@ -5022,12 +6029,19 @@ export {
|
|
|
5022
6029
|
captureformats,
|
|
5023
6030
|
capturekinds,
|
|
5024
6031
|
captureoptionsof,
|
|
6032
|
+
capturepause,
|
|
5025
6033
|
captureregion,
|
|
5026
6034
|
capturereport,
|
|
6035
|
+
capturesourcemaps,
|
|
5027
6036
|
capturestates,
|
|
5028
6037
|
capturestitched,
|
|
5029
6038
|
capturetargets,
|
|
5030
6039
|
capturevisible,
|
|
6040
|
+
cdpallowlistof,
|
|
6041
|
+
cdpdomains,
|
|
6042
|
+
cdpeventruleof,
|
|
6043
|
+
cdpkinds,
|
|
6044
|
+
cdpreport,
|
|
5031
6045
|
channeloptionsof,
|
|
5032
6046
|
channelorigin,
|
|
5033
6047
|
closechannel,
|
|
@@ -5044,13 +6058,17 @@ export {
|
|
|
5044
6058
|
cookiegate,
|
|
5045
6059
|
cookierecordof,
|
|
5046
6060
|
correlationid,
|
|
6061
|
+
cpusnap,
|
|
5047
6062
|
croprect,
|
|
5048
6063
|
crossesviewport,
|
|
5049
6064
|
cursorfrom,
|
|
5050
6065
|
datasetresponse,
|
|
6066
|
+
debuggate,
|
|
6067
|
+
debuggerconsentcovers,
|
|
5051
6068
|
debugwaitbudgetallowed,
|
|
5052
6069
|
dedupeimages,
|
|
5053
6070
|
actionrisk as deriveactionrisk,
|
|
6071
|
+
detachcdpsession,
|
|
5054
6072
|
diffresponse,
|
|
5055
6073
|
diffreviewgrade,
|
|
5056
6074
|
downloadreport,
|
|
@@ -5058,6 +6076,7 @@ export {
|
|
|
5058
6076
|
errorreportresponse,
|
|
5059
6077
|
eventresponse,
|
|
5060
6078
|
exchangesreport,
|
|
6079
|
+
expireprofilerecords,
|
|
5061
6080
|
extractionreport,
|
|
5062
6081
|
extractvalues,
|
|
5063
6082
|
failureclass,
|
|
@@ -5067,14 +6086,20 @@ export {
|
|
|
5067
6086
|
filterexchanges,
|
|
5068
6087
|
finishrecording,
|
|
5069
6088
|
fixedheadermatch,
|
|
6089
|
+
flowmetricnames,
|
|
6090
|
+
flowspecof,
|
|
5070
6091
|
formpayloadof,
|
|
5071
6092
|
formreportresponse,
|
|
5072
6093
|
frameinterval,
|
|
5073
6094
|
generatedvalueallowed,
|
|
5074
6095
|
graphqlopenvelope,
|
|
5075
6096
|
graphqlrequestof,
|
|
6097
|
+
growsampleof,
|
|
6098
|
+
growthtrend,
|
|
5076
6099
|
headerfilterof,
|
|
5077
6100
|
headeruleof,
|
|
6101
|
+
heapintervalallowed,
|
|
6102
|
+
heapsnap,
|
|
5078
6103
|
heldkeysreport,
|
|
5079
6104
|
hostpattern,
|
|
5080
6105
|
htmlqueriesof,
|
|
@@ -5082,10 +6107,12 @@ export {
|
|
|
5082
6107
|
imagefilterof,
|
|
5083
6108
|
imagematches,
|
|
5084
6109
|
imagenames,
|
|
6110
|
+
iscdpkind,
|
|
5085
6111
|
iscontrolkind,
|
|
5086
6112
|
isdebugkind,
|
|
5087
6113
|
isformkind,
|
|
5088
6114
|
isnetwatchkind,
|
|
6115
|
+
isprofilekind,
|
|
5089
6116
|
issocketkind,
|
|
5090
6117
|
iswatchkind,
|
|
5091
6118
|
jsonpathrulesof,
|
|
@@ -5096,12 +6123,15 @@ export {
|
|
|
5096
6123
|
loglevels,
|
|
5097
6124
|
longtaskcapture,
|
|
5098
6125
|
mapresponse,
|
|
6126
|
+
mapurlof,
|
|
5099
6127
|
matchmessage,
|
|
5100
6128
|
matchurlpattern,
|
|
6129
|
+
measure,
|
|
5101
6130
|
mediaentries,
|
|
5102
6131
|
mediakinds,
|
|
5103
6132
|
mediareport,
|
|
5104
6133
|
messagefilterof,
|
|
6134
|
+
methoddomain,
|
|
5105
6135
|
mockfor,
|
|
5106
6136
|
mockspecof,
|
|
5107
6137
|
multipartchunks,
|
|
@@ -5122,6 +6152,8 @@ export {
|
|
|
5122
6152
|
observationresponse,
|
|
5123
6153
|
openchannel,
|
|
5124
6154
|
outcomeresponse,
|
|
6155
|
+
overrideinputof,
|
|
6156
|
+
overridematches,
|
|
5125
6157
|
pairexchange,
|
|
5126
6158
|
pairstates,
|
|
5127
6159
|
parsehtmlbody,
|
|
@@ -5130,6 +6162,7 @@ export {
|
|
|
5130
6162
|
parsetokens,
|
|
5131
6163
|
passwordconsentgranted,
|
|
5132
6164
|
patternorigin,
|
|
6165
|
+
pauseretentionwindow,
|
|
5133
6166
|
payloadshapeof,
|
|
5134
6167
|
payloadvalid,
|
|
5135
6168
|
payloadwithdefaults,
|
|
@@ -5137,11 +6170,15 @@ export {
|
|
|
5137
6170
|
pdfpagesize,
|
|
5138
6171
|
pdfsegments,
|
|
5139
6172
|
pdftextlayout,
|
|
6173
|
+
planallowlist,
|
|
5140
6174
|
pollcursorof,
|
|
5141
6175
|
polldecision,
|
|
5142
6176
|
pollurl,
|
|
5143
6177
|
privatemime,
|
|
5144
6178
|
profilegrantgranted,
|
|
6179
|
+
profilereport,
|
|
6180
|
+
profileretentionwindow,
|
|
6181
|
+
profilerkinds,
|
|
5145
6182
|
protocolversion,
|
|
5146
6183
|
provenancereport,
|
|
5147
6184
|
proxygate,
|
|
@@ -5158,10 +6195,12 @@ export {
|
|
|
5158
6195
|
receivemessage,
|
|
5159
6196
|
reconnectwaits,
|
|
5160
6197
|
recordingoptionsof,
|
|
6198
|
+
recordwatchvalue,
|
|
5161
6199
|
redactconsoletext,
|
|
5162
6200
|
redactedcookies,
|
|
5163
6201
|
regionsteps,
|
|
5164
6202
|
rejectioncapture,
|
|
6203
|
+
replaytrace,
|
|
5165
6204
|
replayurl,
|
|
5166
6205
|
requestbody,
|
|
5167
6206
|
resolutionverdict,
|
|
@@ -5170,30 +6209,40 @@ export {
|
|
|
5170
6209
|
retryafterof,
|
|
5171
6210
|
revertrule,
|
|
5172
6211
|
revocationruleof,
|
|
6212
|
+
rewritesourcelocation,
|
|
5173
6213
|
rotatelogs,
|
|
5174
6214
|
rotationruleof,
|
|
5175
6215
|
safetyresponse,
|
|
5176
6216
|
scaledrect,
|
|
5177
6217
|
seamweights,
|
|
5178
6218
|
selectorresponse,
|
|
6219
|
+
sendcdpcommand,
|
|
5179
6220
|
sendfetch,
|
|
5180
6221
|
sequenceintegrity,
|
|
5181
6222
|
serializearg,
|
|
6223
|
+
serializecdpcommand,
|
|
5182
6224
|
sessionmemory,
|
|
6225
|
+
shiftentryof,
|
|
5183
6226
|
signalsreport,
|
|
5184
6227
|
socketgate,
|
|
5185
6228
|
socketkinds,
|
|
6229
|
+
sourcemapconsentcovers,
|
|
5186
6230
|
spamdetect,
|
|
5187
6231
|
spamruleof,
|
|
5188
6232
|
sserequestheaders,
|
|
5189
6233
|
stackframes,
|
|
5190
6234
|
stackgate,
|
|
5191
6235
|
statusclassof,
|
|
6236
|
+
stepmodeof,
|
|
6237
|
+
stepwindows,
|
|
5192
6238
|
streamsummaries,
|
|
5193
6239
|
streamwindowof,
|
|
5194
6240
|
submitreviewgranted,
|
|
5195
6241
|
subscriptionoptionsof,
|
|
5196
6242
|
tabreportresponse,
|
|
6243
|
+
targetgate,
|
|
6244
|
+
teardowncdpsession,
|
|
6245
|
+
teardownplanof,
|
|
5197
6246
|
templateurl,
|
|
5198
6247
|
thumbdirectiveof,
|
|
5199
6248
|
thumbgeometry,
|
|
@@ -5204,16 +6253,23 @@ export {
|
|
|
5204
6253
|
timelineretentionwindow,
|
|
5205
6254
|
timelinesources,
|
|
5206
6255
|
tokenrequest,
|
|
6256
|
+
tracecategories,
|
|
6257
|
+
traceceilingof,
|
|
6258
|
+
tracestart,
|
|
6259
|
+
tracetofile,
|
|
5207
6260
|
trailreport,
|
|
5208
6261
|
transformgrammar,
|
|
5209
6262
|
unwrapgraphql,
|
|
5210
6263
|
urlencodeform,
|
|
6264
|
+
validatebreakpointcondition,
|
|
5211
6265
|
validatefieldmatch,
|
|
5212
6266
|
validateformrecord,
|
|
5213
6267
|
validatestep,
|
|
5214
6268
|
validatetargetref,
|
|
5215
6269
|
validatevaluegen,
|
|
6270
|
+
watchcdpevents,
|
|
5216
6271
|
watcherdetached,
|
|
6272
|
+
watchexpressionof,
|
|
5217
6273
|
watchgate,
|
|
5218
6274
|
wizardreport
|
|
5219
6275
|
};
|