browser-debugger-cli 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/cdp/schema.d.ts +4 -1
- package/dist/cdp/schema.js +48 -7
- package/dist/commands/cdp.js +3 -2
- package/dist/commands/cleanup.d.ts +11 -0
- package/dist/commands/cleanup.js +161 -57
- package/dist/commands/console.d.ts +20 -1
- package/dist/commands/console.js +57 -17
- package/dist/commands/details.js +3 -2
- package/dist/commands/dom/DomElementResolver.d.ts +10 -3
- package/dist/commands/dom/DomElementResolver.js +35 -17
- package/dist/commands/dom/a11y.d.ts +10 -0
- package/dist/commands/dom/a11y.js +27 -5
- package/dist/commands/dom/eval.d.ts +3 -1
- package/dist/commands/dom/eval.js +29 -4
- package/dist/commands/dom/form.js +16 -62
- package/dist/commands/dom/formInteraction.js +152 -113
- package/dist/commands/dom/formSummary.d.ts +49 -0
- package/dist/commands/dom/formSummary.js +180 -0
- package/dist/commands/dom/frames.d.ts +2 -1
- package/dist/commands/dom/frames.js +17 -2
- package/dist/commands/dom/get.d.ts +6 -5
- package/dist/commands/dom/get.js +92 -82
- package/dist/commands/dom/helpers/index.d.ts +1 -1
- package/dist/commands/dom/helpers/index.js +1 -1
- package/dist/commands/dom/helpers/query.d.ts +44 -17
- package/dist/commands/dom/helpers/query.js +244 -97
- package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
- package/dist/commands/dom/helpers/runElementCommand.js +97 -30
- package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
- package/dist/commands/dom/helpers/screenshot.js +164 -49
- package/dist/commands/dom/index.d.ts +3 -1
- package/dist/commands/dom/index.js +16 -6
- package/dist/commands/dom/layout.d.ts +14 -0
- package/dist/commands/dom/layout.js +54 -0
- package/dist/commands/dom/listeners.d.ts +5 -1
- package/dist/commands/dom/listeners.js +13 -3
- package/dist/commands/dom/query.js +2 -3
- package/dist/commands/dom/screenshot.d.ts +12 -2
- package/dist/commands/dom/screenshot.js +27 -3
- package/dist/commands/dom/semanticUtils.d.ts +6 -13
- package/dist/commands/dom/semanticUtils.js +15 -19
- package/dist/commands/dom/wait.d.ts +13 -0
- package/dist/commands/dom/wait.js +83 -0
- package/dist/commands/helpJson.js +2 -2
- package/dist/commands/network/list.js +4 -11
- package/dist/commands/optionBehaviors.js +112 -21
- package/dist/commands/page.d.ts +2 -1
- package/dist/commands/page.js +41 -5
- package/dist/commands/peek.js +4 -11
- package/dist/commands/sessions.d.ts +8 -0
- package/dist/commands/sessions.js +19 -0
- package/dist/commands/shared/CommandRunner.js +4 -4
- package/dist/commands/shared/dataFetcher.js +2 -2
- package/dist/commands/shared/followMode.d.ts +21 -1
- package/dist/commands/shared/followMode.js +29 -2
- package/dist/commands/shared/handleValidationError.d.ts +2 -2
- package/dist/commands/shared/handleValidationError.js +12 -3
- package/dist/commands/shared/optionTypes.d.ts +40 -5
- package/dist/commands/shared/startHelpers.js +12 -3
- package/dist/commands/shared/validation.d.ts +3 -2
- package/dist/commands/shared/validation.js +4 -3
- package/dist/commands/start.d.ts +63 -0
- package/dist/commands/start.js +115 -15
- package/dist/commands/status.js +29 -7
- package/dist/commands/stop.js +7 -6
- package/dist/commands/tail.js +4 -11
- package/dist/commands/types.d.ts +2 -0
- package/dist/commands.js +2 -0
- package/dist/connection/chromeIdentity.d.ts +65 -0
- package/dist/connection/chromeIdentity.js +143 -0
- package/dist/connection/launcher/profilePreferences.d.ts +47 -0
- package/dist/connection/launcher/profilePreferences.js +151 -0
- package/dist/connection/launcher.d.ts +21 -2
- package/dist/connection/launcher.js +42 -16
- package/dist/connection/portReservation.d.ts +14 -4
- package/dist/connection/portReservation.js +21 -6
- package/dist/connection/startupExit.d.ts +8 -0
- package/dist/connection/startupExit.js +15 -6
- package/dist/constants.d.ts +6 -2
- package/dist/constants.js +9 -2
- package/dist/daemon/SessionController.js +23 -7
- package/dist/daemon/errors.d.ts +1 -1
- package/dist/daemon/errors.js +1 -1
- package/dist/daemon/launcher.d.ts +2 -1
- package/dist/daemon/launcher.js +5 -6
- package/dist/daemon/server/SocketServer.js +1 -2
- package/dist/daemon/session/Session.d.ts +13 -0
- package/dist/daemon/session/Session.js +57 -8
- package/dist/daemon/session/chromeConnection.d.ts +9 -0
- package/dist/daemon/session/chromeConnection.js +45 -8
- package/dist/daemon/session/commandRegistry.js +52 -62
- package/dist/daemon/session/interactions.d.ts +35 -9
- package/dist/daemon/session/interactions.js +36 -9
- package/dist/daemon/session/triggeredRequests.d.ts +67 -0
- package/dist/daemon/session/triggeredRequests.js +157 -0
- package/dist/daemon/session/types.d.ts +5 -1
- package/dist/daemon.js +5393 -1600
- package/dist/errors/messages.d.ts +387 -24
- package/dist/errors/messages.js +761 -67
- package/dist/index.js +3976 -1558
- package/dist/ipc/client.d.ts +12 -1
- package/dist/ipc/client.js +22 -3
- package/dist/ipc/protocol/commands.d.ts +89 -4
- package/dist/ipc/protocol/commands.js +2 -0
- package/dist/ipc/protocol/domTypes.d.ts +258 -7
- package/dist/ipc/session/lifecycle.d.ts +8 -1
- package/dist/ipc/session/queries.d.ts +5 -1
- package/dist/ipc/session/types.d.ts +5 -0
- package/dist/ipc/transport/index.d.ts +2 -1
- package/dist/ipc/transport/index.js +2 -2
- package/dist/runtime/dom/actionEffects.d.ts +106 -0
- package/dist/runtime/dom/actionEffects.js +256 -0
- package/dist/runtime/dom/actionEffectsScripts.d.ts +52 -0
- package/dist/runtime/dom/actionEffectsScripts.js +234 -0
- package/dist/runtime/dom/elementGeometry.d.ts +170 -0
- package/dist/runtime/dom/elementGeometry.js +553 -0
- package/dist/runtime/dom/elementInfo.d.ts +77 -0
- package/dist/runtime/dom/elementInfo.js +191 -0
- package/dist/runtime/dom/evalHelpers.d.ts +51 -6
- package/dist/runtime/dom/evalHelpers.js +136 -26
- package/dist/runtime/dom/eventListeners.d.ts +2 -1
- package/dist/runtime/dom/eventListeners.js +174 -47
- package/dist/runtime/dom/formDiscovery.d.ts +1 -1
- package/dist/runtime/dom/formDiscovery.js +116 -16
- package/dist/runtime/dom/formFillHelpers/fill.d.ts +10 -0
- package/dist/runtime/dom/formFillHelpers/fill.js +125 -10
- package/dist/runtime/dom/formFillHelpers/index.d.ts +2 -2
- package/dist/runtime/dom/formFillHelpers/index.js +2 -2
- package/dist/runtime/dom/formFillHelpers/pressKey.js +14 -3
- package/dist/runtime/dom/formFillHelpers/scroll.d.ts +3 -0
- package/dist/runtime/dom/formFillHelpers/scroll.js +60 -18
- package/dist/runtime/dom/formFillHelpers/shared.d.ts +17 -0
- package/dist/runtime/dom/formFillHelpers/shared.js +25 -1
- package/dist/runtime/dom/formFillHelpers/stability.d.ts +20 -6
- package/dist/runtime/dom/formFillHelpers/stability.js +50 -19
- package/dist/runtime/dom/formSubmitHelpers.d.ts +3 -0
- package/dist/runtime/dom/formSubmitHelpers.js +89 -15
- package/dist/runtime/dom/frameLayout.d.ts +60 -0
- package/dist/runtime/dom/frameLayout.js +140 -0
- package/dist/runtime/dom/frameOrigin.d.ts +50 -0
- package/dist/runtime/dom/frameOrigin.js +62 -0
- package/dist/runtime/dom/frameScopedConnection.d.ts +92 -0
- package/dist/runtime/dom/frameScopedConnection.js +252 -0
- package/dist/runtime/dom/frameSelection.d.ts +1 -1
- package/dist/runtime/dom/frameSelection.js +2 -2
- package/dist/runtime/dom/frames.d.ts +25 -2
- package/dist/runtime/dom/frames.js +202 -63
- package/dist/runtime/dom/layout.d.ts +67 -0
- package/dist/runtime/dom/layout.js +333 -0
- package/dist/runtime/dom/listenerPageScripts.d.ts +66 -0
- package/dist/runtime/dom/listenerPageScripts.js +279 -0
- package/dist/runtime/dom/listenerSummary.d.ts +132 -11
- package/dist/runtime/dom/listenerSummary.js +344 -22
- package/dist/runtime/dom/pageActivity.d.ts +41 -0
- package/dist/runtime/dom/pageActivity.js +123 -0
- package/dist/runtime/dom/reactEventHelpers.d.ts +58 -2
- package/dist/runtime/dom/reactEventHelpers.js +212 -41
- package/dist/runtime/dom/targetNode.d.ts +80 -27
- package/dist/runtime/dom/targetNode.js +249 -33
- package/dist/runtime/dom/wait.d.ts +25 -0
- package/dist/runtime/dom/wait.js +199 -0
- package/dist/runtime/dom/waitCondition.d.ts +71 -0
- package/dist/runtime/dom/waitCondition.js +75 -0
- package/dist/runtime/page/emulation.d.ts +51 -0
- package/dist/runtime/page/emulation.js +80 -0
- package/dist/runtime/page/loadingState.d.ts +36 -0
- package/dist/runtime/page/loadingState.js +86 -0
- package/dist/runtime/page/navigation.d.ts +46 -2
- package/dist/runtime/page/navigation.js +69 -33
- package/dist/session/QueryCacheManager.d.ts +11 -1
- package/dist/session/QueryCacheManager.js +25 -3
- package/dist/session/chromeOwners.d.ts +34 -0
- package/dist/session/chromeOwners.js +51 -0
- package/dist/session/cleanup/staleSession.d.ts +11 -1
- package/dist/session/cleanup/staleSession.js +17 -6
- package/dist/session/cleanup/userCommands.js +2 -4
- package/dist/session/metadata.d.ts +5 -1
- package/dist/session/metadata.js +2 -1
- package/dist/session/paths.d.ts +77 -3
- package/dist/session/paths.js +111 -5
- package/dist/session/port.d.ts +31 -7
- package/dist/session/port.js +50 -43
- package/dist/session/portClaims.d.ts +66 -0
- package/dist/session/portClaims.js +284 -0
- package/dist/session/sessionList.d.ts +58 -0
- package/dist/session/sessionList.js +199 -0
- package/dist/session/sessionName.d.ts +46 -0
- package/dist/session/sessionName.js +97 -0
- package/dist/telemetry/a11y.d.ts +8 -3
- package/dist/telemetry/a11y.js +92 -28
- package/dist/telemetry/requestKinds.d.ts +32 -0
- package/dist/telemetry/requestKinds.js +61 -0
- package/dist/telemetry/requestState.d.ts +31 -0
- package/dist/telemetry/requestState.js +38 -0
- package/dist/types.d.ts +80 -3
- package/dist/ui/formatters/a11y.js +3 -0
- package/dist/ui/formatters/console/chronological.d.ts +8 -0
- package/dist/ui/formatters/console/chronological.js +17 -4
- package/dist/ui/formatters/console/json.js +3 -4
- package/dist/ui/formatters/console/shared.d.ts +12 -0
- package/dist/ui/formatters/console.d.ts +2 -2
- package/dist/ui/formatters/console.js +1 -1
- package/dist/ui/formatters/details.js +2 -1
- package/dist/ui/formatters/dom.d.ts +26 -14
- package/dist/ui/formatters/dom.js +65 -52
- package/dist/ui/formatters/form.js +29 -18
- package/dist/ui/formatters/layout.d.ts +31 -0
- package/dist/ui/formatters/layout.js +53 -0
- package/dist/ui/formatters/listeners.d.ts +3 -2
- package/dist/ui/formatters/listeners.js +73 -9
- package/dist/ui/formatters/networkHeaders.js +13 -0
- package/dist/ui/formatters/preview.js +2 -1
- package/dist/ui/formatters/requestStatus.d.ts +1 -17
- package/dist/ui/formatters/requestStatus.js +2 -30
- package/dist/ui/formatters/sessions.d.ts +12 -0
- package/dist/ui/formatters/sessions.js +40 -0
- package/dist/ui/formatters/status.d.ts +21 -2
- package/dist/ui/formatters/status.js +47 -10
- package/dist/ui/formatters/triggeredRequests.d.ts +36 -0
- package/dist/ui/formatters/triggeredRequests.js +65 -0
- package/dist/ui/formatting.d.ts +10 -0
- package/dist/ui/formatting.js +28 -36
- package/dist/ui/messages/chrome.d.ts +9 -0
- package/dist/ui/messages/chrome.js +17 -5
- package/dist/ui/messages/commands.d.ts +388 -14
- package/dist/ui/messages/commands.js +664 -21
- package/dist/ui/messages/consoleMessages.d.ts +10 -0
- package/dist/ui/messages/consoleMessages.js +17 -0
- package/dist/ui/messages/hints.js +2 -1
- package/dist/ui/messages/preview.js +5 -4
- package/dist/ui/messages/session.d.ts +16 -21
- package/dist/ui/messages/session.js +28 -26
- package/dist/ui/messages/sessionCommand.d.ts +43 -0
- package/dist/ui/messages/sessionCommand.js +52 -0
- package/dist/utils/async.d.ts +8 -0
- package/dist/utils/async.js +19 -0
- package/dist/utils/http.d.ts +22 -1
- package/dist/utils/http.js +28 -9
- package/dist/utils/selectorFilters.d.ts +36 -8
- package/dist/utils/selectorFilters.js +267 -53
- package/dist/utils/shellDetection.d.ts +8 -2
- package/dist/utils/shellDetection.js +120 -33
- package/dist/utils/suggestions.d.ts +26 -0
- package/dist/utils/suggestions.js +73 -0
- package/dist/utils/taskMappings.js +10 -0
- package/dist/utils/url.d.ts +12 -2
- package/dist/utils/url.js +69 -7
- package/package.json +1 -1
- package/dist/ui/formatters/sessionFormatters.d.ts +0 -58
- package/dist/ui/formatters/sessionFormatters.js +0 -121
|
@@ -10,18 +10,21 @@
|
|
|
10
10
|
* roots and same-origin iframes, like a user sees the page.
|
|
11
11
|
*/
|
|
12
12
|
import { CommandError } from '../../../errors/index.js';
|
|
13
|
-
import { noNodesFoundError, indexOutOfRangeError, eitherArgumentRequiredError, invalidSelectorError, nodeIdNotFoundError, staleNodeError, } from '../../../errors/messages.js';
|
|
13
|
+
import { noNodesFoundError, indexOutOfRangeError, eitherArgumentRequiredError, invalidSelectorError, nodeIdNotFoundError, operationFailedError, similarSelectorsLine, staleNodeError, } from '../../../errors/messages.js';
|
|
14
14
|
import { callCDP } from '../../../ipc/client.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import { ELEMENT_GEOMETRY_JS, VIEWPORT_SIZE_JS, classifyViewportPosition, } from '../../../runtime/dom/elementGeometry.js';
|
|
16
|
+
import { ELEMENT_CONTEXT_JS, ELEMENT_TEXT_JS, ELEMENT_TEXT_LENGTH, textPreview, } from '../../../runtime/dom/elementInfo.js';
|
|
17
|
+
import { DEEP_QUERY_JS, UNSEARCHED_CONTENT_JS, pageNamesJS, selectorArgsJS, } from '../../../runtime/dom/targetNode.js';
|
|
17
18
|
import { createLogger } from '../../../ui/logging/index.js';
|
|
19
|
+
import { sessionCommand } from '../../../ui/messages/sessionCommand.js';
|
|
18
20
|
import { ConcurrencyLimiter } from '../../../utils/concurrency.js';
|
|
21
|
+
import { getErrorMessage } from '../../../utils/errors.js';
|
|
19
22
|
import { EXIT_CODES } from '../../../utils/exitCodes.js';
|
|
23
|
+
import { parseSelectorFilters, withoutVisibleFilters } from '../../../utils/selectorFilters.js';
|
|
24
|
+
import { findSimilarNames, parseSingleNameSelector } from '../../../utils/suggestions.js';
|
|
20
25
|
const log = createLogger('dom');
|
|
21
26
|
/** Maximum concurrent CDP calls to avoid overwhelming the connection. */
|
|
22
27
|
const CDP_CONCURRENCY_LIMIT = 10;
|
|
23
|
-
/** Length of the text preview shown for queried elements. */
|
|
24
|
-
const PREVIEW_LENGTH = 80;
|
|
25
28
|
/**
|
|
26
29
|
* Convert CDP's flat attribute list to a record.
|
|
27
30
|
*
|
|
@@ -63,33 +66,6 @@ async function getOuterHTML(ref) {
|
|
|
63
66
|
const response = await callCDP('DOM.getOuterHTML', ref);
|
|
64
67
|
return response.data?.result?.outerHTML;
|
|
65
68
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Page-side text of an element as a user sees it: `innerText` for a rendered
|
|
68
|
-
* element (CSS-hidden parts left out, inline elements not split apart), none
|
|
69
|
-
* for an element that is not rendered, `textContent` for SVG and other
|
|
70
|
-
* elements without `innerText` and for `display: contents` wrappers (no box
|
|
71
|
-
* of their own, but their children are shown).
|
|
72
|
-
*/
|
|
73
|
-
const ELEMENT_TEXT_JS = `(el) => {
|
|
74
|
-
if (typeof el.innerText !== 'string') return el.textContent || '';
|
|
75
|
-
if (!el.checkVisibility || el.checkVisibility()) return el.innerText;
|
|
76
|
-
const boxless = el.ownerDocument.defaultView.getComputedStyle(el).display === 'contents';
|
|
77
|
-
return boxless ? el.textContent || '' : '';
|
|
78
|
-
}`;
|
|
79
|
-
/**
|
|
80
|
-
* Short text preview of an element's text: whitespace collapsed, cut on a
|
|
81
|
-
* whole character (an emoji is never split, which would make JSON invalid).
|
|
82
|
-
*
|
|
83
|
-
* @param text - Element text as the page renders it
|
|
84
|
-
* @returns Collapsed text, truncated to {@link PREVIEW_LENGTH} characters
|
|
85
|
-
*/
|
|
86
|
-
export function textPreview(text) {
|
|
87
|
-
const collapsed = text.replace(/\s+/g, ' ').trim();
|
|
88
|
-
const characters = Array.from(collapsed);
|
|
89
|
-
return characters.length > PREVIEW_LENGTH
|
|
90
|
-
? characters.slice(0, PREVIEW_LENGTH).join('') + '...'
|
|
91
|
-
: collapsed;
|
|
92
|
-
}
|
|
93
69
|
/** Counter giving each query its own object group (queries may run concurrently) */
|
|
94
70
|
let queryCount = 0;
|
|
95
71
|
/**
|
|
@@ -126,53 +102,168 @@ async function withSelection(selector, use) {
|
|
|
126
102
|
await callCDP('Runtime.releaseObjectGroup', { objectGroup });
|
|
127
103
|
}
|
|
128
104
|
}
|
|
129
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* The "no nodes" error for a selector that matched nothing. One more page
|
|
107
|
+
* evaluation, on this failure path only, tells what the page says about it
|
|
108
|
+
* ({@link noMatchContext}).
|
|
109
|
+
*
|
|
110
|
+
* @param selector - Selector as given
|
|
111
|
+
* @returns Message and suggestion
|
|
112
|
+
*/
|
|
113
|
+
export async function noMatchesError(selector) {
|
|
114
|
+
return noNodesFoundError(selector, await noMatchContext(selector));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* What the page says about a selector that matched nothing, in one
|
|
118
|
+
* evaluation: whether it is still loading, how many elements match with the
|
|
119
|
+
* selector's `:visible` filters removed, whether it has cross-origin iframes
|
|
120
|
+
* or embeds (which selectors do not search), and for a selector that is a
|
|
121
|
+
* single id or class, the similar ids or classes on the page.
|
|
122
|
+
*
|
|
123
|
+
* @param selector - Selector as given
|
|
124
|
+
* @returns Context for {@link noNodesFoundError} (empty when the page did not answer)
|
|
125
|
+
*/
|
|
126
|
+
export async function noMatchContext(selector) {
|
|
127
|
+
const parts = parseSelectorFilters(selector);
|
|
128
|
+
const unfiltered = parts && withoutVisibleFilters(parts);
|
|
129
|
+
const single = parseSingleNameSelector(selector);
|
|
130
|
+
const hidden = unfiltered
|
|
131
|
+
? `(() => { try { return (${DEEP_QUERY_JS})(${JSON.stringify(selector)}, ${JSON.stringify(unfiltered)}).length; } catch (e) { return 0; } })()`
|
|
132
|
+
: '0';
|
|
133
|
+
const names = single ? pageNamesJS(single.kind) : '[]';
|
|
134
|
+
try {
|
|
135
|
+
const evaluated = await callCDP('Runtime.evaluate', {
|
|
136
|
+
expression: `({ hidden: ${hidden}, readyState: document.readyState, unsearched: ${UNSEARCHED_CONTENT_JS}, names: ${names} })`,
|
|
137
|
+
returnByValue: true,
|
|
138
|
+
});
|
|
139
|
+
const { result } = (evaluated.data?.result ?? {});
|
|
140
|
+
const value = (result?.value ?? {});
|
|
141
|
+
const similar = single && Array.isArray(value.names)
|
|
142
|
+
? similarSelectorsLine(single.kind, findSimilarNames(single.name, value.names.filter((n) => typeof n === 'string')))
|
|
143
|
+
: '';
|
|
144
|
+
return {
|
|
145
|
+
hidden: typeof value.hidden === 'number' ? value.hidden : 0,
|
|
146
|
+
...(typeof value.readyState === 'string' && { readyState: value.readyState }),
|
|
147
|
+
...(value.unsearched && {
|
|
148
|
+
unsearched: {
|
|
149
|
+
crossOriginFrames: value.unsearched.crossOriginFrames === true,
|
|
150
|
+
embeds: value.unsearched.embeds === true,
|
|
151
|
+
},
|
|
152
|
+
}),
|
|
153
|
+
...(similar && { similar }),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
log.debug(`Could not read the page after no match: ${getErrorMessage(error)}`);
|
|
158
|
+
return {};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The page's `document.readyState`, read for a failure that may come from a
|
|
163
|
+
* page still loading.
|
|
164
|
+
*
|
|
165
|
+
* @returns The state, or undefined when the page did not answer
|
|
166
|
+
*/
|
|
167
|
+
export async function documentReadyState() {
|
|
168
|
+
try {
|
|
169
|
+
const evaluated = await callCDP('Runtime.evaluate', {
|
|
170
|
+
expression: 'document.readyState',
|
|
171
|
+
returnByValue: true,
|
|
172
|
+
});
|
|
173
|
+
const { result } = (evaluated.data?.result ?? {});
|
|
174
|
+
return typeof result?.value === 'string' ? result.value : undefined;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
log.debug(`Could not read document.readyState: ${getErrorMessage(error)}`);
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Matches whose viewport position `dom query` reports (measuring is not free) */
|
|
182
|
+
const VIEWPORT_HINT_LIMIT = 100;
|
|
183
|
+
/**
|
|
184
|
+
* Where each element of a page-side array lives (an iframe and/or a shadow
|
|
185
|
+
* root), its text and, for the first {@link VIEWPORT_HINT_LIMIT}, its position
|
|
186
|
+
* relative to the viewport, plus the viewport size. An element that cannot be
|
|
187
|
+
* read gets empty details instead of failing the whole query.
|
|
188
|
+
*/
|
|
130
189
|
const ELEMENT_DETAILS_FUNCTION = `function () {
|
|
131
|
-
const
|
|
190
|
+
const contextOf = ${ELEMENT_CONTEXT_JS};
|
|
132
191
|
const textOf = ${ELEMENT_TEXT_JS};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
192
|
+
const geometryOf = ${ELEMENT_GEOMETRY_JS};
|
|
193
|
+
const read = (el, index) => {
|
|
194
|
+
try {
|
|
195
|
+
return { context: contextOf(el), text: textOf(el), geometry: index < ${VIEWPORT_HINT_LIMIT} ? geometryOf(el) : null };
|
|
196
|
+
} catch (e) {
|
|
197
|
+
return {};
|
|
139
198
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return { context: parts.join(' > '), text: textOf(el) };
|
|
143
|
-
});
|
|
199
|
+
};
|
|
200
|
+
return { viewport: (${VIEWPORT_SIZE_JS})(window), elements: Array.from(this, read) };
|
|
144
201
|
}`;
|
|
145
202
|
/**
|
|
146
203
|
* Backend node ids of the elements in a page-side array, each with where it
|
|
147
|
-
* lives (empty for the main document) and its
|
|
204
|
+
* lives (empty for the main document), its text and its viewport position.
|
|
148
205
|
*
|
|
149
206
|
* @param arrayObjectId - Remote object id of the array
|
|
150
207
|
* @returns Elements in array order (ones that cannot be described are left out)
|
|
208
|
+
* @throws CommandError (91) when the page could not describe the matches
|
|
151
209
|
*/
|
|
152
210
|
async function elementsWithDetails(arrayObjectId) {
|
|
211
|
+
const { viewport, elements = [] } = await readPageDetails(arrayObjectId);
|
|
212
|
+
const ids = await elementBackendNodeIds(arrayObjectId);
|
|
213
|
+
return ids.flatMap((backendNodeId, index) => {
|
|
214
|
+
if (backendNodeId === undefined)
|
|
215
|
+
return [];
|
|
216
|
+
const details = elements[index];
|
|
217
|
+
return [
|
|
218
|
+
{
|
|
219
|
+
backendNodeId,
|
|
220
|
+
context: details?.context ?? '',
|
|
221
|
+
text: details?.text ?? '',
|
|
222
|
+
...viewportHint(details?.geometry, viewport),
|
|
223
|
+
},
|
|
224
|
+
];
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Run {@link ELEMENT_DETAILS_FUNCTION} on a page-side array.
|
|
229
|
+
*
|
|
230
|
+
* @param arrayObjectId - Remote object id of the array
|
|
231
|
+
* @returns Details of each element and the viewport size
|
|
232
|
+
* @throws CommandError (91) when the script failed
|
|
233
|
+
*/
|
|
234
|
+
async function readPageDetails(arrayObjectId) {
|
|
153
235
|
const response = await callCDP('Runtime.callFunctionOn', {
|
|
154
236
|
objectId: arrayObjectId,
|
|
155
237
|
functionDeclaration: ELEMENT_DETAILS_FUNCTION,
|
|
156
238
|
returnByValue: true,
|
|
157
239
|
});
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
240
|
+
const result = response.data?.result;
|
|
241
|
+
if (response.status === 'error' || result?.exceptionDetails) {
|
|
242
|
+
const detail = result?.exceptionDetails?.exception?.description ?? response.error ?? 'no result';
|
|
243
|
+
const err = operationFailedError('describe the matches', detail.split('\n')[0] ?? detail);
|
|
244
|
+
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.SCRIPT_ERROR);
|
|
245
|
+
}
|
|
246
|
+
return (result?.result?.value ?? {});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Viewport position of a measured element for `dom query`.
|
|
250
|
+
*
|
|
251
|
+
* @param geometry - Page-side measurements (none beyond the hint limit)
|
|
252
|
+
* @param viewport - Viewport size
|
|
253
|
+
* @returns `inViewport` (and `clippedBy`), or nothing when not measured
|
|
254
|
+
*/
|
|
255
|
+
function viewportHint(geometry, viewport) {
|
|
256
|
+
if (!geometry || !viewport)
|
|
257
|
+
return {};
|
|
258
|
+
const { inViewport, clippedBy } = classifyViewportPosition(geometry, viewport);
|
|
259
|
+
return { inViewport, ...(clippedBy && { clippedBy }) };
|
|
171
260
|
}
|
|
172
261
|
/**
|
|
173
262
|
* The page-side array of a selector query, or the error explaining why there
|
|
174
263
|
* is none: a selector the browser rejects (a `SyntaxError` DOMException) is the
|
|
175
|
-
* user's (81
|
|
264
|
+
* user's (81; the browser's message is left out for selectors with filters,
|
|
265
|
+
* as it quotes the CSS bdg rewrote them to); anything else (no session, a
|
|
266
|
+
* page navigating away) is not.
|
|
176
267
|
*
|
|
177
268
|
* @param selector - CSS selector
|
|
178
269
|
* @param evaluated - `Runtime.evaluate` response
|
|
@@ -184,7 +275,7 @@ function selectionObjectId(selector, evaluated) {
|
|
|
184
275
|
{});
|
|
185
276
|
const description = exceptionDetails?.exception?.description;
|
|
186
277
|
if (description?.startsWith('SyntaxError')) {
|
|
187
|
-
const detail = description.split('\n')[0];
|
|
278
|
+
const detail = parseSelectorFilters(selector) ? undefined : description.split('\n')[0];
|
|
188
279
|
const err = invalidSelectorError(selector, detail);
|
|
189
280
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
190
281
|
}
|
|
@@ -242,7 +333,8 @@ export async function queryDOMElements(selector) {
|
|
|
242
333
|
if (elements.length > 20) {
|
|
243
334
|
log.debug(`Querying ${elements.length} elements with selector: ${selector}`);
|
|
244
335
|
}
|
|
245
|
-
const nodes = await mapConcurrently(elements, async (
|
|
336
|
+
const nodes = await mapConcurrently(elements, async (element, index) => {
|
|
337
|
+
const { backendNodeId, context, text, inViewport, clippedBy } = element;
|
|
246
338
|
const desc = await describeNode({ backendNodeId });
|
|
247
339
|
if (!desc)
|
|
248
340
|
return { index, nodeId: 0 };
|
|
@@ -253,10 +345,12 @@ export async function queryDOMElements(selector) {
|
|
|
253
345
|
index,
|
|
254
346
|
nodeId: desc.backendNodeId,
|
|
255
347
|
tag: desc.nodeName.toLowerCase(),
|
|
256
|
-
...identifyingAttributes(attributes),
|
|
348
|
+
...identifyingAttributes(attributes, desc.nodeName),
|
|
257
349
|
...(classes && { classes }),
|
|
258
350
|
...(preview && { preview }),
|
|
259
351
|
...(context && { context }),
|
|
352
|
+
...(inViewport && { inViewport }),
|
|
353
|
+
...(clippedBy && { clippedBy }),
|
|
260
354
|
};
|
|
261
355
|
});
|
|
262
356
|
return { selector, count: nodes.length, nodes };
|
|
@@ -265,22 +359,26 @@ export async function queryDOMElements(selector) {
|
|
|
265
359
|
* The attributes that tell similar elements apart (form fields especially).
|
|
266
360
|
*
|
|
267
361
|
* @param attributes - Element attributes
|
|
268
|
-
* @
|
|
362
|
+
* @param nodeName - Element name (`OPTION`s also report their `value`)
|
|
363
|
+
* @returns id, name and type (and an option's value) when present
|
|
269
364
|
*/
|
|
270
|
-
function identifyingAttributes(attributes) {
|
|
365
|
+
function identifyingAttributes(attributes, nodeName) {
|
|
366
|
+
const value = nodeName === 'OPTION' ? attributes['value'] : undefined;
|
|
271
367
|
return {
|
|
272
368
|
...(attributes['id'] && { id: attributes['id'] }),
|
|
273
369
|
...(attributes['name'] && { name: attributes['name'] }),
|
|
274
370
|
...(attributes['type'] && { type: attributes['type'] }),
|
|
371
|
+
...(value !== undefined && { value }),
|
|
275
372
|
};
|
|
276
373
|
}
|
|
277
374
|
/**
|
|
278
375
|
* The text of one element as the page renders it ({@link ELEMENT_TEXT_JS}).
|
|
279
376
|
*
|
|
280
377
|
* @param ref - Node reference
|
|
378
|
+
* @param full - Read all of a large container's text, not just its start
|
|
281
379
|
* @returns Element text, or empty when the node cannot be read
|
|
282
380
|
*/
|
|
283
|
-
async function elementText(ref) {
|
|
381
|
+
async function elementText(ref, full) {
|
|
284
382
|
const objectGroup = `bdg-text-${process.pid}-${++queryCount}`;
|
|
285
383
|
const resolved = await callCDP('DOM.resolveNode', { ...ref, objectGroup });
|
|
286
384
|
const objectId = resolved.data?.result?.object
|
|
@@ -290,7 +388,8 @@ async function elementText(ref) {
|
|
|
290
388
|
try {
|
|
291
389
|
const response = await callCDP('Runtime.callFunctionOn', {
|
|
292
390
|
objectId,
|
|
293
|
-
functionDeclaration: `function () { return (${ELEMENT_TEXT_JS})(this); }`,
|
|
391
|
+
functionDeclaration: `function (full) { return (${ELEMENT_TEXT_JS})(this, full); }`,
|
|
392
|
+
arguments: [{ value: full }],
|
|
294
393
|
returnByValue: true,
|
|
295
394
|
});
|
|
296
395
|
const value = response.data?.result?.result
|
|
@@ -302,26 +401,94 @@ async function elementText(ref) {
|
|
|
302
401
|
}
|
|
303
402
|
}
|
|
304
403
|
/**
|
|
305
|
-
* Get DOM context (tag, classes, text preview) for a node
|
|
404
|
+
* Get DOM context (tag, classes, text preview) for a node: a one-line
|
|
405
|
+
* preview, and up to {@link ELEMENT_TEXT_LENGTH} characters of text when it
|
|
406
|
+
* is longer (all of it with `full`).
|
|
306
407
|
*
|
|
307
408
|
* @param ref - Node reference
|
|
409
|
+
* @param options - `full`: the whole text instead of its first 500 characters
|
|
308
410
|
* @returns DOM context, or null if the node does not exist
|
|
309
411
|
*/
|
|
310
|
-
export async function getDomContext(ref) {
|
|
412
|
+
export async function getDomContext(ref, options = {}) {
|
|
311
413
|
await callCDP('DOM.enable', {});
|
|
312
414
|
const desc = await describeNode(ref);
|
|
313
415
|
if (!desc) {
|
|
314
416
|
log.debug(`No DOM context for ${JSON.stringify(ref)}`);
|
|
315
417
|
return null;
|
|
316
418
|
}
|
|
419
|
+
const full = options.full === true;
|
|
317
420
|
const classes = unpackAttributes(desc.attributes)['class']?.split(/\s+/).filter(Boolean);
|
|
318
|
-
const
|
|
421
|
+
const text = await elementText(ref, full);
|
|
422
|
+
const preview = textPreview(text);
|
|
423
|
+
const longer = textPreview(text, full ? Number.POSITIVE_INFINITY : ELEMENT_TEXT_LENGTH);
|
|
319
424
|
return {
|
|
320
425
|
tag: desc.nodeName.toLowerCase(),
|
|
321
426
|
...(classes && classes.length > 0 && { classes }),
|
|
322
427
|
...(preview && { preview }),
|
|
428
|
+
...(longer !== preview && { text: longer }),
|
|
429
|
+
...(!preview && (await childElements(ref))),
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/** Child elements named for an element without text */
|
|
433
|
+
const CHILDREN_LISTED = 5;
|
|
434
|
+
/**
|
|
435
|
+
* The child elements of an element (for one without text: a body holding
|
|
436
|
+
* only an iframe, an empty app root).
|
|
437
|
+
*
|
|
438
|
+
* @param ref - Node reference
|
|
439
|
+
* @returns The first {@link CHILDREN_LISTED} as `tag#id.class` and how many there are
|
|
440
|
+
*/
|
|
441
|
+
async function childElements(ref) {
|
|
442
|
+
const response = await callCDP('DOM.describeNode', { ...ref, depth: 1 });
|
|
443
|
+
const node = response.data?.result?.node;
|
|
444
|
+
const elements = (node?.children ?? []).filter((child) => child.nodeType === 1);
|
|
445
|
+
return {
|
|
446
|
+
children: elements.slice(0, CHILDREN_LISTED).map(childLabel),
|
|
447
|
+
childCount: elements.length,
|
|
323
448
|
};
|
|
324
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* A child element in a few characters.
|
|
452
|
+
*
|
|
453
|
+
* @param node - Child node
|
|
454
|
+
* @returns e.g. `iframe#app.full`
|
|
455
|
+
*/
|
|
456
|
+
function childLabel(node) {
|
|
457
|
+
const attributes = unpackAttributes(node.attributes);
|
|
458
|
+
const id = attributes['id'] ? `#${attributes['id']}` : '';
|
|
459
|
+
const classes = (attributes['class'] ?? '').split(/\s+/).filter(Boolean).slice(0, 2);
|
|
460
|
+
return `${node.nodeName.toLowerCase()}${id}${classes.map((name) => `.${name}`).join('')}`;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* All matches of a selector.
|
|
464
|
+
*
|
|
465
|
+
* @param selector - CSS selector
|
|
466
|
+
* @returns Backend node ids of the matches (at least one)
|
|
467
|
+
* @throws CommandError (83) when nothing matches
|
|
468
|
+
*/
|
|
469
|
+
async function selectMatches(selector) {
|
|
470
|
+
const backendNodeIds = await selectAll(selector);
|
|
471
|
+
if (backendNodeIds.length > 0)
|
|
472
|
+
return backendNodeIds;
|
|
473
|
+
const err = await noMatchesError(selector);
|
|
474
|
+
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* One match of a selector.
|
|
478
|
+
*
|
|
479
|
+
* @param selector - CSS selector
|
|
480
|
+
* @param index - Which match (0-based)
|
|
481
|
+
* @returns Its backend node id
|
|
482
|
+
* @throws CommandError (83) when nothing matches, (81) for an index beyond the matches
|
|
483
|
+
*/
|
|
484
|
+
export async function selectMatch(selector, index = 0) {
|
|
485
|
+
const backendNodeIds = await selectMatches(selector);
|
|
486
|
+
const backendNodeId = backendNodeIds[index];
|
|
487
|
+
if (backendNodeId !== undefined)
|
|
488
|
+
return backendNodeId;
|
|
489
|
+
const err = indexOutOfRangeError(index, backendNodeIds.length - 1);
|
|
490
|
+
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
491
|
+
}
|
|
325
492
|
/**
|
|
326
493
|
* Pick the nodes `dom get --raw` should report for a selector.
|
|
327
494
|
*
|
|
@@ -330,20 +497,10 @@ export async function getDomContext(ref) {
|
|
|
330
497
|
* @returns Node references to describe
|
|
331
498
|
*/
|
|
332
499
|
async function selectForGet(selector, options) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
const err = noNodesFoundError(selector);
|
|
336
|
-
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
337
|
-
}
|
|
338
|
-
if (options.all)
|
|
339
|
-
return backendNodeIds.map((backendNodeId) => ({ backendNodeId }));
|
|
340
|
-
const position = options.nth ?? 0;
|
|
341
|
-
const backendNodeId = backendNodeIds[position];
|
|
342
|
-
if (backendNodeId === undefined) {
|
|
343
|
-
const err = indexOutOfRangeError(position, backendNodeIds.length - 1);
|
|
344
|
-
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
500
|
+
if (options.all) {
|
|
501
|
+
return (await selectMatches(selector)).map((backendNodeId) => ({ backendNodeId }));
|
|
345
502
|
}
|
|
346
|
-
return [{ backendNodeId }];
|
|
503
|
+
return [{ backendNodeId: await selectMatch(selector, options.nth ?? 0) }];
|
|
347
504
|
}
|
|
348
505
|
/**
|
|
349
506
|
* Get full details (attributes, outer HTML) for `bdg dom get --raw`.
|
|
@@ -366,7 +523,7 @@ export async function getDOMElements(options) {
|
|
|
366
523
|
refs = await selectForGet(options.selector, options);
|
|
367
524
|
}
|
|
368
525
|
else {
|
|
369
|
-
const err = eitherArgumentRequiredError('selector', 'nodeId', 'bdg dom get <selector> or bdg dom get --node-id <id>');
|
|
526
|
+
const err = eitherArgumentRequiredError('selector', 'nodeId', `${sessionCommand('bdg dom get <selector>')} or ${sessionCommand('bdg dom get --node-id <id>')}`);
|
|
370
527
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
371
528
|
}
|
|
372
529
|
const nodes = await mapConcurrently(refs, async (ref) => {
|
|
@@ -398,7 +555,7 @@ export async function getDOMElements(options) {
|
|
|
398
555
|
export async function resolveSelector(selector) {
|
|
399
556
|
const backendNodeId = (await selectAll(selector))[0];
|
|
400
557
|
if (backendNodeId === undefined) {
|
|
401
|
-
const err =
|
|
558
|
+
const err = await noMatchesError(selector);
|
|
402
559
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
403
560
|
}
|
|
404
561
|
return { backendNodeId };
|
|
@@ -412,16 +569,6 @@ export async function resolveSelector(selector) {
|
|
|
412
569
|
export async function resolveBackendNodeIds(selectors) {
|
|
413
570
|
return mapConcurrently(selectors, async (selector) => (await selectAll(selector))[0]);
|
|
414
571
|
}
|
|
415
|
-
/**
|
|
416
|
-
* Accessibility node of the first element matching a selector.
|
|
417
|
-
*
|
|
418
|
-
* @param selector - CSS selector
|
|
419
|
-
* @returns A11y node, or null when nothing matches or the node is not exposed
|
|
420
|
-
*/
|
|
421
|
-
export async function resolveA11yNodeForSelector(selector) {
|
|
422
|
-
const [backendNodeId] = await resolveBackendNodeIds([selector]);
|
|
423
|
-
return backendNodeId === undefined ? null : resolveA11yNode({ backendNodeId });
|
|
424
|
-
}
|
|
425
572
|
/**
|
|
426
573
|
* Check that a cached element is still part of the current page.
|
|
427
574
|
*
|
|
@@ -431,10 +578,10 @@ export async function resolveA11yNodeForSelector(selector) {
|
|
|
431
578
|
* false for removed elements.
|
|
432
579
|
*
|
|
433
580
|
* @param backendNodeId - Backend node id from the query cache
|
|
434
|
-
* @param
|
|
581
|
+
* @param source - Index the user gave and the list it refers to, for the error message
|
|
435
582
|
* @throws CommandError (87) when the element is gone
|
|
436
583
|
*/
|
|
437
|
-
export async function assertNodeAttached(backendNodeId,
|
|
584
|
+
export async function assertNodeAttached(backendNodeId, source) {
|
|
438
585
|
const resolved = await callCDP('DOM.resolveNode', { backendNodeId, objectGroup: 'bdg-check' });
|
|
439
586
|
const objectId = resolved.data?.result?.object
|
|
440
587
|
.objectId;
|
|
@@ -450,7 +597,7 @@ export async function assertNodeAttached(backendNodeId, index) {
|
|
|
450
597
|
await callCDP('Runtime.releaseObjectGroup', { objectGroup: 'bdg-check' });
|
|
451
598
|
}
|
|
452
599
|
if (!attached) {
|
|
453
|
-
const err = staleNodeError(index);
|
|
600
|
+
const err = staleNodeError(source?.index, source);
|
|
454
601
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.STALE_CACHE);
|
|
455
602
|
}
|
|
456
603
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Captures the common flow: resolve selector/index → call IPC → normalize errors.
|
|
5
5
|
* Keeps individual command handlers focused on option wiring and output formatting.
|
|
6
6
|
*/
|
|
7
|
+
import type { IndexSource } from '../../../types.js';
|
|
7
8
|
interface IpcResponse<T> {
|
|
8
9
|
status: string;
|
|
9
10
|
data?: T;
|
|
@@ -16,6 +17,8 @@ interface ResultPayload {
|
|
|
16
17
|
error?: string | undefined;
|
|
17
18
|
suggestion?: string | undefined;
|
|
18
19
|
exitCode?: number | undefined;
|
|
20
|
+
/** The element is not one the command acts on (fill, submit) */
|
|
21
|
+
unsuitableElement?: boolean | undefined;
|
|
19
22
|
}
|
|
20
23
|
interface CommandResult<T> {
|
|
21
24
|
success: boolean;
|
|
@@ -42,6 +45,8 @@ export interface ElementCommandOptions<Req, Res extends ResultPayload> {
|
|
|
42
45
|
}) => Req;
|
|
43
46
|
/** Invoke the IPC client function. */
|
|
44
47
|
call: (req: Req) => Promise<IpcResponse<Res>>;
|
|
48
|
+
/** `bdg dom` subcommand being run, e.g. "fill" (for suggestions). */
|
|
49
|
+
command: string;
|
|
45
50
|
/** Operation label used in fallback error messages (e.g. "fill element"). */
|
|
46
51
|
action: string;
|
|
47
52
|
/** Fallback suggestion when the result reports failure without one. */
|
|
@@ -49,8 +54,11 @@ export interface ElementCommandOptions<Req, Res extends ResultPayload> {
|
|
|
49
54
|
}
|
|
50
55
|
/**
|
|
51
56
|
* Resolve an element target, invoke the IPC call, and normalize failures
|
|
52
|
-
* into the structured `CommandRunner` result shape.
|
|
57
|
+
* into the structured `CommandRunner` result shape. A numeric index names the
|
|
58
|
+
* list it refers to (`indexSource` in the data, and in errors).
|
|
53
59
|
*/
|
|
54
|
-
export declare function runElementCommand<Req, Res extends ResultPayload>(options: ElementCommandOptions<Req, Res>): Promise<CommandResult<Omit<Res, 'success'
|
|
60
|
+
export declare function runElementCommand<Req, Res extends ResultPayload>(options: ElementCommandOptions<Req, Res>): Promise<CommandResult<Omit<Res, 'success'> & {
|
|
61
|
+
indexSource?: IndexSource;
|
|
62
|
+
}>>;
|
|
55
63
|
export {};
|
|
56
64
|
//# sourceMappingURL=runElementCommand.d.ts.map
|