@vforsh/argus 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/argus.js +402 -149
- package/dist/cli/register/keydownCommand.d.ts.map +1 -1
- package/dist/cli/register/keydownCommand.js +15 -2
- package/dist/cli/register/keydownCommand.js.map +1 -1
- package/dist/cli/register/netCommands.d.ts +5 -0
- package/dist/cli/register/netCommands.d.ts.map +1 -1
- package/dist/cli/register/netCommands.js +23 -6
- package/dist/cli/register/netCommands.js.map +1 -1
- package/dist/commands/domKeydown.d.ts +8 -1
- package/dist/commands/domKeydown.d.ts.map +1 -1
- package/dist/commands/domKeydown.js +35 -6
- package/dist/commands/domKeydown.js.map +1 -1
- package/dist/commands/netMock.d.ts +2 -0
- package/dist/commands/netMock.d.ts.map +1 -1
- package/dist/commands/netMock.js +22 -1
- package/dist/commands/netMock.js.map +1 -1
- package/dist/skill/argus/SKILL.md +3 -0
- package/dist/skill/argus/reference/INSPECT.md +3 -1
- package/dist/skill/argus/reference/NET.md +4 -1
- package/package.json +1 -1
package/dist/argus.js
CHANGED
|
@@ -5,15 +5,29 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
@@ -2130,7 +2144,7 @@ var {
|
|
|
2130
2144
|
// package.json
|
|
2131
2145
|
var package_default = {
|
|
2132
2146
|
name: "@vforsh/argus",
|
|
2133
|
-
version: "0.1.
|
|
2147
|
+
version: "0.1.21",
|
|
2134
2148
|
repository: {
|
|
2135
2149
|
type: "git",
|
|
2136
2150
|
url: "git+https://github.com/vforsh/argus.git",
|
|
@@ -6838,6 +6852,9 @@ function validateAddRequest(body) {
|
|
|
6838
6852
|
if (payload.times !== undefined && (!Number.isInteger(payload.times) || payload.times < 1)) {
|
|
6839
6853
|
return "times must be an integer >= 1";
|
|
6840
6854
|
}
|
|
6855
|
+
if (payload.scope !== undefined && payload.scope !== "page" && payload.scope !== "selected") {
|
|
6856
|
+
return "scope must be one of: page, selected";
|
|
6857
|
+
}
|
|
6841
6858
|
return null;
|
|
6842
6859
|
}
|
|
6843
6860
|
var validateMatch = (match) => {
|
|
@@ -9358,10 +9375,12 @@ var route29 = defineJsonRoute({
|
|
|
9358
9375
|
});
|
|
9359
9376
|
|
|
9360
9377
|
// ../argus-watcher/dist/cdp/keyboard.js
|
|
9361
|
-
var
|
|
9362
|
-
const
|
|
9378
|
+
var buildKeyMaps = () => {
|
|
9379
|
+
const byKey = new Map;
|
|
9380
|
+
const byCode = new Map;
|
|
9363
9381
|
const put = (lookup, def) => {
|
|
9364
|
-
|
|
9382
|
+
byKey.set(lookup.toLowerCase(), def);
|
|
9383
|
+
byCode.set(def.code.toLowerCase(), def);
|
|
9365
9384
|
};
|
|
9366
9385
|
for (let i = 0;i < 26; i++) {
|
|
9367
9386
|
const lower = String.fromCharCode(97 + i);
|
|
@@ -9396,11 +9415,14 @@ var buildKeyMap = () => {
|
|
|
9396
9415
|
const name = `F${i}`;
|
|
9397
9416
|
put(name, { key: name, code: name, keyCode: 111 + i });
|
|
9398
9417
|
}
|
|
9399
|
-
return
|
|
9418
|
+
return { byKey, byCode };
|
|
9400
9419
|
};
|
|
9401
|
-
var
|
|
9420
|
+
var KEY_MAPS = buildKeyMaps();
|
|
9402
9421
|
var resolveKeyDefinition = (key) => {
|
|
9403
|
-
return
|
|
9422
|
+
return KEY_MAPS.byKey.get(key.toLowerCase());
|
|
9423
|
+
};
|
|
9424
|
+
var resolveCodeDefinition = (code) => {
|
|
9425
|
+
return KEY_MAPS.byCode.get(code.toLowerCase());
|
|
9404
9426
|
};
|
|
9405
9427
|
var MODIFIER_BITS = {
|
|
9406
9428
|
alt: 1,
|
|
@@ -9430,8 +9452,61 @@ var parseModifiers = (input) => {
|
|
|
9430
9452
|
}
|
|
9431
9453
|
return mask;
|
|
9432
9454
|
};
|
|
9455
|
+
var resolveKeyboardEvent = (options) => {
|
|
9456
|
+
const modifiers = options.modifiers ?? 0;
|
|
9457
|
+
const keyInput = normalizeOptionalString(options.key);
|
|
9458
|
+
const codeInput = normalizeOptionalString(options.code);
|
|
9459
|
+
if (!keyInput && !codeInput) {
|
|
9460
|
+
throw new Error("key or code is required");
|
|
9461
|
+
}
|
|
9462
|
+
const keyDef = keyInput ? resolveKeyDefinition(keyInput) : undefined;
|
|
9463
|
+
const codeDef = codeInput ? resolveCodeDefinition(codeInput) : undefined;
|
|
9464
|
+
const baseDef = codeDef ?? keyDef;
|
|
9465
|
+
if (!baseDef) {
|
|
9466
|
+
if (codeInput && !keyInput) {
|
|
9467
|
+
throw new Error(`Unknown code: "${codeInput}"`);
|
|
9468
|
+
}
|
|
9469
|
+
throw new Error(`Unknown key: "${keyInput}"`);
|
|
9470
|
+
}
|
|
9471
|
+
const key = resolveEventKey(keyInput, baseDef, modifiers);
|
|
9472
|
+
const text = resolveEventText(key, baseDef);
|
|
9473
|
+
const event = {
|
|
9474
|
+
key,
|
|
9475
|
+
code: codeInput ?? baseDef.code,
|
|
9476
|
+
keyCode: baseDef.keyCode,
|
|
9477
|
+
modifiers,
|
|
9478
|
+
altKey: (modifiers & MODIFIER_BITS.alt) !== 0,
|
|
9479
|
+
ctrlKey: (modifiers & MODIFIER_BITS.ctrl) !== 0,
|
|
9480
|
+
metaKey: (modifiers & MODIFIER_BITS.meta) !== 0,
|
|
9481
|
+
shiftKey: (modifiers & MODIFIER_BITS.shift) !== 0
|
|
9482
|
+
};
|
|
9483
|
+
if (text !== undefined) {
|
|
9484
|
+
event.text = text;
|
|
9485
|
+
}
|
|
9486
|
+
return event;
|
|
9487
|
+
};
|
|
9488
|
+
var normalizeOptionalString = (value) => {
|
|
9489
|
+
const normalized = value?.trim();
|
|
9490
|
+
return normalized ? normalized : undefined;
|
|
9491
|
+
};
|
|
9492
|
+
var resolveEventKey = (keyInput, def, modifiers) => {
|
|
9493
|
+
const semanticKey = keyInput ?? def.key;
|
|
9494
|
+
if (isSingleLetter(semanticKey)) {
|
|
9495
|
+
return isShift(modifiers) ? semanticKey.toUpperCase() : semanticKey.toLowerCase();
|
|
9496
|
+
}
|
|
9497
|
+
return semanticKey;
|
|
9498
|
+
};
|
|
9499
|
+
var resolveEventText = (key, def) => {
|
|
9500
|
+
if (key.length === 1) {
|
|
9501
|
+
return key;
|
|
9502
|
+
}
|
|
9503
|
+
return def.text;
|
|
9504
|
+
};
|
|
9505
|
+
var isSingleLetter = (value) => /^[a-z]$/i.test(value);
|
|
9506
|
+
var isShift = (modifiers) => (modifiers & MODIFIER_BITS.shift) !== 0;
|
|
9433
9507
|
var dispatchKeydown = async (session, options) => {
|
|
9434
|
-
const {
|
|
9508
|
+
const { selector } = options;
|
|
9509
|
+
const event = resolveKeyboardEvent(options);
|
|
9435
9510
|
let focused = false;
|
|
9436
9511
|
if (selector) {
|
|
9437
9512
|
const { allNodeIds, nodeIds } = await resolveDomSelectorMatches(session, selector, false);
|
|
@@ -9447,31 +9522,23 @@ var dispatchKeydown = async (session, options) => {
|
|
|
9447
9522
|
await session.sendAndWait("DOM.focus", { nodeId });
|
|
9448
9523
|
focused = true;
|
|
9449
9524
|
}
|
|
9450
|
-
const
|
|
9451
|
-
if (!def) {
|
|
9452
|
-
throw new Error(`Unknown key: "${key}"`);
|
|
9453
|
-
}
|
|
9454
|
-
let text = def.text;
|
|
9455
|
-
if (text && text.length === 1 && (modifiers & 8) !== 0) {
|
|
9456
|
-
text = text.toUpperCase();
|
|
9457
|
-
}
|
|
9458
|
-
const isPrintable = text != null && text !== "\r";
|
|
9525
|
+
const isPrintable = event.text != null && event.text !== "\r";
|
|
9459
9526
|
const baseParams = {
|
|
9460
|
-
code:
|
|
9461
|
-
key:
|
|
9462
|
-
windowsVirtualKeyCode:
|
|
9463
|
-
nativeVirtualKeyCode:
|
|
9464
|
-
modifiers
|
|
9527
|
+
code: event.code,
|
|
9528
|
+
key: event.key,
|
|
9529
|
+
windowsVirtualKeyCode: event.keyCode,
|
|
9530
|
+
nativeVirtualKeyCode: event.keyCode,
|
|
9531
|
+
modifiers: event.modifiers
|
|
9465
9532
|
};
|
|
9466
9533
|
if (isPrintable) {
|
|
9467
|
-
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyDown", text });
|
|
9468
|
-
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "char", text });
|
|
9534
|
+
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyDown", text: event.text });
|
|
9535
|
+
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "char", text: event.text });
|
|
9469
9536
|
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
9470
9537
|
} else {
|
|
9471
|
-
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "rawKeyDown", text:
|
|
9538
|
+
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "rawKeyDown", text: event.text });
|
|
9472
9539
|
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
9473
9540
|
}
|
|
9474
|
-
return { key:
|
|
9541
|
+
return { key: event.key, code: event.code, modifiers: event.modifiers, focused, event };
|
|
9475
9542
|
};
|
|
9476
9543
|
|
|
9477
9544
|
// ../argus-watcher/dist/http/routes/postDomKeydown.js
|
|
@@ -9481,12 +9548,23 @@ var route30 = defineJsonRoute({
|
|
|
9481
9548
|
parseBody: true,
|
|
9482
9549
|
endpoint: "dom/keydown",
|
|
9483
9550
|
validate: (payload) => {
|
|
9484
|
-
|
|
9485
|
-
|
|
9551
|
+
const hasKey = typeof payload.key === "string" && payload.key.trim() !== "";
|
|
9552
|
+
const hasCode = typeof payload.code === "string" && payload.code.trim() !== "";
|
|
9553
|
+
if (payload.key != null && !hasKey) {
|
|
9554
|
+
return "key must be a non-empty string";
|
|
9555
|
+
}
|
|
9556
|
+
if (payload.code != null && !hasCode) {
|
|
9557
|
+
return "code must be a non-empty string";
|
|
9558
|
+
}
|
|
9559
|
+
if (!hasKey && !hasCode) {
|
|
9560
|
+
return "key or code is required";
|
|
9486
9561
|
}
|
|
9487
9562
|
if (payload.selector != null && (typeof payload.selector !== "string" || payload.selector.trim() === "")) {
|
|
9488
9563
|
return "selector must be a non-empty string";
|
|
9489
9564
|
}
|
|
9565
|
+
if (payload.modifiers != null && typeof payload.modifiers !== "string") {
|
|
9566
|
+
return "modifiers must be a string";
|
|
9567
|
+
}
|
|
9490
9568
|
try {
|
|
9491
9569
|
parseModifiers(payload.modifiers);
|
|
9492
9570
|
} catch (error) {
|
|
@@ -9497,10 +9575,18 @@ var route30 = defineJsonRoute({
|
|
|
9497
9575
|
handle: async ({ ctx, body: payload }) => {
|
|
9498
9576
|
const result = await dispatchKeydown(ctx.cdpSession, {
|
|
9499
9577
|
key: payload.key,
|
|
9578
|
+
code: payload.code,
|
|
9500
9579
|
selector: payload.selector,
|
|
9501
9580
|
modifiers: parseModifiers(payload.modifiers)
|
|
9502
9581
|
});
|
|
9503
|
-
return {
|
|
9582
|
+
return {
|
|
9583
|
+
ok: true,
|
|
9584
|
+
key: result.key,
|
|
9585
|
+
code: result.code,
|
|
9586
|
+
modifiers: result.modifiers,
|
|
9587
|
+
focused: result.focused,
|
|
9588
|
+
event: result.event
|
|
9589
|
+
};
|
|
9504
9590
|
}
|
|
9505
9591
|
});
|
|
9506
9592
|
|
|
@@ -11905,73 +11991,169 @@ var createThrottleController = () => {
|
|
|
11905
11991
|
return { getStatus, setDesired, clearDesired, onAttach };
|
|
11906
11992
|
};
|
|
11907
11993
|
|
|
11908
|
-
// ../argus-watcher/dist/net/
|
|
11909
|
-
var
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
11916
|
-
|
|
11917
|
-
|
|
11918
|
-
|
|
11919
|
-
|
|
11920
|
-
|
|
11921
|
-
|
|
11994
|
+
// ../argus-watcher/dist/net/NetMockInterception.js
|
|
11995
|
+
var PAGE_TARGET = { key: "page", sessionId: null };
|
|
11996
|
+
|
|
11997
|
+
class NetMockInterception {
|
|
11998
|
+
onPaused;
|
|
11999
|
+
onError;
|
|
12000
|
+
binding = null;
|
|
12001
|
+
bound = false;
|
|
12002
|
+
enabledTargets = new Map;
|
|
12003
|
+
reconcileTail = Promise.resolve();
|
|
12004
|
+
constructor(onPaused, onError) {
|
|
12005
|
+
this.onPaused = onPaused;
|
|
12006
|
+
this.onError = onError;
|
|
12007
|
+
}
|
|
12008
|
+
bind(binding) {
|
|
12009
|
+
this.binding = binding;
|
|
12010
|
+
if (this.bound) {
|
|
12011
|
+
return;
|
|
11922
12012
|
}
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
12013
|
+
this.bound = true;
|
|
12014
|
+
binding.pageSession.onEvent("Fetch.requestPaused", (params, meta) => {
|
|
12015
|
+
const request = parsePausedRequest(params, meta);
|
|
12016
|
+
if (request) {
|
|
12017
|
+
this.onPaused(request);
|
|
12018
|
+
}
|
|
12019
|
+
});
|
|
12020
|
+
}
|
|
12021
|
+
get enabled() {
|
|
12022
|
+
return this.enabledTargets.size > 0;
|
|
12023
|
+
}
|
|
12024
|
+
matchesScope(scope, request) {
|
|
12025
|
+
if (scope === "page") {
|
|
12026
|
+
return request.sessionId === null;
|
|
11928
12027
|
}
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
enabled = false;
|
|
11935
|
-
recordError(error);
|
|
12028
|
+
const selected = this.binding?.getSelectedTarget() ?? null;
|
|
12029
|
+
if (selected?.sessionId) {
|
|
12030
|
+
return request.sessionId === selected.sessionId;
|
|
12031
|
+
}
|
|
12032
|
+
if (request.sessionId !== null) {
|
|
11936
12033
|
return false;
|
|
11937
12034
|
}
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
12035
|
+
const selectedFrameId = selected?.frameId ?? null;
|
|
12036
|
+
const selectedIsChildFrame = selectedFrameId !== null && selectedFrameId !== selected?.topFrameId;
|
|
12037
|
+
return !selectedIsChildFrame || request.frameId === selectedFrameId;
|
|
12038
|
+
}
|
|
12039
|
+
async sendRequestCommand(request, method, params) {
|
|
12040
|
+
await this.sendCommand({ key: request.sessionId ? `session:${request.sessionId}` : "page", sessionId: request.sessionId }, method, params);
|
|
12041
|
+
}
|
|
12042
|
+
reconcile(scopes, reset = false) {
|
|
12043
|
+
const requestedScopes = new Set(scopes);
|
|
12044
|
+
const operation = this.reconcileTail.then(() => this.applyReconcile(requestedScopes, reset));
|
|
12045
|
+
this.reconcileTail = operation.then(() => {
|
|
11941
12046
|
return;
|
|
11942
|
-
}
|
|
11943
|
-
enabled = false;
|
|
11944
|
-
if (!session || !session.isAttached()) {
|
|
12047
|
+
}, () => {
|
|
11945
12048
|
return;
|
|
12049
|
+
});
|
|
12050
|
+
return operation;
|
|
12051
|
+
}
|
|
12052
|
+
async applyReconcile(scopes, reset) {
|
|
12053
|
+
if (reset) {
|
|
12054
|
+
this.enabledTargets.clear();
|
|
12055
|
+
}
|
|
12056
|
+
const session = this.binding?.pageSession;
|
|
12057
|
+
if (!session?.isAttached()) {
|
|
12058
|
+
this.enabledTargets.clear();
|
|
12059
|
+
return false;
|
|
12060
|
+
}
|
|
12061
|
+
const desiredTargets = this.getDesiredTargets(scopes);
|
|
12062
|
+
for (const [key, target] of this.enabledTargets) {
|
|
12063
|
+
if (!desiredTargets.has(key)) {
|
|
12064
|
+
await this.sendCommand(target, "Fetch.disable");
|
|
12065
|
+
this.enabledTargets.delete(key);
|
|
12066
|
+
}
|
|
12067
|
+
}
|
|
12068
|
+
for (const [key, target] of desiredTargets) {
|
|
12069
|
+
if (this.enabledTargets.has(key)) {
|
|
12070
|
+
continue;
|
|
12071
|
+
}
|
|
12072
|
+
const enabled = await this.sendCommand(target, "Fetch.enable", { patterns: [{ urlPattern: "*", requestStage: "Request" }] });
|
|
12073
|
+
if (enabled) {
|
|
12074
|
+
this.enabledTargets.set(key, target);
|
|
12075
|
+
}
|
|
12076
|
+
}
|
|
12077
|
+
return this.enabled;
|
|
12078
|
+
}
|
|
12079
|
+
onDetach() {
|
|
12080
|
+
this.enabledTargets.clear();
|
|
12081
|
+
}
|
|
12082
|
+
getDesiredTargets(scopes) {
|
|
12083
|
+
const targets = new Map;
|
|
12084
|
+
if (scopes.has("page")) {
|
|
12085
|
+
targets.set(PAGE_TARGET.key, PAGE_TARGET);
|
|
12086
|
+
}
|
|
12087
|
+
if (!scopes.has("selected")) {
|
|
12088
|
+
return targets;
|
|
12089
|
+
}
|
|
12090
|
+
const sessionId = this.binding?.getSelectedTarget()?.sessionId ?? null;
|
|
12091
|
+
const selectedTarget = sessionId ? { key: `session:${sessionId}`, sessionId } : PAGE_TARGET;
|
|
12092
|
+
targets.set(selectedTarget.key, selectedTarget);
|
|
12093
|
+
return targets;
|
|
12094
|
+
}
|
|
12095
|
+
async sendCommand(target, method, params = {}) {
|
|
12096
|
+
const session = this.binding?.pageSession;
|
|
12097
|
+
if (!session?.isAttached()) {
|
|
12098
|
+
return false;
|
|
11946
12099
|
}
|
|
11947
12100
|
try {
|
|
11948
|
-
await session.sendAndWait(
|
|
12101
|
+
await session.sendAndWait(method, params, target.sessionId ? { sessionId: target.sessionId } : undefined);
|
|
12102
|
+
return true;
|
|
11949
12103
|
} catch (error) {
|
|
11950
|
-
|
|
12104
|
+
if (!isBenignInterceptionError(error)) {
|
|
12105
|
+
this.onError(error);
|
|
12106
|
+
}
|
|
12107
|
+
return false;
|
|
11951
12108
|
}
|
|
12109
|
+
}
|
|
12110
|
+
}
|
|
12111
|
+
var parsePausedRequest = (params, meta) => {
|
|
12112
|
+
const paused = params;
|
|
12113
|
+
const requestId = paused?.requestId;
|
|
12114
|
+
if (typeof requestId !== "string" || requestId === "") {
|
|
12115
|
+
return null;
|
|
12116
|
+
}
|
|
12117
|
+
return {
|
|
12118
|
+
requestId,
|
|
12119
|
+
url: paused.request?.url ?? "",
|
|
12120
|
+
method: paused.request?.method ?? "GET",
|
|
12121
|
+
resourceType: paused.resourceType ?? "",
|
|
12122
|
+
frameId: paused.frameId ?? null,
|
|
12123
|
+
sessionId: meta.sessionId ?? null,
|
|
12124
|
+
headers: paused.request?.headers ?? {}
|
|
11952
12125
|
};
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
12126
|
+
};
|
|
12127
|
+
var isBenignInterceptionError = (error) => {
|
|
12128
|
+
const code = error?.code;
|
|
12129
|
+
if (code === "cdp_not_attached") {
|
|
12130
|
+
return true;
|
|
12131
|
+
}
|
|
12132
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12133
|
+
return message.includes("Invalid InterceptionId") || message.includes("Inspected target navigated or closed") || message.includes("Session with given id not found") || message.includes("No target with given id");
|
|
12134
|
+
};
|
|
12135
|
+
|
|
12136
|
+
// ../argus-watcher/dist/net/NetMockController.js
|
|
12137
|
+
var createNetMockController = () => {
|
|
12138
|
+
let lastError = null;
|
|
12139
|
+
let nextRuleId = 1;
|
|
12140
|
+
const rules = [];
|
|
12141
|
+
const recordError = (error) => {
|
|
12142
|
+
lastError = { message: error instanceof Error ? error.message : String(error) };
|
|
12143
|
+
const code = error?.code;
|
|
12144
|
+
if (typeof code === "string") {
|
|
12145
|
+
lastError.code = code;
|
|
11957
12146
|
}
|
|
11958
|
-
bound = true;
|
|
11959
|
-
nextSession.onEvent("Fetch.requestPaused", (params) => {
|
|
11960
|
-
handleRequestPaused(params);
|
|
11961
|
-
});
|
|
11962
12147
|
};
|
|
11963
|
-
const
|
|
11964
|
-
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
const
|
|
11970
|
-
const method = paused.request?.method ?? "GET";
|
|
11971
|
-
const resourceType = paused.resourceType ?? "";
|
|
11972
|
-
const rule = rules.find((candidate) => ruleMatches(candidate, url, method, resourceType));
|
|
12148
|
+
const interception = new NetMockInterception((request) => void handleRequestPaused(request), recordError);
|
|
12149
|
+
const bind = (binding) => {
|
|
12150
|
+
interception.bind(binding);
|
|
12151
|
+
interception.reconcile(getActiveScopes(rules));
|
|
12152
|
+
};
|
|
12153
|
+
const handleRequestPaused = async (paused) => {
|
|
12154
|
+
const rule = rules.find((candidate) => interception.matchesScope(candidate.scope ?? "page", paused) && ruleMatches(candidate, paused.url, paused.method, paused.resourceType));
|
|
11973
12155
|
if (!rule) {
|
|
11974
|
-
await sendAction("Fetch.continueRequest", { requestId });
|
|
12156
|
+
await sendAction(paused, "Fetch.continueRequest", { requestId: paused.requestId });
|
|
11975
12157
|
return;
|
|
11976
12158
|
}
|
|
11977
12159
|
rule.hits += 1;
|
|
@@ -11980,53 +12162,41 @@ var createNetMockController = () => {
|
|
|
11980
12162
|
}
|
|
11981
12163
|
const action = rule.action;
|
|
11982
12164
|
if (action.kind === "block") {
|
|
11983
|
-
await sendAction("Fetch.failRequest", { requestId, errorReason: "BlockedByClient" });
|
|
12165
|
+
await sendAction(paused, "Fetch.failRequest", { requestId: paused.requestId, errorReason: "BlockedByClient" });
|
|
11984
12166
|
return;
|
|
11985
12167
|
}
|
|
11986
12168
|
if (action.kind === "fail") {
|
|
11987
|
-
await sendAction("Fetch.failRequest", { requestId, errorReason: action.reason });
|
|
12169
|
+
await sendAction(paused, "Fetch.failRequest", { requestId: paused.requestId, errorReason: action.reason });
|
|
11988
12170
|
return;
|
|
11989
12171
|
}
|
|
11990
12172
|
if (action.kind === "fulfill") {
|
|
11991
|
-
const fulfillParams = { requestId, responseCode: action.status };
|
|
12173
|
+
const fulfillParams = { requestId: paused.requestId, responseCode: action.status };
|
|
11992
12174
|
if (action.headers && action.headers.length > 0) {
|
|
11993
12175
|
fulfillParams.responseHeaders = action.headers;
|
|
11994
12176
|
}
|
|
11995
12177
|
if (action.bodyBase64 != null) {
|
|
11996
12178
|
fulfillParams.body = action.bodyBase64;
|
|
11997
12179
|
}
|
|
11998
|
-
await sendAction("Fetch.fulfillRequest", fulfillParams);
|
|
12180
|
+
await sendAction(paused, "Fetch.fulfillRequest", fulfillParams);
|
|
11999
12181
|
return;
|
|
12000
12182
|
}
|
|
12001
|
-
const continueParams = { requestId };
|
|
12183
|
+
const continueParams = { requestId: paused.requestId };
|
|
12002
12184
|
if (action.rewriteHost) {
|
|
12003
|
-
const rewritten = rewriteUrlHost(url, action.rewriteHost);
|
|
12185
|
+
const rewritten = rewriteUrlHost(paused.url, action.rewriteHost);
|
|
12004
12186
|
if (rewritten) {
|
|
12005
12187
|
continueParams.url = rewritten;
|
|
12006
12188
|
}
|
|
12007
12189
|
}
|
|
12008
12190
|
if (action.setHeaders && action.setHeaders.length > 0) {
|
|
12009
|
-
continueParams.headers = mergeHeaders(paused.
|
|
12010
|
-
}
|
|
12011
|
-
await sendAction("Fetch.continueRequest", continueParams);
|
|
12012
|
-
};
|
|
12013
|
-
const sendAction = async (cdpMethod, params) => {
|
|
12014
|
-
if (!session || !session.isAttached()) {
|
|
12015
|
-
return;
|
|
12016
|
-
}
|
|
12017
|
-
try {
|
|
12018
|
-
await session.sendAndWait(cdpMethod, params);
|
|
12019
|
-
} catch (error) {
|
|
12020
|
-
if (isBenignInterceptionError(error)) {
|
|
12021
|
-
return;
|
|
12022
|
-
}
|
|
12023
|
-
recordError(error);
|
|
12191
|
+
continueParams.headers = mergeHeaders(paused.headers, action.setHeaders);
|
|
12024
12192
|
}
|
|
12193
|
+
await sendAction(paused, "Fetch.continueRequest", continueParams);
|
|
12025
12194
|
};
|
|
12195
|
+
const sendAction = async (request, cdpMethod, params) => interception.sendRequestCommand(request, cdpMethod, params);
|
|
12026
12196
|
const getStatus = (ctx) => ({
|
|
12027
12197
|
ok: true,
|
|
12028
12198
|
attached: ctx.attached,
|
|
12029
|
-
enabled,
|
|
12199
|
+
enabled: interception.enabled,
|
|
12030
12200
|
rules: rules.map(toPublicRule),
|
|
12031
12201
|
lastError
|
|
12032
12202
|
});
|
|
@@ -12034,6 +12204,7 @@ var createNetMockController = () => {
|
|
|
12034
12204
|
lastError = null;
|
|
12035
12205
|
const rule = {
|
|
12036
12206
|
id: nextRuleId++,
|
|
12207
|
+
scope: input.scope ?? "page",
|
|
12037
12208
|
match: input.match,
|
|
12038
12209
|
action: input.action,
|
|
12039
12210
|
delayMs: input.delayMs,
|
|
@@ -12046,7 +12217,7 @@ var createNetMockController = () => {
|
|
|
12046
12217
|
if (!attached) {
|
|
12047
12218
|
return { ok: true, attached: false, enabled: false, rule: toPublicRule(rule) };
|
|
12048
12219
|
}
|
|
12049
|
-
const applied =
|
|
12220
|
+
const applied = await interception.reconcile(getActiveScopes(rules));
|
|
12050
12221
|
return {
|
|
12051
12222
|
ok: true,
|
|
12052
12223
|
attached: true,
|
|
@@ -12062,32 +12233,33 @@ var createNetMockController = () => {
|
|
|
12062
12233
|
rules.splice(index, 1);
|
|
12063
12234
|
}
|
|
12064
12235
|
if (rules.length === 0) {
|
|
12065
|
-
await
|
|
12236
|
+
await interception.reconcile(new Set);
|
|
12237
|
+
} else {
|
|
12238
|
+
await interception.reconcile(getActiveScopes(rules));
|
|
12066
12239
|
}
|
|
12067
|
-
return { ok: true, removed, enabled };
|
|
12240
|
+
return { ok: true, removed, enabled: interception.enabled };
|
|
12068
12241
|
};
|
|
12069
12242
|
const clearRules = async () => {
|
|
12070
12243
|
const removed = rules.length;
|
|
12071
12244
|
rules.length = 0;
|
|
12072
|
-
await
|
|
12073
|
-
return { ok: true, removed, enabled };
|
|
12245
|
+
await interception.reconcile(new Set);
|
|
12246
|
+
return { ok: true, removed, enabled: interception.enabled };
|
|
12074
12247
|
};
|
|
12075
|
-
const onAttach = async (
|
|
12076
|
-
|
|
12077
|
-
enabled = false;
|
|
12078
|
-
if (!hasActiveRules()) {
|
|
12079
|
-
return;
|
|
12080
|
-
}
|
|
12081
|
-
const applied = await enableInterception();
|
|
12248
|
+
const onAttach = async () => {
|
|
12249
|
+
const applied = await interception.reconcile(getActiveScopes(rules), true);
|
|
12082
12250
|
if (!applied && lastError) {
|
|
12083
12251
|
console.warn(`[NetMock] Failed to re-enable interception on attach: ${lastError.message}`);
|
|
12084
12252
|
}
|
|
12085
12253
|
};
|
|
12254
|
+
const onTargetChanged = async () => {
|
|
12255
|
+
await interception.reconcile(getActiveScopes(rules));
|
|
12256
|
+
};
|
|
12086
12257
|
const onDetach = () => {
|
|
12087
|
-
|
|
12258
|
+
interception.onDetach();
|
|
12088
12259
|
};
|
|
12089
|
-
return { bind, getStatus, addRule, removeRule, clearRules, onAttach, onDetach };
|
|
12260
|
+
return { bind, getStatus, addRule, removeRule, clearRules, onAttach, onTargetChanged, onDetach };
|
|
12090
12261
|
};
|
|
12262
|
+
var getActiveScopes = (rules) => new Set(rules.filter(isRuleActive).map((rule) => rule.scope ?? "page"));
|
|
12091
12263
|
var isRuleActive = (rule) => rule.times == null || rule.hits < rule.times;
|
|
12092
12264
|
var ruleMatches = (rule, url, method, resourceType) => {
|
|
12093
12265
|
if (!isRuleActive(rule)) {
|
|
@@ -12131,16 +12303,9 @@ var mergeHeaders = (original, overrides) => {
|
|
|
12131
12303
|
}
|
|
12132
12304
|
return [...merged.values()];
|
|
12133
12305
|
};
|
|
12134
|
-
var isBenignInterceptionError = (error) => {
|
|
12135
|
-
const code = error?.code;
|
|
12136
|
-
if (code === "cdp_not_attached") {
|
|
12137
|
-
return true;
|
|
12138
|
-
}
|
|
12139
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
12140
|
-
return message.includes("Invalid InterceptionId") || message.includes("Inspected target navigated or closed");
|
|
12141
|
-
};
|
|
12142
12306
|
var toPublicRule = (rule) => ({
|
|
12143
12307
|
id: rule.id,
|
|
12308
|
+
scope: rule.scope ?? "page",
|
|
12144
12309
|
match: rule.match,
|
|
12145
12310
|
action: rule.action,
|
|
12146
12311
|
delayMs: rule.delayMs,
|
|
@@ -17053,7 +17218,7 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
17053
17218
|
await emulationController.onAttach(session);
|
|
17054
17219
|
await throttleController.onAttach(session);
|
|
17055
17220
|
await visibilityController.onAttach(sourceHandle.pageSession ?? session);
|
|
17056
|
-
await netMockController.onAttach(
|
|
17221
|
+
await netMockController.onAttach();
|
|
17057
17222
|
await networkCapture?.onAttached();
|
|
17058
17223
|
onIndicatorAttach(session, target);
|
|
17059
17224
|
await maybeInjectOnAttach(session, target);
|
|
@@ -17070,6 +17235,7 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
17070
17235
|
},
|
|
17071
17236
|
reason: null
|
|
17072
17237
|
});
|
|
17238
|
+
netMockController.onTargetChanged();
|
|
17073
17239
|
onIndicatorAttach(session, target);
|
|
17074
17240
|
};
|
|
17075
17241
|
const handleSourceDetach = (reason) => {
|
|
@@ -17097,7 +17263,18 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
17097
17263
|
indicatorController?.setRecording(recording);
|
|
17098
17264
|
}
|
|
17099
17265
|
});
|
|
17100
|
-
netMockController.bind(
|
|
17266
|
+
netMockController.bind({
|
|
17267
|
+
pageSession: sourceHandle.pageSession ?? sourceHandle.session,
|
|
17268
|
+
getSelectedTarget: () => {
|
|
17269
|
+
const context = sourceHandle.getNetFilterContext?.() ?? null;
|
|
17270
|
+
const frameId = context?.selectedFrameId ?? null;
|
|
17271
|
+
return {
|
|
17272
|
+
frameId,
|
|
17273
|
+
topFrameId: context?.topFrameId ?? null,
|
|
17274
|
+
sessionId: frameId ? sourceHandle.getFrameSessionId?.(frameId) ?? null : null
|
|
17275
|
+
};
|
|
17276
|
+
}
|
|
17277
|
+
});
|
|
17101
17278
|
const dialogSession = sourceHandle.pageSession ?? sourceHandle.session;
|
|
17102
17279
|
dialogSession.onEvent("Page.javascriptDialogOpening", (params) => {
|
|
17103
17280
|
const dialog = parseDialogStatus(params);
|
|
@@ -22101,6 +22278,10 @@ var buildAddRequest = async (options, output) => {
|
|
|
22101
22278
|
if (!action) {
|
|
22102
22279
|
return null;
|
|
22103
22280
|
}
|
|
22281
|
+
const scope = resolveMockScope(options, output);
|
|
22282
|
+
if (!scope) {
|
|
22283
|
+
return null;
|
|
22284
|
+
}
|
|
22104
22285
|
const match = { url: urlPattern };
|
|
22105
22286
|
if (options.method) {
|
|
22106
22287
|
match.method = options.method;
|
|
@@ -22108,7 +22289,21 @@ var buildAddRequest = async (options, output) => {
|
|
|
22108
22289
|
if (options.resourceType) {
|
|
22109
22290
|
match.resourceType = options.resourceType;
|
|
22110
22291
|
}
|
|
22111
|
-
return { match, action, delayMs, times };
|
|
22292
|
+
return { scope, match, action, delayMs, times };
|
|
22293
|
+
};
|
|
22294
|
+
var resolveMockScope = (options, output) => {
|
|
22295
|
+
if (options.scope && options.frame) {
|
|
22296
|
+
output.writeWarn("Cannot combine --scope and --frame. Use one or the other.");
|
|
22297
|
+
process.exitCode = 2;
|
|
22298
|
+
return null;
|
|
22299
|
+
}
|
|
22300
|
+
const value = (options.scope ?? options.frame ?? "page").trim().toLowerCase();
|
|
22301
|
+
if (value === "page" || value === "selected") {
|
|
22302
|
+
return value;
|
|
22303
|
+
}
|
|
22304
|
+
output.writeWarn(`Invalid mock scope: ${value}. Expected page or selected.`);
|
|
22305
|
+
process.exitCode = 2;
|
|
22306
|
+
return null;
|
|
22112
22307
|
};
|
|
22113
22308
|
var buildAction = async (options, responseHeaders, requestHeaders, delayMs, output) => {
|
|
22114
22309
|
const invalid = (message) => {
|
|
@@ -22296,6 +22491,9 @@ var describeRule = (rule) => {
|
|
|
22296
22491
|
if (rule.times != null) {
|
|
22297
22492
|
extras.push(`times ${Math.min(rule.hits, rule.times)}/${rule.times}`);
|
|
22298
22493
|
}
|
|
22494
|
+
if (rule.scope === "selected") {
|
|
22495
|
+
extras.push("scope selected");
|
|
22496
|
+
}
|
|
22299
22497
|
extras.push(`hits ${rule.hits}`);
|
|
22300
22498
|
return `#${rule.id} ${match} → ${describeAction(rule.action)} [${extras.join(", ")}]`;
|
|
22301
22499
|
};
|
|
@@ -22415,6 +22613,8 @@ var netMockCommand = {
|
|
|
22415
22613
|
{ flags: "--url <pattern>", description: "URL wildcard pattern; substring match when it contains no *" },
|
|
22416
22614
|
{ flags: "--method <method>", description: "Only match this HTTP method" },
|
|
22417
22615
|
{ flags: "--resource-type <type>", description: "Only match this CDP resource type (Fetch, XHR, Document, ...)" },
|
|
22616
|
+
{ flags: "--scope <scope>", description: "Intercept the top-level page or currently selected target (page|selected)" },
|
|
22617
|
+
{ flags: "--frame <frame>", description: "Alias for --scope; accepts page or selected" },
|
|
22418
22618
|
{ flags: "--block", description: "Abort matching requests as BlockedByClient" },
|
|
22419
22619
|
{ flags: "--fail <reason>", description: "Abort with a network error (TimedOut, ConnectionRefused, ...)" },
|
|
22420
22620
|
{ flags: "--status <code>", description: "Stub a response with this HTTP status (default 200 when a body is given)" },
|
|
@@ -22441,12 +22641,13 @@ var netMockCommand = {
|
|
|
22441
22641
|
'argus net mock add app --url "*/analytics/*" --block',
|
|
22442
22642
|
'argus net mock add app --url "*/api/save" --fail ConnectionRefused --times 1',
|
|
22443
22643
|
'argus net mock add app --url "*/api/config" --status 200 --body-file ./fixtures/config.json',
|
|
22644
|
+
'argus net mock add extension --scope selected --url "*/api/config" --status 200 --body-file ./fixtures/config.json',
|
|
22444
22645
|
`argus net mock add app --url "*/game/init" --status 500 --body '{"error":"maintenance"}'`,
|
|
22445
22646
|
'argus net mock add app --url "*/api/*" --delay 2s --method POST',
|
|
22446
22647
|
'argus net mock add app --url "cdn.prod.com" --rewrite-host localhost:3000'
|
|
22447
22648
|
],
|
|
22448
22649
|
action: async (id, options) => {
|
|
22449
|
-
await runNetMockAdd(id, options);
|
|
22650
|
+
await runNetMockAdd(id, resolveNetMockAddOptions(options));
|
|
22450
22651
|
}
|
|
22451
22652
|
},
|
|
22452
22653
|
{
|
|
@@ -22457,7 +22658,7 @@ var netMockCommand = {
|
|
|
22457
22658
|
options: [jsonOption],
|
|
22458
22659
|
examples: ["argus net mock ls app", "argus net mock ls app --json"],
|
|
22459
22660
|
action: async (id, options) => {
|
|
22460
|
-
await runNetMockList(id, options);
|
|
22661
|
+
await runNetMockList(id, resolveCommandOptions(options));
|
|
22461
22662
|
}
|
|
22462
22663
|
},
|
|
22463
22664
|
{
|
|
@@ -22471,7 +22672,7 @@ var netMockCommand = {
|
|
|
22471
22672
|
options: [jsonOption],
|
|
22472
22673
|
examples: ["argus net mock rm 2 app", "argus net mock rm 2 app --json"],
|
|
22473
22674
|
action: async (rule, id, options) => {
|
|
22474
|
-
await runNetMockRemove(id, rule, options);
|
|
22675
|
+
await runNetMockRemove(id, rule, resolveCommandOptions(options));
|
|
22475
22676
|
}
|
|
22476
22677
|
},
|
|
22477
22678
|
{
|
|
@@ -22481,7 +22682,7 @@ var netMockCommand = {
|
|
|
22481
22682
|
options: [jsonOption],
|
|
22482
22683
|
examples: ["argus net mock clear app", "argus net mock clear app --json"],
|
|
22483
22684
|
action: async (id, options) => {
|
|
22484
|
-
await runNetMockClear(id, options);
|
|
22685
|
+
await runNetMockClear(id, resolveCommandOptions(options));
|
|
22485
22686
|
}
|
|
22486
22687
|
}
|
|
22487
22688
|
]
|
|
@@ -22704,8 +22905,8 @@ Examples:
|
|
|
22704
22905
|
]
|
|
22705
22906
|
}
|
|
22706
22907
|
];
|
|
22707
|
-
var resolveCommandOptions = (value) => {
|
|
22708
|
-
const fallback = parseNetArgv(
|
|
22908
|
+
var resolveCommandOptions = (value, argv = process.argv.slice(2)) => {
|
|
22909
|
+
const fallback = parseNetArgv(argv);
|
|
22709
22910
|
if (value && typeof value === "object" && "opts" in value && typeof value.opts === "function") {
|
|
22710
22911
|
return {
|
|
22711
22912
|
...value.opts(),
|
|
@@ -22717,6 +22918,16 @@ var resolveCommandOptions = (value) => {
|
|
|
22717
22918
|
...fallback
|
|
22718
22919
|
};
|
|
22719
22920
|
};
|
|
22921
|
+
var resolveNetMockAddOptions = (value, argv = process.argv.slice(2)) => {
|
|
22922
|
+
const resolved = resolveCommandOptions(value, argv);
|
|
22923
|
+
for (const key of ["method", "status", "resourceType"]) {
|
|
22924
|
+
const option = resolved[key];
|
|
22925
|
+
if (Array.isArray(option)) {
|
|
22926
|
+
resolved[key] = option.at(-1);
|
|
22927
|
+
}
|
|
22928
|
+
}
|
|
22929
|
+
return resolved;
|
|
22930
|
+
};
|
|
22720
22931
|
var parseNetArgv = (argv) => {
|
|
22721
22932
|
const parsed = {};
|
|
22722
22933
|
const readValue = (flag) => {
|
|
@@ -47417,10 +47628,34 @@ var domCommands = [
|
|
|
47417
47628
|
];
|
|
47418
47629
|
|
|
47419
47630
|
// dist/commands/domKeydown.js
|
|
47631
|
+
var normalizeOptionalString2 = (value) => {
|
|
47632
|
+
const normalized = value?.trim();
|
|
47633
|
+
return normalized ? normalized : undefined;
|
|
47634
|
+
};
|
|
47635
|
+
var mergeModifierOptions = (options) => {
|
|
47636
|
+
const modifiers = new Set;
|
|
47637
|
+
for (const part of (options.modifiers ?? "").split(",")) {
|
|
47638
|
+
const name = part.trim().toLowerCase();
|
|
47639
|
+
if (name) {
|
|
47640
|
+
modifiers.add(name);
|
|
47641
|
+
}
|
|
47642
|
+
}
|
|
47643
|
+
if (options.shift)
|
|
47644
|
+
modifiers.add("shift");
|
|
47645
|
+
if (options.ctrl)
|
|
47646
|
+
modifiers.add("ctrl");
|
|
47647
|
+
if (options.alt)
|
|
47648
|
+
modifiers.add("alt");
|
|
47649
|
+
if (options.meta || options.cmd)
|
|
47650
|
+
modifiers.add("meta");
|
|
47651
|
+
return modifiers.size > 0 ? Array.from(modifiers).join(",") : undefined;
|
|
47652
|
+
};
|
|
47420
47653
|
var runDomKeydown = defineWatcherCommand({
|
|
47421
47654
|
build: (_args, options, output) => {
|
|
47422
|
-
|
|
47423
|
-
|
|
47655
|
+
const key = normalizeOptionalString2(options.key);
|
|
47656
|
+
const code = normalizeOptionalString2(options.code);
|
|
47657
|
+
if (!key && !code) {
|
|
47658
|
+
output.writeWarn("--key or --code is required");
|
|
47424
47659
|
process.exitCode = 2;
|
|
47425
47660
|
return null;
|
|
47426
47661
|
}
|
|
@@ -47428,15 +47663,20 @@ var runDomKeydown = defineWatcherCommand({
|
|
|
47428
47663
|
path: "/dom/keydown",
|
|
47429
47664
|
method: "POST",
|
|
47430
47665
|
body: {
|
|
47431
|
-
key
|
|
47666
|
+
key,
|
|
47667
|
+
code,
|
|
47432
47668
|
selector: options.selector,
|
|
47433
|
-
modifiers: options
|
|
47669
|
+
modifiers: mergeModifierOptions(options)
|
|
47434
47670
|
},
|
|
47435
47671
|
timeoutMs: 30000
|
|
47436
47672
|
};
|
|
47437
47673
|
},
|
|
47438
|
-
formatHuman: (response, { output }) => {
|
|
47439
|
-
|
|
47674
|
+
formatHuman: (response, { options, output }) => {
|
|
47675
|
+
if (options.printEvent) {
|
|
47676
|
+
output.writeHuman(`Dispatched keydown event: ${JSON.stringify(response.event)}`);
|
|
47677
|
+
return;
|
|
47678
|
+
}
|
|
47679
|
+
output.writeHuman(`Dispatched keydown: ${response.key} (code=${response.code})`);
|
|
47440
47680
|
}
|
|
47441
47681
|
});
|
|
47442
47682
|
|
|
@@ -47446,13 +47686,26 @@ var keydownCommand = {
|
|
|
47446
47686
|
description: "Dispatch a keyboard event to the connected page",
|
|
47447
47687
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
47448
47688
|
options: [
|
|
47449
|
-
{ flags: "--key <name>", description: "
|
|
47689
|
+
{ flags: "--key <name>", description: "KeyboardEvent.key value (e.g. Enter, a, ArrowUp)" },
|
|
47690
|
+
{ flags: "--code <code>", description: "KeyboardEvent.code value (e.g. KeyG, Digit1)" },
|
|
47450
47691
|
{ flags: "--selector <css>", description: "Focus element before dispatching" },
|
|
47451
47692
|
{ flags: "--testid <id>", description: `Shorthand for --selector "[data-testid='<id>']"` },
|
|
47452
47693
|
{ flags: "--modifiers <list>", description: "Comma-separated modifiers: shift,ctrl,alt,meta" },
|
|
47694
|
+
{ flags: "--shift", description: "Shortcut for --modifiers shift" },
|
|
47695
|
+
{ flags: "--ctrl", description: "Shortcut for --modifiers ctrl" },
|
|
47696
|
+
{ flags: "--alt", description: "Shortcut for --modifiers alt" },
|
|
47697
|
+
{ flags: "--meta", description: "Shortcut for --modifiers meta" },
|
|
47698
|
+
{ flags: "--cmd", description: "Alias for --meta" },
|
|
47699
|
+
{ flags: "--print-event", description: "Print resolved key/code/modifier event details" },
|
|
47453
47700
|
{ flags: "--json", description: "Output JSON for automation" }
|
|
47454
47701
|
],
|
|
47455
|
-
examples: [
|
|
47702
|
+
examples: [
|
|
47703
|
+
"argus keydown app --key Enter",
|
|
47704
|
+
"argus keydown app --key G",
|
|
47705
|
+
"argus keydown app --code KeyG",
|
|
47706
|
+
'argus keydown app --key a --selector "#input"',
|
|
47707
|
+
"argus keydown app --key a --shift --ctrl"
|
|
47708
|
+
],
|
|
47456
47709
|
action: async (id, options) => {
|
|
47457
47710
|
if (!resolveTestId(options))
|
|
47458
47711
|
return;
|
|
@@ -48715,7 +48968,7 @@ var extractPlugin = (mod) => {
|
|
|
48715
48968
|
return null;
|
|
48716
48969
|
return plugin;
|
|
48717
48970
|
};
|
|
48718
|
-
var
|
|
48971
|
+
var normalizeOptionalString3 = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
48719
48972
|
var normalizeCommands = (value) => {
|
|
48720
48973
|
if (!Array.isArray(value))
|
|
48721
48974
|
return [];
|
|
@@ -48737,11 +48990,11 @@ var createLoadedEntry = (entry, plugin, url) => ({
|
|
|
48737
48990
|
alias: entry.alias,
|
|
48738
48991
|
status: "loaded",
|
|
48739
48992
|
name: plugin.name,
|
|
48740
|
-
version:
|
|
48741
|
-
description:
|
|
48993
|
+
version: normalizeOptionalString3(plugin.version),
|
|
48994
|
+
description: normalizeOptionalString3(plugin.description),
|
|
48742
48995
|
commands: normalizeCommands(plugin.commands),
|
|
48743
|
-
homepage:
|
|
48744
|
-
minArgusVersion:
|
|
48996
|
+
homepage: normalizeOptionalString3(plugin.homepage),
|
|
48997
|
+
minArgusVersion: normalizeOptionalString3(plugin.minArgusVersion),
|
|
48745
48998
|
url
|
|
48746
48999
|
});
|
|
48747
49000
|
var registerPlugins = async (program2, argv = process.argv.slice(2)) => {
|