File: /var/www/vhost/disk-apps/alq-cali.bikenow.co/node_modules/chromium-bidi/lib/iife/mapperTab.js
(function () {
'use strict';
function mitt(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e]);},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]));},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e);}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e);});}}}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class EventEmitter {
#emitter = mitt();
on(type, handler) {
this.#emitter.on(type, handler);
return this;
}
once(event, handler) {
const onceHandler = (eventData) => {
handler(eventData);
this.off(event, onceHandler);
};
return this.on(event, onceHandler);
}
off(type, handler) {
this.#emitter.off(type, handler);
return this;
}
emit(event, eventData) {
this.#emitter.emit(event, eventData);
}
removeAllListeners(event) {
if (event) {
this.#emitter.all.delete(event);
}
else {
this.#emitter.all.clear();
}
return this;
}
}
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var LogType;
(function (LogType) {
LogType["bidi"] = "bidi";
LogType["cdp"] = "cdp";
LogType["debug"] = "debug";
LogType["debugError"] = "debug:error";
LogType["debugInfo"] = "debug:info";
LogType["debugWarn"] = "debug:warn";
})(LogType || (LogType = {}));
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var _a$6;
class ProcessingQueue {
static LOGGER_PREFIX = `${LogType.debug}:queue`;
#logger;
#processor;
#queue = [];
#isProcessing = false;
constructor(processor, logger) {
this.#processor = processor;
this.#logger = logger;
}
add(entry, name) {
this.#queue.push([entry, name]);
void this.#processIfNeeded();
}
async #processIfNeeded() {
if (this.#isProcessing) {
return;
}
this.#isProcessing = true;
while (this.#queue.length > 0) {
const arrayEntry = this.#queue.shift();
if (!arrayEntry) {
continue;
}
const [entryPromise, name] = arrayEntry;
this.#logger?.(_a$6.LOGGER_PREFIX, 'Processing event:', name);
await entryPromise
.then((entry) => {
if (entry.kind === 'error') {
this.#logger?.(LogType.debugError, 'Event threw before sending:', entry.error.message, entry.error.stack);
return;
}
return this.#processor(entry.value);
})
.catch((error) => {
this.#logger?.(LogType.debugError, 'Event was not processed:', error?.message);
});
}
this.#isProcessing = false;
}
}
_a$6 = ProcessingQueue;
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var BiDiModule;
(function (BiDiModule) {
BiDiModule["Bluetooth"] = "bluetooth";
BiDiModule["Browser"] = "browser";
BiDiModule["BrowsingContext"] = "browsingContext";
BiDiModule["Cdp"] = "goog:cdp";
BiDiModule["Input"] = "input";
BiDiModule["Log"] = "log";
BiDiModule["Network"] = "network";
BiDiModule["Script"] = "script";
BiDiModule["Session"] = "session";
})(BiDiModule || (BiDiModule = {}));
var Script$2;
(function (Script) {
(function (EventNames) {
EventNames["Message"] = "script.message";
EventNames["RealmCreated"] = "script.realmCreated";
EventNames["RealmDestroyed"] = "script.realmDestroyed";
})(Script.EventNames || (Script.EventNames = {}));
})(Script$2 || (Script$2 = {}));
var Log$1;
(function (Log) {
(function (EventNames) {
EventNames["LogEntryAdded"] = "log.entryAdded";
})(Log.EventNames || (Log.EventNames = {}));
})(Log$1 || (Log$1 = {}));
var BrowsingContext$2;
(function (BrowsingContext) {
(function (EventNames) {
EventNames["ContextCreated"] = "browsingContext.contextCreated";
EventNames["ContextDestroyed"] = "browsingContext.contextDestroyed";
EventNames["DomContentLoaded"] = "browsingContext.domContentLoaded";
EventNames["DownloadEnd"] = "browsingContext.downloadEnd";
EventNames["DownloadWillBegin"] = "browsingContext.downloadWillBegin";
EventNames["FragmentNavigated"] = "browsingContext.fragmentNavigated";
EventNames["HistoryUpdated"] = "browsingContext.historyUpdated";
EventNames["Load"] = "browsingContext.load";
EventNames["NavigationAborted"] = "browsingContext.navigationAborted";
EventNames["NavigationCommitted"] = "browsingContext.navigationCommitted";
EventNames["NavigationFailed"] = "browsingContext.navigationFailed";
EventNames["NavigationStarted"] = "browsingContext.navigationStarted";
EventNames["UserPromptClosed"] = "browsingContext.userPromptClosed";
EventNames["UserPromptOpened"] = "browsingContext.userPromptOpened";
})(BrowsingContext.EventNames || (BrowsingContext.EventNames = {}));
})(BrowsingContext$2 || (BrowsingContext$2 = {}));
var Input$2;
(function (Input) {
(function (EventNames) {
EventNames["FileDialogOpened"] = "input.fileDialogOpened";
})(Input.EventNames || (Input.EventNames = {}));
})(Input$2 || (Input$2 = {}));
var Network$2;
(function (Network) {
(function (EventNames) {
EventNames["AuthRequired"] = "network.authRequired";
EventNames["BeforeRequestSent"] = "network.beforeRequestSent";
EventNames["FetchError"] = "network.fetchError";
EventNames["ResponseCompleted"] = "network.responseCompleted";
EventNames["ResponseStarted"] = "network.responseStarted";
})(Network.EventNames || (Network.EventNames = {}));
})(Network$2 || (Network$2 = {}));
var Bluetooth$2;
(function (Bluetooth) {
(function (EventNames) {
EventNames["RequestDevicePromptUpdated"] = "bluetooth.requestDevicePromptUpdated";
EventNames["GattConnectionAttempted"] = "bluetooth.gattConnectionAttempted";
EventNames["CharacteristicEventGenerated"] = "bluetooth.characteristicEventGenerated";
EventNames["DescriptorEventGenerated"] = "bluetooth.descriptorEventGenerated";
})(Bluetooth.EventNames || (Bluetooth.EventNames = {}));
})(Bluetooth$2 || (Bluetooth$2 = {}));
const EVENT_NAMES = new Set([
...Object.values(BiDiModule),
...Object.values(Bluetooth$2.EventNames),
...Object.values(BrowsingContext$2.EventNames),
...Object.values(Input$2.EventNames),
...Object.values(Log$1.EventNames),
...Object.values(Network$2.EventNames),
...Object.values(Script$2.EventNames),
]);
class Exception extends Error {
error;
message;
stacktrace;
constructor(error, message, stacktrace) {
super();
this.error = error;
this.message = message;
this.stacktrace = stacktrace;
}
toErrorResponse(commandId) {
return {
type: 'error',
id: commandId,
error: this.error,
message: this.message,
stacktrace: this.stacktrace,
};
}
}
class InvalidArgumentException extends Exception {
constructor(message, stacktrace) {
super("invalid argument" , message, stacktrace);
}
}
class InvalidSelectorException extends Exception {
constructor(message, stacktrace) {
super("invalid selector" , message, stacktrace);
}
}
class MoveTargetOutOfBoundsException extends Exception {
constructor(message, stacktrace) {
super("move target out of bounds" , message, stacktrace);
}
}
class NoSuchAlertException extends Exception {
constructor(message, stacktrace) {
super("no such alert" , message, stacktrace);
}
}
class NoSuchElementException extends Exception {
constructor(message, stacktrace) {
super("no such element" , message, stacktrace);
}
}
class NoSuchFrameException extends Exception {
constructor(message, stacktrace) {
super("no such frame" , message, stacktrace);
}
}
class NoSuchHandleException extends Exception {
constructor(message, stacktrace) {
super("no such handle" , message, stacktrace);
}
}
class NoSuchHistoryEntryException extends Exception {
constructor(message, stacktrace) {
super("no such history entry" , message, stacktrace);
}
}
class NoSuchInterceptException extends Exception {
constructor(message, stacktrace) {
super("no such intercept" , message, stacktrace);
}
}
class NoSuchNodeException extends Exception {
constructor(message, stacktrace) {
super("no such node" , message, stacktrace);
}
}
class NoSuchRequestException extends Exception {
constructor(message, stacktrace) {
super("no such request" , message, stacktrace);
}
}
class NoSuchScriptException extends Exception {
constructor(message, stacktrace) {
super("no such script" , message, stacktrace);
}
}
class NoSuchUserContextException extends Exception {
constructor(message, stacktrace) {
super("no such user context" , message, stacktrace);
}
}
class UnknownCommandException extends Exception {
constructor(message, stacktrace) {
super("unknown command" , message, stacktrace);
}
}
class UnknownErrorException extends Exception {
constructor(message, stacktrace = new Error().stack) {
super("unknown error" , message, stacktrace);
}
}
class UnableToCaptureScreenException extends Exception {
constructor(message, stacktrace) {
super("unable to capture screen" , message, stacktrace);
}
}
class UnsupportedOperationException extends Exception {
constructor(message, stacktrace) {
super("unsupported operation" , message, stacktrace);
}
}
class UnableToSetCookieException extends Exception {
constructor(message, stacktrace) {
super("unable to set cookie" , message, stacktrace);
}
}
class UnableToSetFileInputException extends Exception {
constructor(message, stacktrace) {
super("unable to set file input" , message, stacktrace);
}
}
class InvalidWebExtensionException extends Exception {
constructor(message, stacktrace) {
super("invalid web extension" , message, stacktrace);
}
}
class NoSuchWebExtensionException extends Exception {
constructor(message, stacktrace) {
super("no such web extension" , message, stacktrace);
}
}
class NoSuchNetworkCollectorException extends Exception {
constructor(message, stacktrace) {
super("no such network collector" , message, stacktrace);
}
}
class NoSuchNetworkDataException extends Exception {
constructor(message, stacktrace) {
super("no such network data" , message, stacktrace);
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class BidiNoOpParser {
parseDisableSimulationParameters(params) {
return params;
}
parseHandleRequestDevicePromptParams(params) {
return params;
}
parseSimulateAdapterParameters(params) {
return params;
}
parseSimulateAdvertisementParameters(params) {
return params;
}
parseSimulateCharacteristicParameters(params) {
return params;
}
parseSimulateCharacteristicResponseParameters(params) {
return params;
}
parseSimulateDescriptorParameters(params) {
return params;
}
parseSimulateDescriptorResponseParameters(params) {
return params;
}
parseSimulateGattConnectionResponseParameters(params) {
return params;
}
parseSimulateGattDisconnectionParameters(params) {
return params;
}
parseSimulatePreconnectedPeripheralParameters(params) {
return params;
}
parseSimulateServiceParameters(params) {
return params;
}
parseCreateUserContextParameters(params) {
return params;
}
parseRemoveUserContextParameters(params) {
return params;
}
parseSetClientWindowStateParameters(params) {
return params;
}
parseActivateParams(params) {
return params;
}
parseCaptureScreenshotParams(params) {
return params;
}
parseCloseParams(params) {
return params;
}
parseCreateParams(params) {
return params;
}
parseGetTreeParams(params) {
return params;
}
parseHandleUserPromptParams(params) {
return params;
}
parseLocateNodesParams(params) {
return params;
}
parseNavigateParams(params) {
return params;
}
parsePrintParams(params) {
return params;
}
parseReloadParams(params) {
return params;
}
parseSetViewportParams(params) {
return params;
}
parseTraverseHistoryParams(params) {
return params;
}
parseGetSessionParams(params) {
return params;
}
parseResolveRealmParams(params) {
return params;
}
parseSendCommandParams(params) {
return params;
}
parseSetForcedColorsModeThemeOverrideParams(params) {
return params;
}
parseSetGeolocationOverrideParams(params) {
return params;
}
parseSetLocaleOverrideParams(params) {
return params;
}
parseSetScreenOrientationOverrideParams(params) {
return params;
}
parseSetScriptingEnabledParams(params) {
return params;
}
parseSetTimezoneOverrideParams(params) {
return params;
}
parseAddPreloadScriptParams(params) {
return params;
}
parseCallFunctionParams(params) {
return params;
}
parseDisownParams(params) {
return params;
}
parseEvaluateParams(params) {
return params;
}
parseGetRealmsParams(params) {
return params;
}
parseRemovePreloadScriptParams(params) {
return params;
}
parsePerformActionsParams(params) {
return params;
}
parseReleaseActionsParams(params) {
return params;
}
parseSetFilesParams(params) {
return params;
}
parseAddDataCollectorParams(params) {
return params;
}
parseAddInterceptParams(params) {
return params;
}
parseContinueRequestParams(params) {
return params;
}
parseContinueResponseParams(params) {
return params;
}
parseContinueWithAuthParams(params) {
return params;
}
parseDisownDataParams(params) {
return params;
}
parseFailRequestParams(params) {
return params;
}
parseGetDataParams(params) {
return params;
}
parseProvideResponseParams(params) {
return params;
}
parseRemoveDataCollectorParams(params) {
return params;
}
parseRemoveInterceptParams(params) {
return params;
}
parseSetCacheBehaviorParams(params) {
return params;
}
parseSetExtraHeadersParams(params) {
return params;
}
parseSetPermissionsParams(params) {
return params;
}
parseSubscribeParams(params) {
return params;
}
parseUnsubscribeParams(params) {
return params;
}
parseDeleteCookiesParams(params) {
return params;
}
parseGetCookiesParams(params) {
return params;
}
parseSetCookieParams(params) {
return params;
}
parseInstallParams(params) {
return params;
}
parseUninstallParams(params) {
return params;
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class BrowserProcessor {
#browserCdpClient;
#browsingContextStorage;
#configStorage;
#userContextStorage;
constructor(browserCdpClient, browsingContextStorage, configStorage, userContextStorage) {
this.#browserCdpClient = browserCdpClient;
this.#browsingContextStorage = browsingContextStorage;
this.#configStorage = configStorage;
this.#userContextStorage = userContextStorage;
}
close() {
setTimeout(() => this.#browserCdpClient.sendCommand('Browser.close'), 0);
return {};
}
async createUserContext(params) {
const w3cParams = params;
if (w3cParams.acceptInsecureCerts !== undefined) {
const globalConfig = this.#configStorage.getGlobalConfig();
if (w3cParams.acceptInsecureCerts === false &&
globalConfig.acceptInsecureCerts === true)
throw new UnknownErrorException(`Cannot set user context's "acceptInsecureCerts" to false, when a capability "acceptInsecureCerts" is set to true`);
}
const request = {};
if (w3cParams.proxy) {
const proxyStr = getProxyStr(w3cParams.proxy);
if (proxyStr) {
request.proxyServer = proxyStr;
}
if (w3cParams.proxy.noProxy) {
request.proxyBypassList = w3cParams.proxy.noProxy.join(',');
}
}
else {
if (params['goog:proxyServer'] !== undefined) {
request.proxyServer = params['goog:proxyServer'];
}
const proxyBypassList = params['goog:proxyBypassList'] ?? undefined;
if (proxyBypassList) {
request.proxyBypassList = proxyBypassList.join(',');
}
}
const context = await this.#browserCdpClient.sendCommand('Target.createBrowserContext', request);
this.#configStorage.updateUserContextConfig(context.browserContextId, {
acceptInsecureCerts: params['acceptInsecureCerts'],
userPromptHandler: params['unhandledPromptBehavior'],
});
return {
userContext: context.browserContextId,
};
}
async removeUserContext(params) {
const userContext = params.userContext;
if (userContext === 'default') {
throw new InvalidArgumentException('`default` user context cannot be removed');
}
try {
await this.#browserCdpClient.sendCommand('Target.disposeBrowserContext', {
browserContextId: userContext,
});
}
catch (err) {
if (err.message.startsWith('Failed to find context with id')) {
throw new NoSuchUserContextException(err.message);
}
throw err;
}
return {};
}
async getUserContexts() {
return {
userContexts: await this.#userContextStorage.getUserContexts(),
};
}
async #getWindowInfo(targetId) {
const windowInfo = await this.#browserCdpClient.sendCommand('Browser.getWindowForTarget', { targetId });
return {
active: false,
clientWindow: `${windowInfo.windowId}`,
state: windowInfo.bounds.windowState ?? 'normal',
height: windowInfo.bounds.height ?? 0,
width: windowInfo.bounds.width ?? 0,
x: windowInfo.bounds.left ?? 0,
y: windowInfo.bounds.top ?? 0,
};
}
async getClientWindows() {
const topLevelTargetIds = this.#browsingContextStorage
.getTopLevelContexts()
.map((b) => b.cdpTarget.id);
const clientWindows = await Promise.all(topLevelTargetIds.map(async (targetId) => await this.#getWindowInfo(targetId)));
const uniqueClientWindowIds = new Set();
const uniqueClientWindows = new Array();
for (const window of clientWindows) {
if (!uniqueClientWindowIds.has(window.clientWindow)) {
uniqueClientWindowIds.add(window.clientWindow);
uniqueClientWindows.push(window);
}
}
return { clientWindows: uniqueClientWindows };
}
}
function getProxyStr(proxyConfig) {
if (proxyConfig.proxyType === 'direct' ||
proxyConfig.proxyType === 'system') {
return undefined;
}
if (proxyConfig.proxyType === 'pac') {
throw new UnsupportedOperationException(`PAC proxy configuration is not supported per user context`);
}
if (proxyConfig.proxyType === 'autodetect') {
throw new UnsupportedOperationException(`Autodetect proxy is not supported per user context`);
}
if (proxyConfig.proxyType === 'manual') {
const servers = [];
if (proxyConfig.httpProxy !== undefined) {
servers.push(`http=${proxyConfig.httpProxy}`);
}
if (proxyConfig.sslProxy !== undefined) {
servers.push(`https=${proxyConfig.sslProxy}`);
}
if (proxyConfig.socksProxy !== undefined ||
proxyConfig.socksVersion !== undefined) {
if (proxyConfig.socksProxy === undefined) {
throw new InvalidArgumentException(`'socksVersion' cannot be set without 'socksProxy'`);
}
if (proxyConfig.socksVersion === undefined ||
typeof proxyConfig.socksVersion !== 'number' ||
!Number.isInteger(proxyConfig.socksVersion) ||
proxyConfig.socksVersion < 0 ||
proxyConfig.socksVersion > 255) {
throw new InvalidArgumentException(`'socksVersion' must be between 0 and 255`);
}
servers.push(`socks=socks${proxyConfig.socksVersion}://${proxyConfig.socksProxy}`);
}
if (servers.length === 0) {
return undefined;
}
return servers.join(';');
}
throw new UnknownErrorException(`Unknown proxy type`);
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class CdpProcessor {
#browsingContextStorage;
#realmStorage;
#cdpConnection;
#browserCdpClient;
constructor(browsingContextStorage, realmStorage, cdpConnection, browserCdpClient) {
this.#browsingContextStorage = browsingContextStorage;
this.#realmStorage = realmStorage;
this.#cdpConnection = cdpConnection;
this.#browserCdpClient = browserCdpClient;
}
getSession(params) {
const context = params.context;
const sessionId = this.#browsingContextStorage.getContext(context).cdpTarget.cdpSessionId;
if (sessionId === undefined) {
return {};
}
return { session: sessionId };
}
resolveRealm(params) {
const context = params.realm;
const realm = this.#realmStorage.getRealm({ realmId: context });
if (realm === undefined) {
throw new UnknownErrorException(`Could not find realm ${params.realm}`);
}
return { executionContextId: realm.executionContextId };
}
async sendCommand(params) {
const client = params.session
? this.#cdpConnection.getCdpClient(params.session)
: this.#browserCdpClient;
const result = await client.sendCommand(params.method, params.params);
return {
result,
session: params.session,
};
}
}
class BrowsingContextProcessor {
#browserCdpClient;
#browsingContextStorage;
#contextConfigStorage;
#eventManager;
#userContextStorage;
constructor(browserCdpClient, browsingContextStorage, userContextStorage, contextConfigStorage, eventManager) {
this.#contextConfigStorage = contextConfigStorage;
this.#userContextStorage = userContextStorage;
this.#browserCdpClient = browserCdpClient;
this.#browsingContextStorage = browsingContextStorage;
this.#eventManager = eventManager;
this.#eventManager.addSubscribeHook(BrowsingContext$2.EventNames.ContextCreated, this.#onContextCreatedSubscribeHook.bind(this));
}
getTree(params) {
const resultContexts = params.root === undefined
? this.#browsingContextStorage.getTopLevelContexts()
: [this.#browsingContextStorage.getContext(params.root)];
return {
contexts: resultContexts.map((c) => c.serializeToBidiValue(params.maxDepth ?? Number.MAX_VALUE)),
};
}
async create(params) {
let referenceContext;
let userContext = 'default';
if (params.referenceContext !== undefined) {
referenceContext = this.#browsingContextStorage.getContext(params.referenceContext);
if (!referenceContext.isTopLevelContext()) {
throw new InvalidArgumentException(`referenceContext should be a top-level context`);
}
userContext = referenceContext.userContext;
}
if (params.userContext !== undefined) {
userContext = params.userContext;
}
const existingContexts = this.#browsingContextStorage
.getAllContexts()
.filter((context) => context.userContext === userContext);
let newWindow = false;
switch (params.type) {
case "tab" :
newWindow = false;
break;
case "window" :
newWindow = true;
break;
}
if (!existingContexts.length) {
newWindow = true;
}
let result;
try {
result = await this.#browserCdpClient.sendCommand('Target.createTarget', {
url: 'about:blank',
newWindow,
browserContextId: userContext === 'default' ? undefined : userContext,
background: params.background === true,
});
}
catch (err) {
if (
err.message.startsWith('Failed to find browser context with id') ||
err.message === 'browserContextId') {
throw new NoSuchUserContextException(`The context ${userContext} was not found`);
}
throw err;
}
const context = await this.#browsingContextStorage.waitForContext(result.targetId);
await context.lifecycleLoaded();
return { context: context.id };
}
navigate(params) {
const context = this.#browsingContextStorage.getContext(params.context);
return context.navigate(params.url, params.wait ?? "none" );
}
reload(params) {
const context = this.#browsingContextStorage.getContext(params.context);
return context.reload(params.ignoreCache ?? false, params.wait ?? "none" );
}
async activate(params) {
const context = this.#browsingContextStorage.getContext(params.context);
if (!context.isTopLevelContext()) {
throw new InvalidArgumentException('Activation is only supported on the top-level context');
}
await context.activate();
return {};
}
async captureScreenshot(params) {
const context = this.#browsingContextStorage.getContext(params.context);
return await context.captureScreenshot(params);
}
async print(params) {
const context = this.#browsingContextStorage.getContext(params.context);
return await context.print(params);
}
async setViewport(params) {
const config = {};
if (params.devicePixelRatio !== undefined) {
config.devicePixelRatio = params.devicePixelRatio;
}
if (params.viewport !== undefined) {
config.viewport = params.viewport;
}
const impactedTopLevelContexts = await this.#getRelatedTopLevelBrowsingContexts(params.context, params.userContexts);
for (const userContextId of params.userContexts ?? []) {
this.#contextConfigStorage.updateUserContextConfig(userContextId, config);
}
if (params.context !== undefined) {
this.#contextConfigStorage.updateBrowsingContextConfig(params.context, config);
}
await Promise.all(impactedTopLevelContexts.map((context) => context.setViewport(params.viewport, params.devicePixelRatio)));
return {};
}
async #getRelatedTopLevelBrowsingContexts(browsingContextId, userContextIds) {
if (browsingContextId === undefined && userContextIds === undefined) {
throw new InvalidArgumentException('Either userContexts or context must be provided');
}
if (browsingContextId !== undefined && userContextIds !== undefined) {
throw new InvalidArgumentException('userContexts and context are mutually exclusive');
}
if (browsingContextId !== undefined) {
const context = this.#browsingContextStorage.getContext(browsingContextId);
if (!context.isTopLevelContext()) {
throw new InvalidArgumentException('Emulating viewport is only supported on the top-level context');
}
return [context];
}
await this.#userContextStorage.verifyUserContextIdList(userContextIds);
const result = [];
for (const userContextId of userContextIds) {
const topLevelBrowsingContexts = this.#browsingContextStorage
.getTopLevelContexts()
.filter((browsingContext) => browsingContext.userContext === userContextId);
result.push(...topLevelBrowsingContexts);
}
return [...new Set(result).values()];
}
async traverseHistory(params) {
const context = this.#browsingContextStorage.getContext(params.context);
if (!context) {
throw new InvalidArgumentException(`No browsing context with id ${params.context}`);
}
if (!context.isTopLevelContext()) {
throw new InvalidArgumentException('Traversing history is only supported on the top-level context');
}
await context.traverseHistory(params.delta);
return {};
}
async handleUserPrompt(params) {
const context = this.#browsingContextStorage.getContext(params.context);
try {
await context.handleUserPrompt(params.accept, params.userText);
}
catch (error) {
if (error.message?.includes('No dialog is showing')) {
throw new NoSuchAlertException('No dialog is showing');
}
throw error;
}
return {};
}
async close(params) {
const context = this.#browsingContextStorage.getContext(params.context);
if (!context.isTopLevelContext()) {
throw new InvalidArgumentException(`Non top-level browsing context ${context.id} cannot be closed.`);
}
const parentCdpClient = context.cdpTarget.parentCdpClient;
try {
const detachedFromTargetPromise = new Promise((resolve) => {
const onContextDestroyed = (event) => {
if (event.targetId === params.context) {
parentCdpClient.off('Target.detachedFromTarget', onContextDestroyed);
resolve();
}
};
parentCdpClient.on('Target.detachedFromTarget', onContextDestroyed);
});
try {
if (params.promptUnload) {
await context.close();
}
else {
await parentCdpClient.sendCommand('Target.closeTarget', {
targetId: params.context,
});
}
}
catch (error) {
if (!parentCdpClient.isCloseError(error)) {
throw error;
}
}
await detachedFromTargetPromise;
}
catch (error) {
if (!(error.code === -32e3 &&
error.message === 'Not attached to an active page')) {
throw error;
}
}
return {};
}
async locateNodes(params) {
const context = this.#browsingContextStorage.getContext(params.context);
return await context.locateNodes(params);
}
#onContextCreatedSubscribeHook(contextId) {
const context = this.#browsingContextStorage.getContext(contextId);
const contextsToReport = [
context,
...this.#browsingContextStorage.getContext(contextId).allChildren,
];
contextsToReport.forEach((context) => {
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.ContextCreated,
params: context.serializeToBidiValue(),
}, context.id);
});
return Promise.resolve();
}
}
/**
* Copyright 2025 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class EmulationProcessor {
#userContextStorage;
#browsingContextStorage;
#contextConfigStorage;
constructor(browsingContextStorage, userContextStorage, contextConfigStorage) {
this.#userContextStorage = userContextStorage;
this.#browsingContextStorage = browsingContextStorage;
this.#contextConfigStorage = contextConfigStorage;
}
async setGeolocationOverride(params) {
if ('coordinates' in params && 'error' in params) {
throw new InvalidArgumentException('Coordinates and error cannot be set at the same time');
}
let geolocation = null;
if ('coordinates' in params) {
if ((params.coordinates?.altitude ?? null) === null &&
(params.coordinates?.altitudeAccuracy ?? null) !== null) {
throw new InvalidArgumentException('Geolocation altitudeAccuracy can be set only with altitude');
}
geolocation = params.coordinates;
}
else if ('error' in params) {
if (params.error.type !== 'positionUnavailable') {
throw new InvalidArgumentException(`Unknown geolocation error ${params.error.type}`);
}
geolocation = params.error;
}
else {
throw new InvalidArgumentException(`Coordinates or error should be set`);
}
const browsingContexts = await this.#getRelatedTopLevelBrowsingContexts(params.contexts, params.userContexts);
for (const browsingContextId of params.contexts ?? []) {
this.#contextConfigStorage.updateBrowsingContextConfig(browsingContextId, {
geolocation,
});
}
for (const userContextId of params.userContexts ?? []) {
this.#contextConfigStorage.updateUserContextConfig(userContextId, {
geolocation,
});
}
await Promise.all(browsingContexts.map(async (context) => await context.setGeolocationOverride(geolocation)));
return {};
}
async setLocaleOverride(params) {
const locale = params.locale ?? null;
if (locale !== null && !isValidLocale(locale)) {
throw new InvalidArgumentException(`Invalid locale "${locale}"`);
}
const browsingContexts = await this.#getRelatedTopLevelBrowsingContexts(params.contexts, params.userContexts);
for (const browsingContextId of params.contexts ?? []) {
this.#contextConfigStorage.updateBrowsingContextConfig(browsingContextId, {
locale,
});
}
for (const userContextId of params.userContexts ?? []) {
this.#contextConfigStorage.updateUserContextConfig(userContextId, {
locale,
});
}
await Promise.all(browsingContexts.map(async (context) => await context.setLocaleOverride(locale)));
return {};
}
async setScriptingEnabled(params) {
const scriptingEnabled = params.enabled;
const browsingContexts = await this.#getRelatedTopLevelBrowsingContexts(params.contexts, params.userContexts);
for (const browsingContextId of params.contexts ?? []) {
this.#contextConfigStorage.updateBrowsingContextConfig(browsingContextId, {
scriptingEnabled,
});
}
for (const userContextId of params.userContexts ?? []) {
this.#contextConfigStorage.updateUserContextConfig(userContextId, {
scriptingEnabled,
});
}
await Promise.all(browsingContexts.map(async (context) => await context.setScriptingEnabled(scriptingEnabled)));
return {};
}
async setScreenOrientationOverride(params) {
const browsingContexts = await this.#getRelatedTopLevelBrowsingContexts(params.contexts, params.userContexts);
for (const browsingContextId of params.contexts ?? []) {
this.#contextConfigStorage.updateBrowsingContextConfig(browsingContextId, {
screenOrientation: params.screenOrientation,
});
}
for (const userContextId of params.userContexts ?? []) {
this.#contextConfigStorage.updateUserContextConfig(userContextId, {
screenOrientation: params.screenOrientation,
});
}
await Promise.all(browsingContexts.map(async (context) => await context.setScreenOrientationOverride(params.screenOrientation)));
return {};
}
async #getRelatedTopLevelBrowsingContexts(browsingContextIds, userContextIds) {
if (browsingContextIds === undefined && userContextIds === undefined) {
throw new InvalidArgumentException('Either user contexts or browsing contexts must be provided');
}
if (browsingContextIds !== undefined && userContextIds !== undefined) {
throw new InvalidArgumentException('User contexts and browsing contexts are mutually exclusive');
}
const result = [];
if (browsingContextIds === undefined) {
if (userContextIds.length === 0) {
throw new InvalidArgumentException('user context should be provided');
}
await this.#userContextStorage.verifyUserContextIdList(userContextIds);
for (const userContextId of userContextIds) {
const topLevelBrowsingContexts = this.#browsingContextStorage
.getTopLevelContexts()
.filter((browsingContext) => browsingContext.userContext === userContextId);
result.push(...topLevelBrowsingContexts);
}
}
else {
if (browsingContextIds.length === 0) {
throw new InvalidArgumentException('browsing context should be provided');
}
for (const browsingContextId of browsingContextIds) {
const browsingContext = this.#browsingContextStorage.getContext(browsingContextId);
if (!browsingContext.isTopLevelContext()) {
throw new InvalidArgumentException('The command is only supported on the top-level context');
}
result.push(browsingContext);
}
}
return [...new Set(result).values()];
}
async setTimezoneOverride(params) {
let timezone = params.timezone ?? null;
if (timezone !== null && !isValidTimezone(timezone)) {
throw new InvalidArgumentException(`Invalid timezone "${timezone}"`);
}
if (timezone !== null && isTimeZoneOffsetString(timezone)) {
timezone = `GMT${timezone}`;
}
const browsingContexts = await this.#getRelatedTopLevelBrowsingContexts(params.contexts, params.userContexts);
for (const browsingContextId of params.contexts ?? []) {
this.#contextConfigStorage.updateBrowsingContextConfig(browsingContextId, {
timezone,
});
}
for (const userContextId of params.userContexts ?? []) {
this.#contextConfigStorage.updateUserContextConfig(userContextId, {
timezone,
});
}
await Promise.all(browsingContexts.map(async (context) => await context.setTimezoneOverride(timezone)));
return {};
}
}
function isValidLocale(locale) {
try {
new Intl.Locale(locale);
return true;
}
catch (e) {
if (e instanceof RangeError) {
return false;
}
throw e;
}
}
function isValidTimezone(timezone) {
try {
Intl.DateTimeFormat(undefined, { timeZone: timezone });
return true;
}
catch (e) {
if (e instanceof RangeError) {
return false;
}
throw e;
}
}
function isTimeZoneOffsetString(timezone) {
return /^[+-](?:2[0-3]|[01]\d)(?::[0-5]\d)?$/.test(timezone);
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function assert(predicate, message) {
if (!predicate) {
throw new Error(message ?? 'Internal assertion failed.');
}
}
/*
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function isSingleComplexGrapheme(value) {
return isSingleGrapheme(value) && value.length > 1;
}
function isSingleGrapheme(value) {
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
return [...segmenter.segment(value)].length === 1;
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class NoneSource {
type = "none" ;
}
class KeySource {
type = "key" ;
pressed = new Set();
#modifiers = 0;
get modifiers() {
return this.#modifiers;
}
get alt() {
return (this.#modifiers & 1) === 1;
}
set alt(value) {
this.#setModifier(value, 1);
}
get ctrl() {
return (this.#modifiers & 2) === 2;
}
set ctrl(value) {
this.#setModifier(value, 2);
}
get meta() {
return (this.#modifiers & 4) === 4;
}
set meta(value) {
this.#setModifier(value, 4);
}
get shift() {
return (this.#modifiers & 8) === 8;
}
set shift(value) {
this.#setModifier(value, 8);
}
#setModifier(value, bit) {
if (value) {
this.#modifiers |= bit;
}
else {
this.#modifiers &= ~bit;
}
}
}
class PointerSource {
type = "pointer" ;
subtype;
pointerId;
pressed = new Set();
x = 0;
y = 0;
radiusX;
radiusY;
force;
constructor(id, subtype) {
this.pointerId = id;
this.subtype = subtype;
}
get buttons() {
let buttons = 0;
for (const button of this.pressed) {
switch (button) {
case 0:
buttons |= 1;
break;
case 1:
buttons |= 4;
break;
case 2:
buttons |= 2;
break;
case 3:
buttons |= 8;
break;
case 4:
buttons |= 16;
break;
}
}
return buttons;
}
static ClickContext = class ClickContext {
static #DOUBLE_CLICK_TIME_MS = 500;
static #MAX_DOUBLE_CLICK_RADIUS = 2;
count = 0;
#x;
#y;
#time;
constructor(x, y, time) {
this.#x = x;
this.#y = y;
this.#time = time;
}
compare(context) {
return (
context.#time - this.#time > ClickContext.#DOUBLE_CLICK_TIME_MS ||
Math.abs(context.#x - this.#x) >
ClickContext.#MAX_DOUBLE_CLICK_RADIUS ||
Math.abs(context.#y - this.#y) > ClickContext.#MAX_DOUBLE_CLICK_RADIUS);
}
};
#clickContexts = new Map();
setClickCount(button, context) {
let storedContext = this.#clickContexts.get(button);
if (!storedContext || storedContext.compare(context)) {
storedContext = context;
}
++storedContext.count;
this.#clickContexts.set(button, storedContext);
return storedContext.count;
}
getClickCount(button) {
return this.#clickContexts.get(button)?.count ?? 0;
}
resetClickCount() {
this.#clickContexts = new Map();
}
}
class WheelSource {
type = "wheel" ;
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function getNormalizedKey(value) {
switch (value) {
case '\uE000':
return 'Unidentified';
case '\uE001':
return 'Cancel';
case '\uE002':
return 'Help';
case '\uE003':
return 'Backspace';
case '\uE004':
return 'Tab';
case '\uE005':
return 'Clear';
case '\uE006':
case '\uE007':
return 'Enter';
case '\uE008':
return 'Shift';
case '\uE009':
return 'Control';
case '\uE00A':
return 'Alt';
case '\uE00B':
return 'Pause';
case '\uE00C':
return 'Escape';
case '\uE00D':
return ' ';
case '\uE00E':
return 'PageUp';
case '\uE00F':
return 'PageDown';
case '\uE010':
return 'End';
case '\uE011':
return 'Home';
case '\uE012':
return 'ArrowLeft';
case '\uE013':
return 'ArrowUp';
case '\uE014':
return 'ArrowRight';
case '\uE015':
return 'ArrowDown';
case '\uE016':
return 'Insert';
case '\uE017':
return 'Delete';
case '\uE018':
return ';';
case '\uE019':
return '=';
case '\uE01A':
return '0';
case '\uE01B':
return '1';
case '\uE01C':
return '2';
case '\uE01D':
return '3';
case '\uE01E':
return '4';
case '\uE01F':
return '5';
case '\uE020':
return '6';
case '\uE021':
return '7';
case '\uE022':
return '8';
case '\uE023':
return '9';
case '\uE024':
return '*';
case '\uE025':
return '+';
case '\uE026':
return ',';
case '\uE027':
return '-';
case '\uE028':
return '.';
case '\uE029':
return '/';
case '\uE031':
return 'F1';
case '\uE032':
return 'F2';
case '\uE033':
return 'F3';
case '\uE034':
return 'F4';
case '\uE035':
return 'F5';
case '\uE036':
return 'F6';
case '\uE037':
return 'F7';
case '\uE038':
return 'F8';
case '\uE039':
return 'F9';
case '\uE03A':
return 'F10';
case '\uE03B':
return 'F11';
case '\uE03C':
return 'F12';
case '\uE03D':
return 'Meta';
case '\uE040':
return 'ZenkakuHankaku';
case '\uE050':
return 'Shift';
case '\uE051':
return 'Control';
case '\uE052':
return 'Alt';
case '\uE053':
return 'Meta';
case '\uE054':
return 'PageUp';
case '\uE055':
return 'PageDown';
case '\uE056':
return 'End';
case '\uE057':
return 'Home';
case '\uE058':
return 'ArrowLeft';
case '\uE059':
return 'ArrowUp';
case '\uE05A':
return 'ArrowRight';
case '\uE05B':
return 'ArrowDown';
case '\uE05C':
return 'Insert';
case '\uE05D':
return 'Delete';
default:
return value;
}
}
function getKeyCode(key) {
switch (key) {
case '`':
case '~':
return 'Backquote';
case '\\':
case '|':
return 'Backslash';
case '\uE003':
return 'Backspace';
case '[':
case '{':
return 'BracketLeft';
case ']':
case '}':
return 'BracketRight';
case ',':
case '<':
return 'Comma';
case '0':
case ')':
return 'Digit0';
case '1':
case '!':
return 'Digit1';
case '2':
case '@':
return 'Digit2';
case '3':
case '#':
return 'Digit3';
case '4':
case '$':
return 'Digit4';
case '5':
case '%':
return 'Digit5';
case '6':
case '^':
return 'Digit6';
case '7':
case '&':
return 'Digit7';
case '8':
case '*':
return 'Digit8';
case '9':
case '(':
return 'Digit9';
case '=':
case '+':
return 'Equal';
case '>':
return 'IntlBackslash';
case 'a':
case 'A':
return 'KeyA';
case 'b':
case 'B':
return 'KeyB';
case 'c':
case 'C':
return 'KeyC';
case 'd':
case 'D':
return 'KeyD';
case 'e':
case 'E':
return 'KeyE';
case 'f':
case 'F':
return 'KeyF';
case 'g':
case 'G':
return 'KeyG';
case 'h':
case 'H':
return 'KeyH';
case 'i':
case 'I':
return 'KeyI';
case 'j':
case 'J':
return 'KeyJ';
case 'k':
case 'K':
return 'KeyK';
case 'l':
case 'L':
return 'KeyL';
case 'm':
case 'M':
return 'KeyM';
case 'n':
case 'N':
return 'KeyN';
case 'o':
case 'O':
return 'KeyO';
case 'p':
case 'P':
return 'KeyP';
case 'q':
case 'Q':
return 'KeyQ';
case 'r':
case 'R':
return 'KeyR';
case 's':
case 'S':
return 'KeyS';
case 't':
case 'T':
return 'KeyT';
case 'u':
case 'U':
return 'KeyU';
case 'v':
case 'V':
return 'KeyV';
case 'w':
case 'W':
return 'KeyW';
case 'x':
case 'X':
return 'KeyX';
case 'y':
case 'Y':
return 'KeyY';
case 'z':
case 'Z':
return 'KeyZ';
case '-':
case '_':
return 'Minus';
case '.':
return 'Period';
case "'":
case '"':
return 'Quote';
case ';':
case ':':
return 'Semicolon';
case '/':
case '?':
return 'Slash';
case '\uE00A':
return 'AltLeft';
case '\uE052':
return 'AltRight';
case '\uE009':
return 'ControlLeft';
case '\uE051':
return 'ControlRight';
case '\uE006':
return 'Enter';
case '\uE00B':
return 'Pause';
case '\uE03D':
return 'MetaLeft';
case '\uE053':
return 'MetaRight';
case '\uE008':
return 'ShiftLeft';
case '\uE050':
return 'ShiftRight';
case ' ':
case '\uE00D':
return 'Space';
case '\uE004':
return 'Tab';
case '\uE017':
return 'Delete';
case '\uE010':
return 'End';
case '\uE002':
return 'Help';
case '\uE011':
return 'Home';
case '\uE016':
return 'Insert';
case '\uE00F':
return 'PageDown';
case '\uE00E':
return 'PageUp';
case '\uE015':
return 'ArrowDown';
case '\uE012':
return 'ArrowLeft';
case '\uE014':
return 'ArrowRight';
case '\uE013':
return 'ArrowUp';
case '\uE00C':
return 'Escape';
case '\uE031':
return 'F1';
case '\uE032':
return 'F2';
case '\uE033':
return 'F3';
case '\uE034':
return 'F4';
case '\uE035':
return 'F5';
case '\uE036':
return 'F6';
case '\uE037':
return 'F7';
case '\uE038':
return 'F8';
case '\uE039':
return 'F9';
case '\uE03A':
return 'F10';
case '\uE03B':
return 'F11';
case '\uE03C':
return 'F12';
case '\uE019':
return 'NumpadEqual';
case '\uE01A':
case '\uE05C':
return 'Numpad0';
case '\uE01B':
case '\uE056':
return 'Numpad1';
case '\uE01C':
case '\uE05B':
return 'Numpad2';
case '\uE01D':
case '\uE055':
return 'Numpad3';
case '\uE01E':
case '\uE058':
return 'Numpad4';
case '\uE01F':
return 'Numpad5';
case '\uE020':
case '\uE05A':
return 'Numpad6';
case '\uE021':
case '\uE057':
return 'Numpad7';
case '\uE022':
case '\uE059':
return 'Numpad8';
case '\uE023':
case '\uE054':
return 'Numpad9';
case '\uE025':
return 'NumpadAdd';
case '\uE026':
return 'NumpadComma';
case '\uE028':
case '\uE05D':
return 'NumpadDecimal';
case '\uE029':
return 'NumpadDivide';
case '\uE007':
return 'NumpadEnter';
case '\uE024':
return 'NumpadMultiply';
case '\uE027':
return 'NumpadSubtract';
default:
return;
}
}
function getKeyLocation(key) {
switch (key) {
case '\uE007':
case '\uE008':
case '\uE009':
case '\uE00A':
case '\uE03D':
return 1;
case '\uE019':
case '\uE01A':
case '\uE01B':
case '\uE01C':
case '\uE01D':
case '\uE01E':
case '\uE01F':
case '\uE020':
case '\uE021':
case '\uE022':
case '\uE023':
case '\uE024':
case '\uE025':
case '\uE026':
case '\uE027':
case '\uE028':
case '\uE029':
case '\uE054':
case '\uE055':
case '\uE056':
case '\uE057':
case '\uE058':
case '\uE059':
case '\uE05A':
case '\uE05B':
case '\uE05C':
case '\uE05D':
return 3;
case '\uE050':
case '\uE051':
case '\uE052':
case '\uE053':
return 2;
default:
return 0;
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const KeyToKeyCode = {
'0': 48,
'1': 49,
'2': 50,
'3': 51,
'4': 52,
'5': 53,
'6': 54,
'7': 55,
'8': 56,
'9': 57,
Abort: 3,
Help: 6,
Backspace: 8,
Tab: 9,
Numpad5: 12,
NumpadEnter: 13,
Enter: 13,
'\\r': 13,
'\\n': 13,
ShiftLeft: 16,
ShiftRight: 16,
ControlLeft: 17,
ControlRight: 17,
AltLeft: 18,
AltRight: 18,
Pause: 19,
CapsLock: 20,
Escape: 27,
Convert: 28,
NonConvert: 29,
Space: 32,
Numpad9: 33,
PageUp: 33,
Numpad3: 34,
PageDown: 34,
End: 35,
Numpad1: 35,
Home: 36,
Numpad7: 36,
ArrowLeft: 37,
Numpad4: 37,
Numpad8: 38,
ArrowUp: 38,
ArrowRight: 39,
Numpad6: 39,
Numpad2: 40,
ArrowDown: 40,
Select: 41,
Open: 43,
PrintScreen: 44,
Insert: 45,
Numpad0: 45,
Delete: 46,
NumpadDecimal: 46,
Digit0: 48,
Digit1: 49,
Digit2: 50,
Digit3: 51,
Digit4: 52,
Digit5: 53,
Digit6: 54,
Digit7: 55,
Digit8: 56,
Digit9: 57,
KeyA: 65,
KeyB: 66,
KeyC: 67,
KeyD: 68,
KeyE: 69,
KeyF: 70,
KeyG: 71,
KeyH: 72,
KeyI: 73,
KeyJ: 74,
KeyK: 75,
KeyL: 76,
KeyM: 77,
KeyN: 78,
KeyO: 79,
KeyP: 80,
KeyQ: 81,
KeyR: 82,
KeyS: 83,
KeyT: 84,
KeyU: 85,
KeyV: 86,
KeyW: 87,
KeyX: 88,
KeyY: 89,
KeyZ: 90,
MetaLeft: 91,
MetaRight: 92,
ContextMenu: 93,
NumpadMultiply: 106,
NumpadAdd: 107,
NumpadSubtract: 109,
NumpadDivide: 111,
F1: 112,
F2: 113,
F3: 114,
F4: 115,
F5: 116,
F6: 117,
F7: 118,
F8: 119,
F9: 120,
F10: 121,
F11: 122,
F12: 123,
F13: 124,
F14: 125,
F15: 126,
F16: 127,
F17: 128,
F18: 129,
F19: 130,
F20: 131,
F21: 132,
F22: 133,
F23: 134,
F24: 135,
NumLock: 144,
ScrollLock: 145,
AudioVolumeMute: 173,
AudioVolumeDown: 174,
AudioVolumeUp: 175,
MediaTrackNext: 176,
MediaTrackPrevious: 177,
MediaStop: 178,
MediaPlayPause: 179,
Semicolon: 186,
Equal: 187,
NumpadEqual: 187,
Comma: 188,
Minus: 189,
Period: 190,
Slash: 191,
Backquote: 192,
BracketLeft: 219,
Backslash: 220,
BracketRight: 221,
Quote: 222,
AltGraph: 225,
Props: 247,
Cancel: 3,
Clear: 12,
Shift: 16,
Control: 17,
Alt: 18,
Accept: 30,
ModeChange: 31,
' ': 32,
Print: 42,
Execute: 43,
'\\u0000': 46,
a: 65,
b: 66,
c: 67,
d: 68,
e: 69,
f: 70,
g: 71,
h: 72,
i: 73,
j: 74,
k: 75,
l: 76,
m: 77,
n: 78,
o: 79,
p: 80,
q: 81,
r: 82,
s: 83,
t: 84,
u: 85,
v: 86,
w: 87,
x: 88,
y: 89,
z: 90,
Meta: 91,
'*': 106,
'+': 107,
'-': 109,
'/': 111,
';': 186,
'=': 187,
',': 188,
'.': 190,
'`': 192,
'[': 219,
'\\\\': 220,
']': 221,
"'": 222,
Attn: 246,
CrSel: 247,
ExSel: 248,
EraseEof: 249,
Play: 250,
ZoomOut: 251,
')': 48,
'!': 49,
'@': 50,
'#': 51,
$: 52,
'%': 53,
'^': 54,
'&': 55,
'(': 57,
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
G: 71,
H: 72,
I: 73,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
Q: 81,
R: 82,
S: 83,
T: 84,
U: 85,
V: 86,
W: 87,
X: 88,
Y: 89,
Z: 90,
':': 186,
'<': 188,
_: 189,
'>': 190,
'?': 191,
'~': 192,
'{': 219,
'|': 220,
'}': 221,
'"': 222,
Camera: 44,
EndCall: 95,
VolumeDown: 182,
VolumeUp: 183,
};
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const CALCULATE_IN_VIEW_CENTER_PT_DECL = ((i) => {
const t = i.getClientRects()[0], e = Math.max(0, Math.min(t.x, t.x + t.width)), n = Math.min(window.innerWidth, Math.max(t.x, t.x + t.width)), h = Math.max(0, Math.min(t.y, t.y + t.height)), m = Math.min(window.innerHeight, Math.max(t.y, t.y + t.height));
return [e + ((n - e) >> 1), h + ((m - h) >> 1)];
}).toString();
const IS_MAC_DECL = (() => {
return navigator.platform.toLowerCase().includes('mac');
}).toString();
async function getElementCenter(context, element) {
const hiddenSandboxRealm = await context.getOrCreateHiddenSandbox();
const result = await hiddenSandboxRealm.callFunction(CALCULATE_IN_VIEW_CENTER_PT_DECL, false, { type: 'undefined' }, [element]);
if (result.type === 'exception') {
throw new NoSuchElementException(`Origin element ${element.sharedId} was not found`);
}
assert(result.result.type === 'array');
assert(result.result.value?.[0]?.type === 'number');
assert(result.result.value?.[1]?.type === 'number');
const { result: { value: [{ value: x }, { value: y }], }, } = result;
return { x: x, y: y };
}
class ActionDispatcher {
static isMacOS = async (context) => {
const hiddenSandboxRealm = await context.getOrCreateHiddenSandbox();
const result = await hiddenSandboxRealm.callFunction(IS_MAC_DECL, false);
assert(result.type !== 'exception');
assert(result.result.type === 'boolean');
return result.result.value;
};
#browsingContextStorage;
#tickStart = 0;
#tickDuration = 0;
#inputState;
#contextId;
#isMacOS;
constructor(inputState, browsingContextStorage, contextId, isMacOS) {
this.#browsingContextStorage = browsingContextStorage;
this.#inputState = inputState;
this.#contextId = contextId;
this.#isMacOS = isMacOS;
}
get #context() {
return this.#browsingContextStorage.getContext(this.#contextId);
}
async dispatchActions(optionsByTick) {
await this.#inputState.queue.run(async () => {
for (const options of optionsByTick) {
await this.dispatchTickActions(options);
}
});
}
async dispatchTickActions(options) {
this.#tickStart = performance.now();
this.#tickDuration = 0;
for (const { action } of options) {
if ('duration' in action && action.duration !== undefined) {
this.#tickDuration = Math.max(this.#tickDuration, action.duration);
}
}
const promises = [
new Promise((resolve) => setTimeout(resolve, this.#tickDuration)),
];
for (const option of options) {
promises.push(this.#dispatchAction(option));
}
await Promise.all(promises);
}
async #dispatchAction({ id, action }) {
const source = this.#inputState.get(id);
const keyState = this.#inputState.getGlobalKeyState();
switch (action.type) {
case 'keyDown': {
await this.#dispatchKeyDownAction(source, action);
this.#inputState.cancelList.push({
id,
action: {
...action,
type: 'keyUp',
},
});
break;
}
case 'keyUp': {
await this.#dispatchKeyUpAction(source, action);
break;
}
case 'pause': {
break;
}
case 'pointerDown': {
await this.#dispatchPointerDownAction(source, keyState, action);
this.#inputState.cancelList.push({
id,
action: {
...action,
type: 'pointerUp',
},
});
break;
}
case 'pointerMove': {
await this.#dispatchPointerMoveAction(source, keyState, action);
break;
}
case 'pointerUp': {
await this.#dispatchPointerUpAction(source, keyState, action);
break;
}
case 'scroll': {
await this.#dispatchScrollAction(source, keyState, action);
break;
}
}
}
async #dispatchPointerDownAction(source, keyState, action) {
const { button } = action;
if (source.pressed.has(button)) {
return;
}
source.pressed.add(button);
const { x, y, subtype: pointerType } = source;
const { width, height, pressure, twist, tangentialPressure } = action;
const { tiltX, tiltY } = getTilt(action);
const { modifiers } = keyState;
const { radiusX, radiusY } = getRadii(width ?? 1, height ?? 1);
switch (pointerType) {
case "mouse" :
case "pen" :
await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
type: 'mousePressed',
x,
y,
modifiers,
button: getCdpButton(button),
buttons: source.buttons,
clickCount: source.setClickCount(button, new PointerSource.ClickContext(x, y, performance.now())),
pointerType,
tangentialPressure,
tiltX,
tiltY,
twist,
force: pressure,
});
break;
case "touch" :
await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
type: 'touchStart',
touchPoints: [
{
x,
y,
radiusX,
radiusY,
tangentialPressure,
tiltX,
tiltY,
twist,
force: pressure,
id: source.pointerId,
},
],
modifiers,
});
break;
}
source.radiusX = radiusX;
source.radiusY = radiusY;
source.force = pressure;
}
#dispatchPointerUpAction(source, keyState, action) {
const { button } = action;
if (!source.pressed.has(button)) {
return;
}
source.pressed.delete(button);
const { x, y, force, radiusX, radiusY, subtype: pointerType } = source;
const { modifiers } = keyState;
switch (pointerType) {
case "mouse" :
case "pen" :
return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
type: 'mouseReleased',
x,
y,
modifiers,
button: getCdpButton(button),
buttons: source.buttons,
clickCount: source.getClickCount(button),
pointerType,
});
case "touch" :
return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
type: 'touchEnd',
touchPoints: [
{
x,
y,
id: source.pointerId,
force,
radiusX,
radiusY,
},
],
modifiers,
});
}
}
async #dispatchPointerMoveAction(source, keyState, action) {
const { x: startX, y: startY, subtype: pointerType } = source;
const { width, height, pressure, twist, tangentialPressure, x: offsetX, y: offsetY, origin = 'viewport', duration = this.#tickDuration, } = action;
const { tiltX, tiltY } = getTilt(action);
const { radiusX, radiusY } = getRadii(width ?? 1, height ?? 1);
const { targetX, targetY } = await this.#getCoordinateFromOrigin(origin, offsetX, offsetY, startX, startY);
if (targetX < 0 || targetY < 0) {
throw new MoveTargetOutOfBoundsException(`Cannot move beyond viewport (x: ${targetX}, y: ${targetY})`);
}
let last;
do {
const ratio = duration > 0 ? (performance.now() - this.#tickStart) / duration : 1;
last = ratio >= 1;
let x;
let y;
if (last) {
x = targetX;
y = targetY;
}
else {
x = Math.round(ratio * (targetX - startX) + startX);
y = Math.round(ratio * (targetY - startY) + startY);
}
if (source.x !== x || source.y !== y) {
const { modifiers } = keyState;
switch (pointerType) {
case "mouse" :
await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
type: 'mouseMoved',
x,
y,
modifiers,
clickCount: 0,
button: getCdpButton(source.pressed.values().next().value ?? 5),
buttons: source.buttons,
pointerType,
tangentialPressure,
tiltX,
tiltY,
twist,
force: pressure,
});
break;
case "pen" :
if (source.pressed.size !== 0) {
await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
type: 'mouseMoved',
x,
y,
modifiers,
clickCount: 0,
button: getCdpButton(source.pressed.values().next().value ?? 5),
buttons: source.buttons,
pointerType,
tangentialPressure,
tiltX,
tiltY,
twist,
force: pressure ?? 0.5,
});
}
break;
case "touch" :
if (source.pressed.size !== 0) {
await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
type: 'touchMove',
touchPoints: [
{
x,
y,
radiusX,
radiusY,
tangentialPressure,
tiltX,
tiltY,
twist,
force: pressure,
id: source.pointerId,
},
],
modifiers,
});
}
break;
}
source.x = x;
source.y = y;
source.radiusX = radiusX;
source.radiusY = radiusY;
source.force = pressure;
}
} while (!last);
}
async #getFrameOffset() {
if (this.#context.id === this.#context.cdpTarget.id) {
return { x: 0, y: 0 };
}
const { backendNodeId } = await this.#context.cdpTarget.cdpClient.sendCommand('DOM.getFrameOwner', { frameId: this.#context.id });
const { model: frameBoxModel } = await this.#context.cdpTarget.cdpClient.sendCommand('DOM.getBoxModel', {
backendNodeId,
});
return { x: frameBoxModel.content[0], y: frameBoxModel.content[1] };
}
async #getCoordinateFromOrigin(origin, offsetX, offsetY, startX, startY) {
let targetX;
let targetY;
const frameOffset = await this.#getFrameOffset();
switch (origin) {
case 'viewport':
targetX = offsetX + frameOffset.x;
targetY = offsetY + frameOffset.y;
break;
case 'pointer':
targetX = startX + offsetX + frameOffset.x;
targetY = startY + offsetY + frameOffset.y;
break;
default: {
const { x: posX, y: posY } = await getElementCenter(this.#context, origin.element);
targetX = posX + offsetX + frameOffset.x;
targetY = posY + offsetY + frameOffset.y;
break;
}
}
return { targetX, targetY };
}
async #dispatchScrollAction(_source, keyState, action) {
const { deltaX: targetDeltaX, deltaY: targetDeltaY, x: offsetX, y: offsetY, origin = 'viewport', duration = this.#tickDuration, } = action;
if (origin === 'pointer') {
throw new InvalidArgumentException('"pointer" origin is invalid for scrolling.');
}
const { targetX, targetY } = await this.#getCoordinateFromOrigin(origin, offsetX, offsetY, 0, 0);
if (targetX < 0 || targetY < 0) {
throw new MoveTargetOutOfBoundsException(`Cannot move beyond viewport (x: ${targetX}, y: ${targetY})`);
}
let currentDeltaX = 0;
let currentDeltaY = 0;
let last;
do {
const ratio = duration > 0 ? (performance.now() - this.#tickStart) / duration : 1;
last = ratio >= 1;
let deltaX;
let deltaY;
if (last) {
deltaX = targetDeltaX - currentDeltaX;
deltaY = targetDeltaY - currentDeltaY;
}
else {
deltaX = Math.round(ratio * targetDeltaX - currentDeltaX);
deltaY = Math.round(ratio * targetDeltaY - currentDeltaY);
}
if (deltaX !== 0 || deltaY !== 0) {
const { modifiers } = keyState;
await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
type: 'mouseWheel',
deltaX,
deltaY,
x: targetX,
y: targetY,
modifiers,
});
currentDeltaX += deltaX;
currentDeltaY += deltaY;
}
} while (!last);
}
async #dispatchKeyDownAction(source, action) {
const rawKey = action.value;
if (!isSingleGrapheme(rawKey)) {
throw new InvalidArgumentException(`Invalid key value: ${rawKey}`);
}
const isGrapheme = isSingleComplexGrapheme(rawKey);
const key = getNormalizedKey(rawKey);
const repeat = source.pressed.has(key);
const code = getKeyCode(rawKey);
const location = getKeyLocation(rawKey);
switch (key) {
case 'Alt':
source.alt = true;
break;
case 'Shift':
source.shift = true;
break;
case 'Control':
source.ctrl = true;
break;
case 'Meta':
source.meta = true;
break;
}
source.pressed.add(key);
const { modifiers } = source;
const unmodifiedText = getKeyEventUnmodifiedText(key, source, isGrapheme);
const text = getKeyEventText(code ?? '', source) ?? unmodifiedText;
let command;
if (this.#isMacOS && source.meta) {
switch (code) {
case 'KeyA':
command = 'SelectAll';
break;
case 'KeyC':
command = 'Copy';
break;
case 'KeyV':
command = source.shift ? 'PasteAndMatchStyle' : 'Paste';
break;
case 'KeyX':
command = 'Cut';
break;
case 'KeyZ':
command = source.shift ? 'Redo' : 'Undo';
break;
}
}
const promises = [
this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {
type: text ? 'keyDown' : 'rawKeyDown',
windowsVirtualKeyCode: KeyToKeyCode[key],
key,
code,
text,
unmodifiedText,
autoRepeat: repeat,
isSystemKey: source.alt || undefined,
location: location < 3 ? location : undefined,
isKeypad: location === 3,
modifiers,
commands: command ? [command] : undefined,
}),
];
if (key === 'Escape') {
if (!source.alt &&
((this.#isMacOS && !source.ctrl && !source.meta) || !this.#isMacOS)) {
promises.push(this.#context.cdpTarget.cdpClient.sendCommand('Input.cancelDragging'));
}
}
await Promise.all(promises);
}
#dispatchKeyUpAction(source, action) {
const rawKey = action.value;
if (!isSingleGrapheme(rawKey)) {
throw new InvalidArgumentException(`Invalid key value: ${rawKey}`);
}
const isGrapheme = isSingleComplexGrapheme(rawKey);
const key = getNormalizedKey(rawKey);
if (!source.pressed.has(key)) {
return;
}
const code = getKeyCode(rawKey);
const location = getKeyLocation(rawKey);
switch (key) {
case 'Alt':
source.alt = false;
break;
case 'Shift':
source.shift = false;
break;
case 'Control':
source.ctrl = false;
break;
case 'Meta':
source.meta = false;
break;
}
source.pressed.delete(key);
const { modifiers } = source;
const unmodifiedText = getKeyEventUnmodifiedText(key, source, isGrapheme);
const text = getKeyEventText(code ?? '', source) ?? unmodifiedText;
return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {
type: 'keyUp',
windowsVirtualKeyCode: KeyToKeyCode[key],
key,
code,
text,
unmodifiedText,
location: location < 3 ? location : undefined,
isSystemKey: source.alt || undefined,
isKeypad: location === 3,
modifiers,
});
}
}
const getKeyEventUnmodifiedText = (key, source, isGrapheme) => {
if (isGrapheme) {
return key;
}
if (key === 'Enter') {
return '\r';
}
return [...key].length === 1
? source.shift
? key.toLocaleUpperCase('en-US')
: key
: undefined;
};
const getKeyEventText = (code, source) => {
if (source.ctrl) {
switch (code) {
case 'Digit2':
if (source.shift) {
return '\x00';
}
break;
case 'KeyA':
return '\x01';
case 'KeyB':
return '\x02';
case 'KeyC':
return '\x03';
case 'KeyD':
return '\x04';
case 'KeyE':
return '\x05';
case 'KeyF':
return '\x06';
case 'KeyG':
return '\x07';
case 'KeyH':
return '\x08';
case 'KeyI':
return '\x09';
case 'KeyJ':
return '\x0A';
case 'KeyK':
return '\x0B';
case 'KeyL':
return '\x0C';
case 'KeyM':
return '\x0D';
case 'KeyN':
return '\x0E';
case 'KeyO':
return '\x0F';
case 'KeyP':
return '\x10';
case 'KeyQ':
return '\x11';
case 'KeyR':
return '\x12';
case 'KeyS':
return '\x13';
case 'KeyT':
return '\x14';
case 'KeyU':
return '\x15';
case 'KeyV':
return '\x16';
case 'KeyW':
return '\x17';
case 'KeyX':
return '\x18';
case 'KeyY':
return '\x19';
case 'KeyZ':
return '\x1A';
case 'BracketLeft':
return '\x1B';
case 'Backslash':
return '\x1C';
case 'BracketRight':
return '\x1D';
case 'Digit6':
if (source.shift) {
return '\x1E';
}
break;
case 'Minus':
return '\x1F';
}
return '';
}
if (source.alt) {
return '';
}
return;
};
function getCdpButton(button) {
switch (button) {
case 0:
return 'left';
case 1:
return 'middle';
case 2:
return 'right';
case 3:
return 'back';
case 4:
return 'forward';
default:
return 'none';
}
}
function getTilt(action) {
const altitudeAngle = action.altitudeAngle ?? Math.PI / 2;
const azimuthAngle = action.azimuthAngle ?? 0;
let tiltXRadians = 0;
let tiltYRadians = 0;
if (altitudeAngle === 0) {
if (azimuthAngle === 0 || azimuthAngle === 2 * Math.PI) {
tiltXRadians = Math.PI / 2;
}
if (azimuthAngle === Math.PI / 2) {
tiltYRadians = Math.PI / 2;
}
if (azimuthAngle === Math.PI) {
tiltXRadians = -Math.PI / 2;
}
if (azimuthAngle === (3 * Math.PI) / 2) {
tiltYRadians = -Math.PI / 2;
}
if (azimuthAngle > 0 && azimuthAngle < Math.PI / 2) {
tiltXRadians = Math.PI / 2;
tiltYRadians = Math.PI / 2;
}
if (azimuthAngle > Math.PI / 2 && azimuthAngle < Math.PI) {
tiltXRadians = -Math.PI / 2;
tiltYRadians = Math.PI / 2;
}
if (azimuthAngle > Math.PI && azimuthAngle < (3 * Math.PI) / 2) {
tiltXRadians = -Math.PI / 2;
tiltYRadians = -Math.PI / 2;
}
if (azimuthAngle > (3 * Math.PI) / 2 && azimuthAngle < 2 * Math.PI) {
tiltXRadians = Math.PI / 2;
tiltYRadians = -Math.PI / 2;
}
}
if (altitudeAngle !== 0) {
const tanAlt = Math.tan(altitudeAngle);
tiltXRadians = Math.atan(Math.cos(azimuthAngle) / tanAlt);
tiltYRadians = Math.atan(Math.sin(azimuthAngle) / tanAlt);
}
const factor = 180 / Math.PI;
return {
tiltX: Math.round(tiltXRadians * factor),
tiltY: Math.round(tiltYRadians * factor),
};
}
function getRadii(width, height) {
return {
radiusX: width ? width / 2 : 0.5,
radiusY: height ? height / 2 : 0.5,
};
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
* Copyright 2022 The Chromium Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Mutex {
#locked = false;
#acquirers = [];
acquire() {
const state = { resolved: false };
if (this.#locked) {
return new Promise((resolve) => {
this.#acquirers.push(() => resolve(this.#release.bind(this, state)));
});
}
this.#locked = true;
return Promise.resolve(this.#release.bind(this, state));
}
#release(state) {
if (state.resolved) {
throw new Error('Cannot release more than once.');
}
state.resolved = true;
const resolve = this.#acquirers.shift();
if (!resolve) {
this.#locked = false;
return;
}
resolve();
}
async run(action) {
const release = await this.acquire();
try {
const result = await action();
return result;
}
finally {
release();
}
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class InputState {
cancelList = [];
#sources = new Map();
#mutex = new Mutex();
getOrCreate(id, type, subtype) {
let source = this.#sources.get(id);
if (!source) {
switch (type) {
case "none" :
source = new NoneSource();
break;
case "key" :
source = new KeySource();
break;
case "pointer" : {
let pointerId = subtype === "mouse" ? 0 : 2;
const pointerIds = new Set();
for (const [, source] of this.#sources) {
if (source.type === "pointer" ) {
pointerIds.add(source.pointerId);
}
}
while (pointerIds.has(pointerId)) {
++pointerId;
}
source = new PointerSource(pointerId, subtype);
break;
}
case "wheel" :
source = new WheelSource();
break;
default:
throw new InvalidArgumentException(`Expected "${"none" }", "${"key" }", "${"pointer" }", or "${"wheel" }". Found unknown source type ${type}.`);
}
this.#sources.set(id, source);
return source;
}
if (source.type !== type) {
throw new InvalidArgumentException(`Input source type of ${id} is ${source.type}, but received ${type}.`);
}
return source;
}
get(id) {
const source = this.#sources.get(id);
if (!source) {
throw new UnknownErrorException(`Internal error.`);
}
return source;
}
getGlobalKeyState() {
const state = new KeySource();
for (const [, source] of this.#sources) {
if (source.type !== "key" ) {
continue;
}
for (const pressed of source.pressed) {
state.pressed.add(pressed);
}
state.alt ||= source.alt;
state.ctrl ||= source.ctrl;
state.meta ||= source.meta;
state.shift ||= source.shift;
}
return state;
}
get queue() {
return this.#mutex;
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class InputStateManager extends WeakMap {
get(context) {
assert(context.isTopLevelContext());
if (!this.has(context)) {
this.set(context, new InputState());
}
return super.get(context);
}
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class InputProcessor {
#browsingContextStorage;
#inputStateManager = new InputStateManager();
constructor(browsingContextStorage) {
this.#browsingContextStorage = browsingContextStorage;
}
async performActions(params) {
const context = this.#browsingContextStorage.getContext(params.context);
const inputState = this.#inputStateManager.get(context.top);
const actionsByTick = this.#getActionsByTick(params, inputState);
const dispatcher = new ActionDispatcher(inputState, this.#browsingContextStorage, params.context, await ActionDispatcher.isMacOS(context).catch(() => false));
await dispatcher.dispatchActions(actionsByTick);
return {};
}
async releaseActions(params) {
const context = this.#browsingContextStorage.getContext(params.context);
const topContext = context.top;
const inputState = this.#inputStateManager.get(topContext);
const dispatcher = new ActionDispatcher(inputState, this.#browsingContextStorage, params.context, await ActionDispatcher.isMacOS(context).catch(() => false));
await dispatcher.dispatchTickActions(inputState.cancelList.reverse());
this.#inputStateManager.delete(topContext);
return {};
}
async setFiles(params) {
const context = this.#browsingContextStorage.getContext(params.context);
const hiddenSandboxRealm = await context.getOrCreateHiddenSandbox();
let result;
try {
result = await hiddenSandboxRealm.callFunction(String(function getFiles(fileListLength) {
if (!(this instanceof HTMLInputElement)) {
if (this instanceof Element) {
return 1 ;
}
return 0 ;
}
if (this.type !== 'file') {
return 2 ;
}
if (this.disabled) {
return 3 ;
}
if (fileListLength > 1 && !this.multiple) {
return 4 ;
}
return;
}), false, params.element, [{ type: 'number', value: params.files.length }]);
}
catch {
throw new NoSuchNodeException(`Could not find element ${params.element.sharedId}`);
}
assert(result.type === 'success');
if (result.result.type === 'number') {
switch (result.result.value) {
case 0 : {
throw new NoSuchElementException(`Could not find element ${params.element.sharedId}`);
}
case 1 : {
throw new UnableToSetFileInputException(`Element ${params.element.sharedId} is not a input`);
}
case 2 : {
throw new UnableToSetFileInputException(`Input element ${params.element.sharedId} is not a file type`);
}
case 3 : {
throw new UnableToSetFileInputException(`Input element ${params.element.sharedId} is disabled`);
}
case 4 : {
throw new UnableToSetFileInputException(`Cannot set multiple files on a non-multiple input element`);
}
}
}
if (params.files.length === 0) {
await hiddenSandboxRealm.callFunction(String(function dispatchEvent() {
if (this.files?.length === 0) {
this.dispatchEvent(new Event('cancel', {
bubbles: true,
}));
return;
}
this.files = new DataTransfer().files;
this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
this.dispatchEvent(new Event('change', { bubbles: true }));
}), false, params.element);
return {};
}
const paths = [];
for (let i = 0; i < params.files.length; ++i) {
const result = await hiddenSandboxRealm.callFunction(String(function getFiles(index) {
return this.files?.item(index);
}), false, params.element, [{ type: 'number', value: 0 }], "root" );
assert(result.type === 'success');
if (result.result.type !== 'object') {
break;
}
const { handle } = result.result;
assert(handle !== undefined);
const { path } = await hiddenSandboxRealm.cdpClient.sendCommand('DOM.getFileInfo', {
objectId: handle,
});
paths.push(path);
void hiddenSandboxRealm.disown(handle).catch(undefined);
}
paths.sort();
const sortedFiles = [...params.files].sort();
if (paths.length !== params.files.length ||
sortedFiles.some((path, index) => {
return paths[index] !== path;
})) {
const { objectId } = await hiddenSandboxRealm.deserializeForCdp(params.element);
assert(objectId !== undefined);
await hiddenSandboxRealm.cdpClient.sendCommand('DOM.setFileInputFiles', {
files: params.files,
objectId,
});
}
else {
await hiddenSandboxRealm.callFunction(String(function dispatchEvent() {
this.dispatchEvent(new Event('cancel', {
bubbles: true,
}));
}), false, params.element);
}
return {};
}
#getActionsByTick(params, inputState) {
const actionsByTick = [];
for (const action of params.actions) {
switch (action.type) {
case "pointer" : {
action.parameters ??= { pointerType: "mouse" };
action.parameters.pointerType ??= "mouse" ;
const source = inputState.getOrCreate(action.id, "pointer" , action.parameters.pointerType);
if (source.subtype !== action.parameters.pointerType) {
throw new InvalidArgumentException(`Expected input source ${action.id} to be ${source.subtype}; got ${action.parameters.pointerType}.`);
}
source.resetClickCount();
break;
}
default:
inputState.getOrCreate(action.id, action.type);
}
const actions = action.actions.map((item) => ({
id: action.id,
action: item,
}));
for (let i = 0; i < actions.length; i++) {
if (actionsByTick.length === i) {
actionsByTick.push([]);
}
actionsByTick[i].push(actions[i]);
}
}
return actionsByTick;
}
}
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function base64ToString(base64Str) {
if ('atob' in globalThis) {
return globalThis.atob(base64Str);
}
return Buffer.from(base64Str, 'base64').toString('ascii');
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
function computeHeadersSize(headers) {
const requestHeaders = headers.reduce((acc, header) => {
return `${acc}${header.name}: ${header.value.value}\r\n`;
}, '');
return new TextEncoder().encode(requestHeaders).length;
}
function stringToBase64(str) {
return typedArrayToBase64(new TextEncoder().encode(str));
}
function typedArrayToBase64(typedArray) {
const chunkSize = 65534;
const chunks = [];
for (let i = 0; i < typedArray.length; i += chunkSize) {
const chunk = typedArray.subarray(i, i + chunkSize);
chunks.push(String.fromCodePoint.apply(null, chunk));
}
const binaryString = chunks.join('');
return btoa(binaryString);
}
function bidiNetworkHeadersFromCdpNetworkHeaders(headers) {
if (!headers) {
return [];
}
return Object.entries(headers).map(([name, value]) => ({
name,
value: {
type: 'string',
value,
},
}));
}
function cdpFetchHeadersFromBidiNetworkHeaders(headers) {
if (headers === undefined) {
return undefined;
}
return headers.map(({ name, value }) => ({
name,
value: value.value,
}));
}
function networkHeaderFromCookieHeaders(headers) {
if (headers === undefined) {
return undefined;
}
const value = headers.reduce((acc, value, index) => {
if (index > 0) {
acc += ';';
}
const cookieValue = value.value.type === 'base64'
? btoa(value.value.value)
: value.value.value;
acc += `${value.name}=${cookieValue}`;
return acc;
}, '');
return {
name: 'Cookie',
value: {
type: 'string',
value,
},
};
}
function cdpAuthChallengeResponseFromBidiAuthContinueWithAuthAction(action) {
switch (action) {
case 'default':
return 'Default';
case 'cancel':
return 'CancelAuth';
case 'provideCredentials':
return 'ProvideCredentials';
}
}
function cdpToBiDiCookie(cookie) {
const result = {
name: cookie.name,
value: { type: 'string', value: cookie.value },
domain: cookie.domain,
path: cookie.path,
size: cookie.size,
httpOnly: cookie.httpOnly,
secure: cookie.secure,
sameSite: cookie.sameSite === undefined
? "none"
: sameSiteCdpToBiDi(cookie.sameSite),
...(cookie.expires >= 0 ? { expiry: cookie.expires } : undefined),
};
result[`goog:session`] = cookie.session;
result[`goog:priority`] = cookie.priority;
result[`goog:sameParty`] = cookie.sameParty;
result[`goog:sourceScheme`] = cookie.sourceScheme;
result[`goog:sourcePort`] = cookie.sourcePort;
if (cookie.partitionKey !== undefined) {
result[`goog:partitionKey`] = cookie.partitionKey;
}
if (cookie.partitionKeyOpaque !== undefined) {
result[`goog:partitionKeyOpaque`] = cookie.partitionKeyOpaque;
}
return result;
}
function deserializeByteValue(value) {
if (value.type === 'base64') {
return base64ToString(value.value);
}
return value.value;
}
function bidiToCdpCookie(params, partitionKey) {
const deserializedValue = deserializeByteValue(params.cookie.value);
const result = {
name: params.cookie.name,
value: deserializedValue,
domain: params.cookie.domain,
path: params.cookie.path ?? '/',
secure: params.cookie.secure ?? false,
httpOnly: params.cookie.httpOnly ?? false,
...(partitionKey.sourceOrigin !== undefined && {
partitionKey: {
hasCrossSiteAncestor: false,
topLevelSite: partitionKey.sourceOrigin,
},
}),
...(params.cookie.expiry !== undefined && {
expires: params.cookie.expiry,
}),
...(params.cookie.sameSite !== undefined && {
sameSite: sameSiteBiDiToCdp(params.cookie.sameSite),
}),
};
if (params.cookie[`goog:url`] !== undefined) {
result.url = params.cookie[`goog:url`];
}
if (params.cookie[`goog:priority`] !== undefined) {
result.priority = params.cookie[`goog:priority`];
}
if (params.cookie[`goog:sameParty`] !== undefined) {
result.sameParty = params.cookie[`goog:sameParty`];
}
if (params.cookie[`goog:sourceScheme`] !== undefined) {
result.sourceScheme = params.cookie[`goog:sourceScheme`];
}
if (params.cookie[`goog:sourcePort`] !== undefined) {
result.sourcePort = params.cookie[`goog:sourcePort`];
}
return result;
}
function sameSiteCdpToBiDi(sameSite) {
switch (sameSite) {
case 'Strict':
return "strict" ;
case 'None':
return "none" ;
case 'Lax':
return "lax" ;
default:
return "lax" ;
}
}
function sameSiteBiDiToCdp(sameSite) {
switch (sameSite) {
case "none" :
return 'None';
case "strict" :
return 'Strict';
case "default" :
case "lax" :
return 'Lax';
}
throw new InvalidArgumentException(`Unknown 'sameSite' value ${sameSite}`);
}
function isSpecialScheme(protocol) {
return ['ftp', 'file', 'http', 'https', 'ws', 'wss'].includes(protocol.replace(/:$/, ''));
}
function getScheme(url) {
return url.protocol.replace(/:$/, '');
}
function matchUrlPattern(pattern, url) {
const parsedUrl = new URL(url);
if (pattern.protocol !== undefined &&
pattern.protocol !== getScheme(parsedUrl)) {
return false;
}
if (pattern.hostname !== undefined &&
pattern.hostname !== parsedUrl.hostname) {
return false;
}
if (pattern.port !== undefined && pattern.port !== parsedUrl.port) {
return false;
}
if (pattern.pathname !== undefined &&
pattern.pathname !== parsedUrl.pathname) {
return false;
}
if (pattern.search !== undefined && pattern.search !== parsedUrl.search) {
return false;
}
return true;
}
function bidiBodySizeFromCdpPostDataEntries(entries) {
let size = 0;
for (const entry of entries) {
size += atob(entry.bytes ?? '').length;
}
return size;
}
function getTiming(timing, offset = 0) {
if (!timing) {
return 0;
}
if (timing <= 0 || timing + offset <= 0) {
return 0;
}
return timing + offset;
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class NetworkProcessor {
#browsingContextStorage;
#networkStorage;
#userContextStorage;
#contextConfigStorage;
constructor(browsingContextStorage, networkStorage, userContextStorage, contextConfigStorage) {
this.#userContextStorage = userContextStorage;
this.#browsingContextStorage = browsingContextStorage;
this.#networkStorage = networkStorage;
this.#contextConfigStorage = contextConfigStorage;
}
async addIntercept(params) {
this.#browsingContextStorage.verifyTopLevelContextsList(params.contexts);
const urlPatterns = params.urlPatterns ?? [];
const parsedUrlPatterns = NetworkProcessor.parseUrlPatterns(urlPatterns);
const intercept = this.#networkStorage.addIntercept({
urlPatterns: parsedUrlPatterns,
phases: params.phases,
contexts: params.contexts,
});
await this.#toggleNetwork();
return {
intercept,
};
}
async continueRequest(params) {
if (params.url !== undefined) {
NetworkProcessor.parseUrlString(params.url);
}
if (params.method !== undefined) {
if (!NetworkProcessor.isMethodValid(params.method)) {
throw new InvalidArgumentException(`Method '${params.method}' is invalid.`);
}
}
if (params.headers) {
NetworkProcessor.validateHeaders(params.headers);
}
const request = this.#getBlockedRequestOrFail(params.request, [
"beforeRequestSent" ,
]);
try {
await request.continueRequest(params);
}
catch (error) {
throw NetworkProcessor.wrapInterceptionError(error);
}
return {};
}
async continueResponse(params) {
if (params.headers) {
NetworkProcessor.validateHeaders(params.headers);
}
const request = this.#getBlockedRequestOrFail(params.request, [
"authRequired" ,
"responseStarted" ,
]);
try {
await request.continueResponse(params);
}
catch (error) {
throw NetworkProcessor.wrapInterceptionError(error);
}
return {};
}
async continueWithAuth(params) {
const networkId = params.request;
const request = this.#getBlockedRequestOrFail(networkId, [
"authRequired" ,
]);
await request.continueWithAuth(params);
return {};
}
async failRequest({ request: networkId, }) {
const request = this.#getRequestOrFail(networkId);
if (request.interceptPhase === "authRequired" ) {
throw new InvalidArgumentException(`Request '${networkId}' in 'authRequired' phase cannot be failed`);
}
if (!request.interceptPhase) {
throw new NoSuchRequestException(`No blocked request found for network id '${networkId}'`);
}
await request.failRequest('Failed');
return {};
}
async provideResponse(params) {
if (params.headers) {
NetworkProcessor.validateHeaders(params.headers);
}
const request = this.#getBlockedRequestOrFail(params.request, [
"beforeRequestSent" ,
"responseStarted" ,
"authRequired" ,
]);
try {
await request.provideResponse(params);
}
catch (error) {
throw NetworkProcessor.wrapInterceptionError(error);
}
return {};
}
async #toggleNetwork() {
await Promise.all(this.#browsingContextStorage.getAllContexts().map((context) => {
return context.cdpTarget.toggleNetwork();
}));
}
async removeIntercept(params) {
this.#networkStorage.removeIntercept(params.intercept);
await this.#toggleNetwork();
return {};
}
async setCacheBehavior(params) {
const contexts = this.#browsingContextStorage.verifyTopLevelContextsList(params.contexts);
if (contexts.size === 0) {
this.#networkStorage.defaultCacheBehavior = params.cacheBehavior;
await Promise.all(this.#browsingContextStorage.getAllContexts().map((context) => {
return context.cdpTarget.toggleSetCacheDisabled();
}));
return {};
}
const cacheDisabled = params.cacheBehavior === 'bypass';
await Promise.all([...contexts.values()].map((context) => {
return context.cdpTarget.toggleSetCacheDisabled(cacheDisabled);
}));
return {};
}
#getRequestOrFail(id) {
const request = this.#networkStorage.getRequestById(id);
if (!request) {
throw new NoSuchRequestException(`Network request with ID '${id}' doesn't exist`);
}
return request;
}
#getBlockedRequestOrFail(id, phases) {
const request = this.#getRequestOrFail(id);
if (!request.interceptPhase) {
throw new NoSuchRequestException(`No blocked request found for network id '${id}'`);
}
if (request.interceptPhase && !phases.includes(request.interceptPhase)) {
throw new InvalidArgumentException(`Blocked request for network id '${id}' is in '${request.interceptPhase}' phase`);
}
return request;
}
static validateHeaders(headers) {
for (const header of headers) {
let headerValue;
if (header.value.type === 'string') {
headerValue = header.value.value;
}
else {
headerValue = atob(header.value.value);
}
if (headerValue !== headerValue.trim() ||
headerValue.includes('\n') ||
headerValue.includes('\0')) {
throw new InvalidArgumentException(`Header value '${headerValue}' is not acceptable value`);
}
}
}
static isMethodValid(method) {
return /^[!#$%&'*+\-.^_`|~a-zA-Z\d]+$/.test(method);
}
static parseUrlString(url) {
try {
return new URL(url);
}
catch (error) {
throw new InvalidArgumentException(`Invalid URL '${url}': ${error}`);
}
}
static parseUrlPatterns(urlPatterns) {
return urlPatterns.map((urlPattern) => {
let patternUrl = '';
let hasProtocol = true;
let hasHostname = true;
let hasPort = true;
let hasPathname = true;
let hasSearch = true;
switch (urlPattern.type) {
case 'string': {
patternUrl = unescapeURLPattern(urlPattern.pattern);
break;
}
case 'pattern': {
if (urlPattern.protocol === undefined) {
hasProtocol = false;
patternUrl += 'http';
}
else {
if (urlPattern.protocol === '') {
throw new InvalidArgumentException('URL pattern must specify a protocol');
}
urlPattern.protocol = unescapeURLPattern(urlPattern.protocol);
if (!urlPattern.protocol.match(/^[a-zA-Z+-.]+$/)) {
throw new InvalidArgumentException('Forbidden characters');
}
patternUrl += urlPattern.protocol;
}
const scheme = patternUrl.toLocaleLowerCase();
patternUrl += ':';
if (isSpecialScheme(scheme)) {
patternUrl += '//';
}
if (urlPattern.hostname === undefined) {
if (scheme !== 'file') {
patternUrl += 'placeholder';
}
hasHostname = false;
}
else {
if (urlPattern.hostname === '') {
throw new InvalidArgumentException('URL pattern must specify a hostname');
}
if (urlPattern.protocol === 'file') {
throw new InvalidArgumentException(`URL pattern protocol cannot be 'file'`);
}
urlPattern.hostname = unescapeURLPattern(urlPattern.hostname);
let insideBrackets = false;
for (const c of urlPattern.hostname) {
if (c === '/' || c === '?' || c === '#') {
throw new InvalidArgumentException(`'/', '?', '#' are forbidden in hostname`);
}
if (!insideBrackets && c === ':') {
throw new InvalidArgumentException(`':' is only allowed inside brackets in hostname`);
}
if (c === '[') {
insideBrackets = true;
}
if (c === ']') {
insideBrackets = false;
}
}
patternUrl += urlPattern.hostname;
}
if (urlPattern.port === undefined) {
hasPort = false;
}
else {
if (urlPattern.port === '') {
throw new InvalidArgumentException(`URL pattern must specify a port`);
}
urlPattern.port = unescapeURLPattern(urlPattern.port);
patternUrl += ':';
if (!urlPattern.port.match(/^\d+$/)) {
throw new InvalidArgumentException('Forbidden characters');
}
patternUrl += urlPattern.port;
}
if (urlPattern.pathname === undefined) {
hasPathname = false;
}
else {
urlPattern.pathname = unescapeURLPattern(urlPattern.pathname);
if (urlPattern.pathname[0] !== '/') {
patternUrl += '/';
}
if (urlPattern.pathname.includes('#') ||
urlPattern.pathname.includes('?')) {
throw new InvalidArgumentException('Forbidden characters');
}
patternUrl += urlPattern.pathname;
}
if (urlPattern.search === undefined) {
hasSearch = false;
}
else {
urlPattern.search = unescapeURLPattern(urlPattern.search);
if (urlPattern.search[0] !== '?') {
patternUrl += '?';
}
if (urlPattern.search.includes('#')) {
throw new InvalidArgumentException('Forbidden characters');
}
patternUrl += urlPattern.search;
}
break;
}
}
const serializePort = (url) => {
const defaultPorts = {
'ftp:': 21,
'file:': null,
'http:': 80,
'https:': 443,
'ws:': 80,
'wss:': 443,
};
if (isSpecialScheme(url.protocol) &&
defaultPorts[url.protocol] !== null &&
(!url.port || String(defaultPorts[url.protocol]) === url.port)) {
return '';
}
else if (url.port) {
return url.port;
}
return undefined;
};
try {
const url = new URL(patternUrl);
return {
protocol: hasProtocol ? url.protocol.replace(/:$/, '') : undefined,
hostname: hasHostname ? url.hostname : undefined,
port: hasPort ? serializePort(url) : undefined,
pathname: hasPathname && url.pathname ? url.pathname : undefined,
search: hasSearch ? url.search : undefined,
};
}
catch (err) {
throw new InvalidArgumentException(`${err.message} '${patternUrl}'`);
}
});
}
static wrapInterceptionError(error) {
if (error?.message.includes('Invalid header') ||
error?.message.includes('Unsafe header')) {
return new InvalidArgumentException(error.message);
}
return error;
}
async addDataCollector(params) {
if (params.userContexts !== undefined && params.contexts !== undefined) {
throw new InvalidArgumentException("'contexts' and 'userContexts' are mutually exclusive");
}
if (params.userContexts !== undefined) {
await this.#userContextStorage.verifyUserContextIdList(params.userContexts);
}
if (params.contexts !== undefined) {
for (const browsingContextId of params.contexts) {
const browsingContext = this.#browsingContextStorage.getContext(browsingContextId);
if (!browsingContext.isTopLevelContext()) {
throw new InvalidArgumentException(`Data collectors are available only on top-level browsing contexts`);
}
}
}
const collectorId = this.#networkStorage.addDataCollector(params);
await this.#toggleNetwork();
return { collector: collectorId };
}
async getData(params) {
return await this.#networkStorage.getCollectedData(params);
}
async removeDataCollector(params) {
this.#networkStorage.removeDataCollector(params);
await this.#toggleNetwork();
return {};
}
disownData(params) {
this.#networkStorage.disownData(params);
return {};
}
async setExtraHeaders(params) {
if (params.userContexts !== undefined && params.contexts !== undefined) {
throw new InvalidArgumentException('contexts and userContexts are mutually exclusive');
}
const cdpExtraHeaders = parseBiDiHeaders(params.headers);
const affectedCdpTargets = new Set();
if (params.userContexts === undefined && params.contexts === undefined) {
this.#contextConfigStorage.updateGlobalConfig({
extraHeaders: cdpExtraHeaders,
});
this.#browsingContextStorage
.getAllContexts()
.forEach((c) => affectedCdpTargets.add(c.cdpTarget));
}
if (params.userContexts !== undefined) {
await this.#userContextStorage.verifyUserContextIdList(params.userContexts);
params.userContexts.forEach((userContext) => {
this.#contextConfigStorage.updateUserContextConfig(userContext, {
extraHeaders: cdpExtraHeaders,
});
this.#browsingContextStorage
.getAllContexts()
.filter((c) => c.userContext === userContext)
.forEach((c) => affectedCdpTargets.add(c.cdpTarget));
});
}
if (params.contexts !== undefined) {
this.#browsingContextStorage.verifyTopLevelContextsList(params.contexts);
params.contexts.forEach((browsingContextId) => {
this.#contextConfigStorage.updateBrowsingContextConfig(browsingContextId, { extraHeaders: cdpExtraHeaders });
affectedCdpTargets.add(this.#browsingContextStorage.getContext(browsingContextId).cdpTarget);
this.#browsingContextStorage
.getContext(browsingContextId)
.allChildren.forEach((c) => affectedCdpTargets.add(c.cdpTarget));
});
}
await Promise.all(Array.from(affectedCdpTargets).map((cdpTarget) => cdpTarget.setExtraHeaders(cdpExtraHeaders)));
return {};
}
}
function unescapeURLPattern(pattern) {
const forbidden = new Set(['(', ')', '*', '{', '}']);
let result = '';
let isEscaped = false;
for (const c of pattern) {
if (!isEscaped) {
if (forbidden.has(c)) {
throw new InvalidArgumentException('Forbidden characters');
}
if (c === '\\') {
isEscaped = true;
continue;
}
}
result += c;
isEscaped = false;
}
return result;
}
function parseBiDiHeaders(headers) {
const parsedHeaders = {};
for (const bidiHeader of headers) {
if (bidiHeader.value.type === 'string') {
if (parsedHeaders[bidiHeader.name] === undefined) {
parsedHeaders[bidiHeader.name] = bidiHeader.value.value;
}
else {
parsedHeaders[bidiHeader.name] =
`${parsedHeaders[bidiHeader.name]}, ${bidiHeader.value.value}`;
}
}
else {
throw new UnsupportedOperationException('Only string headers values are supported');
}
}
return parsedHeaders;
}
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PermissionsProcessor {
#browserCdpClient;
constructor(browserCdpClient) {
this.#browserCdpClient = browserCdpClient;
}
async setPermissions(params) {
try {
const userContextId = params['goog:userContext'] ||
params.userContext;
await this.#browserCdpClient.sendCommand('Browser.setPermission', {
origin: params.origin,
browserContextId: userContextId && userContextId !== 'default'
? userContextId
: undefined,
permission: {
name: params.descriptor.name,
},
setting: params.state,
});
}
catch (err) {
if (err.message ===
`Permission can't be granted to opaque origins.`) {
return {};
}
throw new InvalidArgumentException(err.message);
}
return {};
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function bytesToHex(bytes) {
return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
}
function uuidv4() {
if ('crypto' in globalThis && 'randomUUID' in globalThis.crypto) {
return globalThis.crypto.randomUUID();
}
const randomValues = new Uint8Array(16);
if ('crypto' in globalThis && 'getRandomValues' in globalThis.crypto) {
globalThis.crypto.getRandomValues(randomValues);
}
else {
require('crypto').webcrypto.getRandomValues(randomValues);
}
randomValues[6] = (randomValues[6] & 0x0f) | 0x40;
randomValues[8] = (randomValues[8] & 0x3f) | 0x80;
return [
bytesToHex(randomValues.subarray(0, 4)),
bytesToHex(randomValues.subarray(4, 6)),
bytesToHex(randomValues.subarray(6, 8)),
bytesToHex(randomValues.subarray(8, 10)),
bytesToHex(randomValues.subarray(10, 16)),
].join('-');
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
class ChannelProxy {
#properties;
#id = uuidv4();
#logger;
constructor(channel, logger) {
this.#properties = channel;
this.#logger = logger;
}
async init(realm, eventManager) {
const channelHandle = await ChannelProxy.#createAndGetHandleInRealm(realm);
const sendMessageHandle = await ChannelProxy.#createSendMessageHandle(realm, channelHandle);
void this.#startListener(realm, channelHandle, eventManager);
return sendMessageHandle;
}
async startListenerFromWindow(realm, eventManager) {
try {
const channelHandle = await this.#getHandleFromWindow(realm);
void this.#startListener(realm, channelHandle, eventManager);
}
catch (error) {
this.#logger?.(LogType.debugError, error);
}
}
static #createChannelProxyEvalStr() {
const functionStr = String(() => {
const queue = [];
let queueNonEmptyResolver = null;
return {
async getMessage() {
const onMessage = queue.length > 0
? Promise.resolve()
: new Promise((resolve) => {
queueNonEmptyResolver = resolve;
});
await onMessage;
return queue.shift();
},
sendMessage(message) {
queue.push(message);
if (queueNonEmptyResolver !== null) {
queueNonEmptyResolver();
queueNonEmptyResolver = null;
}
},
};
});
return `(${functionStr})()`;
}
static async #createAndGetHandleInRealm(realm) {
const createChannelHandleResult = await realm.cdpClient.sendCommand('Runtime.evaluate', {
expression: this.#createChannelProxyEvalStr(),
contextId: realm.executionContextId,
serializationOptions: {
serialization: "idOnly" ,
},
});
if (createChannelHandleResult.exceptionDetails ||
createChannelHandleResult.result.objectId === undefined) {
throw new Error(`Cannot create channel`);
}
return createChannelHandleResult.result.objectId;
}
static async #createSendMessageHandle(realm, channelHandle) {
const sendMessageArgResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((channelHandle) => {
return channelHandle.sendMessage;
}),
arguments: [{ objectId: channelHandle }],
executionContextId: realm.executionContextId,
serializationOptions: {
serialization: "idOnly" ,
},
});
return sendMessageArgResult.result.objectId;
}
async #startListener(realm, channelHandle, eventManager) {
for (;;) {
try {
const message = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String(async (channelHandle) => await channelHandle.getMessage()),
arguments: [
{
objectId: channelHandle,
},
],
awaitPromise: true,
executionContextId: realm.executionContextId,
serializationOptions: {
serialization: "deep" ,
maxDepth: this.#properties.serializationOptions?.maxObjectDepth ??
undefined,
},
});
if (message.exceptionDetails) {
throw new Error('Runtime.callFunctionOn in ChannelProxy', {
cause: message.exceptionDetails,
});
}
for (const browsingContext of realm.associatedBrowsingContexts) {
eventManager.registerEvent({
type: 'event',
method: Script$2.EventNames.Message,
params: {
channel: this.#properties.channel,
data: realm.cdpToBidiValue(message, this.#properties.ownership ?? "none" ),
source: realm.source,
},
}, browsingContext.id);
}
}
catch (error) {
this.#logger?.(LogType.debugError, error);
break;
}
}
}
async #getHandleFromWindow(realm) {
const channelHandleResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((id) => {
const w = window;
if (w[id] === undefined) {
return new Promise((resolve) => (w[id] = resolve));
}
const channelProxy = w[id];
delete w[id];
return channelProxy;
}),
arguments: [{ value: this.#id }],
executionContextId: realm.executionContextId,
awaitPromise: true,
serializationOptions: {
serialization: "idOnly" ,
},
});
if (channelHandleResult.exceptionDetails !== undefined ||
channelHandleResult.result.objectId === undefined) {
throw new Error(`ChannelHandle not found in window["${this.#id}"]`);
}
return channelHandleResult.result.objectId;
}
getEvalInWindowStr() {
const delegate = String((id, channelProxy) => {
const w = window;
if (w[id] === undefined) {
w[id] = channelProxy;
}
else {
w[id](channelProxy);
delete w[id];
}
return channelProxy.sendMessage;
});
const channelProxyEval = ChannelProxy.#createChannelProxyEvalStr();
return `(${delegate})('${this.#id}',${channelProxyEval})`;
}
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
class PreloadScript {
#id = uuidv4();
#cdpPreloadScripts = [];
#functionDeclaration;
#targetIds = new Set();
#channels;
#sandbox;
#contexts;
#userContexts;
get id() {
return this.#id;
}
get targetIds() {
return this.#targetIds;
}
constructor(params, logger) {
this.#channels =
params.arguments?.map((a) => new ChannelProxy(a.value, logger)) ?? [];
this.#functionDeclaration = params.functionDeclaration;
this.#sandbox = params.sandbox;
this.#contexts = params.contexts;
this.#userContexts = params.userContexts;
}
get channels() {
return this.#channels;
}
get contexts() {
return this.#contexts;
}
get userContexts() {
return this.#userContexts;
}
#getEvaluateString() {
const channelsArgStr = `[${this.channels
.map((c) => c.getEvalInWindowStr())
.join(', ')}]`;
return `(()=>{(${this.#functionDeclaration})(...${channelsArgStr})})()`;
}
async initInTargets(cdpTargets, runImmediately) {
await Promise.all(Array.from(cdpTargets).map((cdpTarget) => this.initInTarget(cdpTarget, runImmediately)));
}
async initInTarget(cdpTarget, runImmediately) {
const addCdpPreloadScriptResult = await cdpTarget.cdpClient.sendCommand('Page.addScriptToEvaluateOnNewDocument', {
source: this.#getEvaluateString(),
worldName: this.#sandbox,
runImmediately,
});
this.#cdpPreloadScripts.push({
target: cdpTarget,
preloadScriptId: addCdpPreloadScriptResult.identifier,
});
this.#targetIds.add(cdpTarget.id);
}
async remove() {
await Promise.all([
this.#cdpPreloadScripts.map(async (cdpPreloadScript) => {
const cdpTarget = cdpPreloadScript.target;
const cdpPreloadScriptId = cdpPreloadScript.preloadScriptId;
return await cdpTarget.cdpClient.sendCommand('Page.removeScriptToEvaluateOnNewDocument', {
identifier: cdpPreloadScriptId,
});
}),
]);
}
dispose(cdpTargetId) {
this.#cdpPreloadScripts = this.#cdpPreloadScripts.filter((cdpPreloadScript) => cdpPreloadScript.target?.id !== cdpTargetId);
this.#targetIds.delete(cdpTargetId);
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class ScriptProcessor {
#eventManager;
#browsingContextStorage;
#realmStorage;
#preloadScriptStorage;
#userContextStorage;
#logger;
constructor(eventManager, browsingContextStorage, realmStorage, preloadScriptStorage, userContextStorage, logger) {
this.#browsingContextStorage = browsingContextStorage;
this.#realmStorage = realmStorage;
this.#preloadScriptStorage = preloadScriptStorage;
this.#userContextStorage = userContextStorage;
this.#logger = logger;
this.#eventManager = eventManager;
this.#eventManager.addSubscribeHook(Script$2.EventNames.RealmCreated, this.#onRealmCreatedSubscribeHook.bind(this));
}
#onRealmCreatedSubscribeHook(contextId) {
const context = this.#browsingContextStorage.getContext(contextId);
const contextsToReport = [
context,
...this.#browsingContextStorage.getContext(contextId).allChildren,
];
const realms = new Set();
for (const reportContext of contextsToReport) {
const realmsForContext = this.#realmStorage.findRealms({
browsingContextId: reportContext.id,
});
for (const realm of realmsForContext) {
realms.add(realm);
}
}
for (const realm of realms) {
this.#eventManager.registerEvent({
type: 'event',
method: Script$2.EventNames.RealmCreated,
params: realm.realmInfo,
}, context.id);
}
return Promise.resolve();
}
async addPreloadScript(params) {
if (params.userContexts?.length && params.contexts?.length) {
throw new InvalidArgumentException('Both userContexts and contexts cannot be specified.');
}
const userContexts = await this.#userContextStorage.verifyUserContextIdList(params.userContexts ?? []);
const browsingContexts = this.#browsingContextStorage.verifyTopLevelContextsList(params.contexts);
const preloadScript = new PreloadScript(params, this.#logger);
this.#preloadScriptStorage.add(preloadScript);
let contextsToRunIn = [];
if (userContexts.size) {
contextsToRunIn = this.#browsingContextStorage
.getTopLevelContexts()
.filter((context) => {
return userContexts.has(context.userContext);
});
}
else if (browsingContexts.size) {
contextsToRunIn = [...browsingContexts.values()];
}
else {
contextsToRunIn = this.#browsingContextStorage.getTopLevelContexts();
}
const cdpTargets = new Set(contextsToRunIn.map((context) => context.cdpTarget));
await preloadScript.initInTargets(cdpTargets, false);
return {
script: preloadScript.id,
};
}
async removePreloadScript(params) {
const { script: id } = params;
const script = this.#preloadScriptStorage.getPreloadScript(id);
await script.remove();
this.#preloadScriptStorage.remove(id);
return {};
}
async callFunction(params) {
const realm = await this.#getRealm(params.target);
return await realm.callFunction(params.functionDeclaration, params.awaitPromise, params.this, params.arguments, params.resultOwnership, params.serializationOptions, params.userActivation);
}
async evaluate(params) {
const realm = await this.#getRealm(params.target);
return await realm.evaluate(params.expression, params.awaitPromise, params.resultOwnership, params.serializationOptions, params.userActivation);
}
async disown(params) {
const realm = await this.#getRealm(params.target);
await Promise.all(params.handles.map(async (handle) => await realm.disown(handle)));
return {};
}
getRealms(params) {
if (params.context !== undefined) {
this.#browsingContextStorage.getContext(params.context);
}
const realms = this.#realmStorage
.findRealms({
browsingContextId: params.context,
type: params.type,
isHidden: false,
})
.map((realm) => realm.realmInfo);
return { realms };
}
async #getRealm(target) {
if ('context' in target) {
const context = this.#browsingContextStorage.getContext(target.context);
return await context.getOrCreateUserSandbox(target.sandbox);
}
return this.#realmStorage.getRealm({
realmId: target.realm,
isHidden: false,
});
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class SessionProcessor {
#eventManager;
#browserCdpClient;
#initConnection;
#created = false;
constructor(eventManager, browserCdpClient, initConnection) {
this.#eventManager = eventManager;
this.#browserCdpClient = browserCdpClient;
this.#initConnection = initConnection;
}
status() {
return { ready: false, message: 'already connected' };
}
#mergeCapabilities(capabilitiesRequest) {
const mergedCapabilities = [];
for (const first of capabilitiesRequest.firstMatch ?? [{}]) {
const result = {
...capabilitiesRequest.alwaysMatch,
};
for (const key of Object.keys(first)) {
if (result[key] !== undefined) {
throw new InvalidArgumentException(`Capability ${key} in firstMatch is already defined in alwaysMatch`);
}
result[key] = first[key];
}
mergedCapabilities.push(result);
}
const match = mergedCapabilities.find((c) => c.browserName === 'chrome') ??
mergedCapabilities[0] ??
{};
match.unhandledPromptBehavior = this.#getUnhandledPromptBehavior(match.unhandledPromptBehavior);
return match;
}
#getUnhandledPromptBehavior(capabilityValue) {
if (capabilityValue === undefined) {
return undefined;
}
if (typeof capabilityValue === 'object') {
return capabilityValue;
}
if (typeof capabilityValue !== 'string') {
throw new InvalidArgumentException(`Unexpected 'unhandledPromptBehavior' type: ${typeof capabilityValue}`);
}
switch (capabilityValue) {
case 'accept':
case 'accept and notify':
return {
default: "accept" ,
beforeUnload: "accept" ,
};
case 'dismiss':
case 'dismiss and notify':
return {
default: "dismiss" ,
beforeUnload: "accept" ,
};
case 'ignore':
return {
default: "ignore" ,
beforeUnload: "accept" ,
};
default:
throw new InvalidArgumentException(`Unexpected 'unhandledPromptBehavior' value: ${capabilityValue}`);
}
}
async new(params) {
if (this.#created) {
throw new Error('Session has been already created.');
}
this.#created = true;
const matchedCapabitlites = this.#mergeCapabilities(params.capabilities);
await this.#initConnection(matchedCapabitlites);
const version = await this.#browserCdpClient.sendCommand('Browser.getVersion');
return {
sessionId: 'unknown',
capabilities: {
...matchedCapabitlites,
acceptInsecureCerts: matchedCapabitlites.acceptInsecureCerts ?? false,
browserName: version.product,
browserVersion: version.revision,
platformName: '',
setWindowRect: false,
webSocketUrl: '',
userAgent: version.userAgent,
},
};
}
async subscribe(params, googChannel = null) {
const subscription = await this.#eventManager.subscribe(params.events, params.contexts ?? [], params.userContexts ?? [], googChannel);
return {
subscription,
};
}
async unsubscribe(params, googChannel = null) {
if ('subscriptions' in params) {
await this.#eventManager.unsubscribeByIds(params.subscriptions);
return {};
}
await this.#eventManager.unsubscribe(params.events, params.contexts ?? [], googChannel);
return {};
}
}
class StorageProcessor {
#browserCdpClient;
#browsingContextStorage;
#logger;
constructor(browserCdpClient, browsingContextStorage, logger) {
this.#browsingContextStorage = browsingContextStorage;
this.#browserCdpClient = browserCdpClient;
this.#logger = logger;
}
async deleteCookies(params) {
const partitionKey = this.#expandStoragePartitionSpec(params.partition);
let cdpResponse;
try {
cdpResponse = await this.#browserCdpClient.sendCommand('Storage.getCookies', {
browserContextId: this.#getCdpBrowserContextId(partitionKey),
});
}
catch (err) {
if (this.#isNoSuchUserContextError(err)) {
throw new NoSuchUserContextException(err.message);
}
throw err;
}
const cdpCookiesToDelete = cdpResponse.cookies
.filter(
(c) => partitionKey.sourceOrigin === undefined ||
c.partitionKey?.topLevelSite === partitionKey.sourceOrigin)
.filter((cdpCookie) => {
const bidiCookie = cdpToBiDiCookie(cdpCookie);
return this.#matchCookie(bidiCookie, params.filter);
})
.map((cookie) => ({
...cookie,
expires: 1,
}));
await this.#browserCdpClient.sendCommand('Storage.setCookies', {
cookies: cdpCookiesToDelete,
browserContextId: this.#getCdpBrowserContextId(partitionKey),
});
return {
partitionKey,
};
}
async getCookies(params) {
const partitionKey = this.#expandStoragePartitionSpec(params.partition);
let cdpResponse;
try {
cdpResponse = await this.#browserCdpClient.sendCommand('Storage.getCookies', {
browserContextId: this.#getCdpBrowserContextId(partitionKey),
});
}
catch (err) {
if (this.#isNoSuchUserContextError(err)) {
throw new NoSuchUserContextException(err.message);
}
throw err;
}
const filteredBiDiCookies = cdpResponse.cookies
.filter(
(c) => partitionKey.sourceOrigin === undefined ||
c.partitionKey?.topLevelSite === partitionKey.sourceOrigin)
.map((c) => cdpToBiDiCookie(c))
.filter((c) => this.#matchCookie(c, params.filter));
return {
cookies: filteredBiDiCookies,
partitionKey,
};
}
async setCookie(params) {
const partitionKey = this.#expandStoragePartitionSpec(params.partition);
const cdpCookie = bidiToCdpCookie(params, partitionKey);
try {
await this.#browserCdpClient.sendCommand('Storage.setCookies', {
cookies: [cdpCookie],
browserContextId: this.#getCdpBrowserContextId(partitionKey),
});
}
catch (err) {
if (this.#isNoSuchUserContextError(err)) {
throw new NoSuchUserContextException(err.message);
}
this.#logger?.(LogType.debugError, err);
throw new UnableToSetCookieException(err.toString());
}
return {
partitionKey,
};
}
#isNoSuchUserContextError(err) {
return err.message?.startsWith('Failed to find browser context for id');
}
#getCdpBrowserContextId(partitionKey) {
return partitionKey.userContext === 'default'
? undefined
: partitionKey.userContext;
}
#expandStoragePartitionSpecByBrowsingContext(descriptor) {
const browsingContextId = descriptor.context;
const browsingContext = this.#browsingContextStorage.getContext(browsingContextId);
return {
userContext: browsingContext.userContext,
};
}
#expandStoragePartitionSpecByStorageKey(descriptor) {
const unsupportedPartitionKeys = new Map();
let sourceOrigin = descriptor.sourceOrigin;
if (sourceOrigin !== undefined) {
const url = NetworkProcessor.parseUrlString(sourceOrigin);
if (url.origin === 'null') {
sourceOrigin = url.origin;
}
else {
sourceOrigin = `${url.protocol}//${url.hostname}`;
}
}
for (const [key, value] of Object.entries(descriptor)) {
if (key !== undefined &&
value !== undefined &&
!['type', 'sourceOrigin', 'userContext'].includes(key)) {
unsupportedPartitionKeys.set(key, value);
}
}
if (unsupportedPartitionKeys.size > 0) {
this.#logger?.(LogType.debugInfo, `Unsupported partition keys: ${JSON.stringify(Object.fromEntries(unsupportedPartitionKeys))}`);
}
const userContext = descriptor.userContext ?? 'default';
return {
userContext,
...(sourceOrigin === undefined ? {} : { sourceOrigin }),
};
}
#expandStoragePartitionSpec(partitionSpec) {
if (partitionSpec === undefined) {
return { userContext: 'default' };
}
if (partitionSpec.type === 'context') {
return this.#expandStoragePartitionSpecByBrowsingContext(partitionSpec);
}
assert(partitionSpec.type === 'storageKey', 'Unknown partition type');
return this.#expandStoragePartitionSpecByStorageKey(partitionSpec);
}
#matchCookie(cookie, filter) {
if (filter === undefined) {
return true;
}
return ((filter.domain === undefined || filter.domain === cookie.domain) &&
(filter.name === undefined || filter.name === cookie.name) &&
(filter.value === undefined ||
deserializeByteValue(filter.value) ===
deserializeByteValue(cookie.value)) &&
(filter.path === undefined || filter.path === cookie.path) &&
(filter.size === undefined || filter.size === cookie.size) &&
(filter.httpOnly === undefined || filter.httpOnly === cookie.httpOnly) &&
(filter.secure === undefined || filter.secure === cookie.secure) &&
(filter.sameSite === undefined || filter.sameSite === cookie.sameSite) &&
(filter.expiry === undefined || filter.expiry === cookie.expiry));
}
}
/**
* Copyright 2025 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class WebExtensionProcessor {
#browserCdpClient;
constructor(browserCdpClient) {
this.#browserCdpClient = browserCdpClient;
}
async install(params) {
switch (params.extensionData.type) {
case 'archivePath':
case 'base64':
throw new UnsupportedOperationException('Archived and Base64 extensions are not supported');
}
try {
const response = await this.#browserCdpClient.sendCommand('Extensions.loadUnpacked', {
path: params.extensionData.path,
});
return {
extension: response.id,
};
}
catch (err) {
if (err.message.startsWith('invalid web extension')) {
throw new InvalidWebExtensionException(err.message);
}
throw err;
}
}
async uninstall(params) {
try {
await this.#browserCdpClient.sendCommand('Extensions.uninstall', {
id: params.extension,
});
return {};
}
catch (err) {
if (err.message ===
'Uninstall failed. Reason: could not find extension.') {
throw new NoSuchWebExtensionException('no such web extension');
}
throw err;
}
}
}
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class OutgoingMessage {
#message;
#googChannel;
constructor(message, googChannel = null) {
this.#message = message;
this.#googChannel = googChannel;
}
static createFromPromise(messagePromise, googChannel) {
return messagePromise.then((message) => {
if (message.kind === 'success') {
return {
kind: 'success',
value: new OutgoingMessage(message.value, googChannel),
};
}
return message;
});
}
static createResolved(message, googChannel = null) {
return Promise.resolve({
kind: 'success',
value: new OutgoingMessage(message, googChannel),
});
}
get message() {
return this.#message;
}
get googChannel() {
return this.#googChannel;
}
}
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class CommandProcessor extends EventEmitter {
#bluetoothProcessor;
#browserCdpClient;
#browserProcessor;
#browsingContextProcessor;
#cdpProcessor;
#emulationProcessor;
#inputProcessor;
#networkProcessor;
#permissionsProcessor;
#scriptProcessor;
#sessionProcessor;
#storageProcessor;
#webExtensionProcessor;
#parser;
#logger;
constructor(cdpConnection, browserCdpClient, eventManager, browsingContextStorage, realmStorage, preloadScriptStorage, networkStorage, contextConfigStorage, bluetoothProcessor, userContextStorage, parser = new BidiNoOpParser(), initConnection, logger) {
super();
this.#browserCdpClient = browserCdpClient;
this.#parser = parser;
this.#logger = logger;
this.#bluetoothProcessor = bluetoothProcessor;
this.#browserProcessor = new BrowserProcessor(browserCdpClient, browsingContextStorage, contextConfigStorage, userContextStorage);
this.#browsingContextProcessor = new BrowsingContextProcessor(browserCdpClient, browsingContextStorage, userContextStorage, contextConfigStorage, eventManager);
this.#cdpProcessor = new CdpProcessor(browsingContextStorage, realmStorage, cdpConnection, browserCdpClient);
this.#emulationProcessor = new EmulationProcessor(browsingContextStorage, userContextStorage, contextConfigStorage);
this.#inputProcessor = new InputProcessor(browsingContextStorage);
this.#networkProcessor = new NetworkProcessor(browsingContextStorage, networkStorage, userContextStorage, contextConfigStorage);
this.#permissionsProcessor = new PermissionsProcessor(browserCdpClient);
this.#scriptProcessor = new ScriptProcessor(eventManager, browsingContextStorage, realmStorage, preloadScriptStorage, userContextStorage, logger);
this.#sessionProcessor = new SessionProcessor(eventManager, browserCdpClient, initConnection);
this.#storageProcessor = new StorageProcessor(browserCdpClient, browsingContextStorage, logger);
this.#webExtensionProcessor = new WebExtensionProcessor(browserCdpClient);
}
async #processCommand(command) {
switch (command.method) {
case 'bluetooth.disableSimulation':
return await this.#bluetoothProcessor.disableSimulation(this.#parser.parseDisableSimulationParameters(command.params));
case 'bluetooth.handleRequestDevicePrompt':
return await this.#bluetoothProcessor.handleRequestDevicePrompt(this.#parser.parseHandleRequestDevicePromptParams(command.params));
case 'bluetooth.simulateAdapter':
return await this.#bluetoothProcessor.simulateAdapter(this.#parser.parseSimulateAdapterParameters(command.params));
case 'bluetooth.simulateAdvertisement':
return await this.#bluetoothProcessor.simulateAdvertisement(this.#parser.parseSimulateAdvertisementParameters(command.params));
case 'bluetooth.simulateCharacteristic':
return await this.#bluetoothProcessor.simulateCharacteristic(this.#parser.parseSimulateCharacteristicParameters(command.params));
case 'bluetooth.simulateCharacteristicResponse':
return await this.#bluetoothProcessor.simulateCharacteristicResponse(this.#parser.parseSimulateCharacteristicResponseParameters(command.params));
case 'bluetooth.simulateDescriptor':
return await this.#bluetoothProcessor.simulateDescriptor(this.#parser.parseSimulateDescriptorParameters(command.params));
case 'bluetooth.simulateDescriptorResponse':
return await this.#bluetoothProcessor.simulateDescriptorResponse(this.#parser.parseSimulateDescriptorResponseParameters(command.params));
case 'bluetooth.simulateGattConnectionResponse':
return await this.#bluetoothProcessor.simulateGattConnectionResponse(this.#parser.parseSimulateGattConnectionResponseParameters(command.params));
case 'bluetooth.simulateGattDisconnection':
return await this.#bluetoothProcessor.simulateGattDisconnection(this.#parser.parseSimulateGattDisconnectionParameters(command.params));
case 'bluetooth.simulatePreconnectedPeripheral':
return await this.#bluetoothProcessor.simulatePreconnectedPeripheral(this.#parser.parseSimulatePreconnectedPeripheralParameters(command.params));
case 'bluetooth.simulateService':
return await this.#bluetoothProcessor.simulateService(this.#parser.parseSimulateServiceParameters(command.params));
case 'browser.close':
return this.#browserProcessor.close();
case 'browser.createUserContext':
return await this.#browserProcessor.createUserContext(this.#parser.parseCreateUserContextParameters(command.params));
case 'browser.getClientWindows':
return await this.#browserProcessor.getClientWindows();
case 'browser.getUserContexts':
return await this.#browserProcessor.getUserContexts();
case 'browser.removeUserContext':
return await this.#browserProcessor.removeUserContext(this.#parser.parseRemoveUserContextParameters(command.params));
case 'browser.setClientWindowState':
this.#parser.parseSetClientWindowStateParameters(command.params);
throw new UnknownErrorException(`Method ${command.method} is not implemented.`);
case 'browsingContext.activate':
return await this.#browsingContextProcessor.activate(this.#parser.parseActivateParams(command.params));
case 'browsingContext.captureScreenshot':
return await this.#browsingContextProcessor.captureScreenshot(this.#parser.parseCaptureScreenshotParams(command.params));
case 'browsingContext.close':
return await this.#browsingContextProcessor.close(this.#parser.parseCloseParams(command.params));
case 'browsingContext.create':
return await this.#browsingContextProcessor.create(this.#parser.parseCreateParams(command.params));
case 'browsingContext.getTree':
return this.#browsingContextProcessor.getTree(this.#parser.parseGetTreeParams(command.params));
case 'browsingContext.handleUserPrompt':
return await this.#browsingContextProcessor.handleUserPrompt(this.#parser.parseHandleUserPromptParams(command.params));
case 'browsingContext.locateNodes':
return await this.#browsingContextProcessor.locateNodes(this.#parser.parseLocateNodesParams(command.params));
case 'browsingContext.navigate':
return await this.#browsingContextProcessor.navigate(this.#parser.parseNavigateParams(command.params));
case 'browsingContext.print':
return await this.#browsingContextProcessor.print(this.#parser.parsePrintParams(command.params));
case 'browsingContext.reload':
return await this.#browsingContextProcessor.reload(this.#parser.parseReloadParams(command.params));
case 'browsingContext.setViewport':
return await this.#browsingContextProcessor.setViewport(this.#parser.parseSetViewportParams(command.params));
case 'browsingContext.traverseHistory':
return await this.#browsingContextProcessor.traverseHistory(this.#parser.parseTraverseHistoryParams(command.params));
case 'goog:cdp.getSession':
return this.#cdpProcessor.getSession(this.#parser.parseGetSessionParams(command.params));
case 'goog:cdp.resolveRealm':
return this.#cdpProcessor.resolveRealm(this.#parser.parseResolveRealmParams(command.params));
case 'goog:cdp.sendCommand':
return await this.#cdpProcessor.sendCommand(this.#parser.parseSendCommandParams(command.params));
case 'emulation.setForcedColorsModeThemeOverride':
this.#parser.parseSetForcedColorsModeThemeOverrideParams(command.params);
throw new UnknownErrorException(`Method ${command.method} is not implemented.`);
case 'emulation.setGeolocationOverride':
return await this.#emulationProcessor.setGeolocationOverride(this.#parser.parseSetGeolocationOverrideParams(command.params));
case 'emulation.setLocaleOverride':
return await this.#emulationProcessor.setLocaleOverride(this.#parser.parseSetLocaleOverrideParams(command.params));
case 'emulation.setScreenOrientationOverride':
return await this.#emulationProcessor.setScreenOrientationOverride(this.#parser.parseSetScreenOrientationOverrideParams(command.params));
case 'emulation.setScriptingEnabled':
return await this.#emulationProcessor.setScriptingEnabled(this.#parser.parseSetScriptingEnabledParams(command.params));
case 'emulation.setTimezoneOverride':
return await this.#emulationProcessor.setTimezoneOverride(this.#parser.parseSetTimezoneOverrideParams(command.params));
case 'input.performActions':
return await this.#inputProcessor.performActions(this.#parser.parsePerformActionsParams(command.params));
case 'input.releaseActions':
return await this.#inputProcessor.releaseActions(this.#parser.parseReleaseActionsParams(command.params));
case 'input.setFiles':
return await this.#inputProcessor.setFiles(this.#parser.parseSetFilesParams(command.params));
case 'network.addDataCollector':
return await this.#networkProcessor.addDataCollector(this.#parser.parseAddDataCollectorParams(command.params));
case 'network.addIntercept':
return await this.#networkProcessor.addIntercept(this.#parser.parseAddInterceptParams(command.params));
case 'network.continueRequest':
return await this.#networkProcessor.continueRequest(this.#parser.parseContinueRequestParams(command.params));
case 'network.continueResponse':
return await this.#networkProcessor.continueResponse(this.#parser.parseContinueResponseParams(command.params));
case 'network.continueWithAuth':
return await this.#networkProcessor.continueWithAuth(this.#parser.parseContinueWithAuthParams(command.params));
case 'network.disownData':
return this.#networkProcessor.disownData(this.#parser.parseDisownDataParams(command.params));
case 'network.failRequest':
return await this.#networkProcessor.failRequest(this.#parser.parseFailRequestParams(command.params));
case 'network.getData':
return await this.#networkProcessor.getData(this.#parser.parseGetDataParams(command.params));
case 'network.provideResponse':
return await this.#networkProcessor.provideResponse(this.#parser.parseProvideResponseParams(command.params));
case 'network.removeDataCollector':
return await this.#networkProcessor.removeDataCollector(this.#parser.parseRemoveDataCollectorParams(command.params));
case 'network.removeIntercept':
return await this.#networkProcessor.removeIntercept(this.#parser.parseRemoveInterceptParams(command.params));
case 'network.setCacheBehavior':
return await this.#networkProcessor.setCacheBehavior(this.#parser.parseSetCacheBehaviorParams(command.params));
case 'network.setExtraHeaders':
return await this.#networkProcessor.setExtraHeaders(this.#parser.parseSetExtraHeadersParams(command.params));
case 'permissions.setPermission':
return await this.#permissionsProcessor.setPermissions(this.#parser.parseSetPermissionsParams(command.params));
case 'script.addPreloadScript':
return await this.#scriptProcessor.addPreloadScript(this.#parser.parseAddPreloadScriptParams(command.params));
case 'script.callFunction':
return await this.#scriptProcessor.callFunction(this.#parser.parseCallFunctionParams(this.#processTargetParams(command.params)));
case 'script.disown':
return await this.#scriptProcessor.disown(this.#parser.parseDisownParams(this.#processTargetParams(command.params)));
case 'script.evaluate':
return await this.#scriptProcessor.evaluate(this.#parser.parseEvaluateParams(this.#processTargetParams(command.params)));
case 'script.getRealms':
return this.#scriptProcessor.getRealms(this.#parser.parseGetRealmsParams(command.params));
case 'script.removePreloadScript':
return await this.#scriptProcessor.removePreloadScript(this.#parser.parseRemovePreloadScriptParams(command.params));
case 'session.end':
throw new UnknownErrorException(`Method ${command.method} is not implemented.`);
case 'session.new':
return await this.#sessionProcessor.new(command.params);
case 'session.status':
return this.#sessionProcessor.status();
case 'session.subscribe':
return await this.#sessionProcessor.subscribe(this.#parser.parseSubscribeParams(command.params), command['goog:channel']);
case 'session.unsubscribe':
return await this.#sessionProcessor.unsubscribe(this.#parser.parseUnsubscribeParams(command.params), command['goog:channel']);
case 'storage.deleteCookies':
return await this.#storageProcessor.deleteCookies(this.#parser.parseDeleteCookiesParams(command.params));
case 'storage.getCookies':
return await this.#storageProcessor.getCookies(this.#parser.parseGetCookiesParams(command.params));
case 'storage.setCookie':
return await this.#storageProcessor.setCookie(this.#parser.parseSetCookieParams(command.params));
case 'webExtension.install':
return await this.#webExtensionProcessor.install(this.#parser.parseInstallParams(command.params));
case 'webExtension.uninstall':
return await this.#webExtensionProcessor.uninstall(this.#parser.parseUninstallParams(command.params));
}
throw new UnknownCommandException(`Unknown command '${command?.method}'.`);
}
#processTargetParams(params) {
if (typeof params === 'object' &&
params &&
'target' in params &&
typeof params.target === 'object' &&
params.target &&
'context' in params.target) {
delete params.target['realm'];
}
return params;
}
async processCommand(command) {
try {
const result = await this.#processCommand(command);
const response = {
type: 'success',
id: command.id,
result,
};
this.emit("response" , {
message: OutgoingMessage.createResolved(response, command['goog:channel']),
event: command.method,
});
}
catch (e) {
if (e instanceof Exception) {
this.emit("response" , {
message: OutgoingMessage.createResolved(e.toErrorResponse(command.id), command['goog:channel']),
event: command.method,
});
}
else {
const error = e;
this.#logger?.(LogType.bidi, error);
const errorException = this.#browserCdpClient.isCloseError(e)
? new NoSuchFrameException(`Browsing context is gone`)
: new UnknownErrorException(error.message, error.stack);
this.emit("response" , {
message: OutgoingMessage.createResolved(errorException.toErrorResponse(command.id), command['goog:channel']),
event: command.method,
});
}
}
}
}
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class BluetoothGattItem {
id;
uuid;
constructor(id, uuid) {
this.id = id;
this.uuid = uuid;
}
}
class BluetoothDescriptor extends BluetoothGattItem {
characteristic;
constructor(id, uuid, characteristic) {
super(id, uuid);
this.characteristic = characteristic;
}
}
class BluetoothCharacteristic extends BluetoothGattItem {
descriptors = new Map();
service;
constructor(id, uuid, service) {
super(id, uuid);
this.service = service;
}
}
class BluetoothService extends BluetoothGattItem {
characteristics = new Map();
device;
constructor(id, uuid, device) {
super(id, uuid);
this.device = device;
}
}
class BluetoothDevice {
address;
services = new Map();
constructor(address) {
this.address = address;
}
}
class BluetoothProcessor {
#eventManager;
#browsingContextStorage;
#bluetoothDevices = new Map();
#bluetoothCharacteristics = new Map();
#bluetoothDescriptors = new Map();
constructor(eventManager, browsingContextStorage) {
this.#eventManager = eventManager;
this.#browsingContextStorage = browsingContextStorage;
}
#getDevice(address) {
const device = this.#bluetoothDevices.get(address);
if (!device) {
throw new InvalidArgumentException(`Bluetooth device with address ${address} does not exist`);
}
return device;
}
#getService(device, serviceUuid) {
const service = device.services.get(serviceUuid);
if (!service) {
throw new InvalidArgumentException(`Service with UUID ${serviceUuid} on device ${device.address} does not exist`);
}
return service;
}
#getCharacteristic(service, characteristicUuid) {
const characteristic = service.characteristics.get(characteristicUuid);
if (!characteristic) {
throw new InvalidArgumentException(`Characteristic with UUID ${characteristicUuid} does not exist for service ${service.uuid} on device ${service.device.address}`);
}
return characteristic;
}
#getDescriptor(characteristic, descriptorUuid) {
const descriptor = characteristic.descriptors.get(descriptorUuid);
if (!descriptor) {
throw new InvalidArgumentException(`Descriptor with UUID ${descriptorUuid} does not exist for characteristic ${characteristic.uuid} on service ${characteristic.service.uuid} on device ${characteristic.service.device.address}`);
}
return descriptor;
}
async simulateAdapter(params) {
if (params.state === undefined) {
throw new InvalidArgumentException(`Parameter "state" is required for creating a Bluetooth adapter`);
}
const context = this.#browsingContextStorage.getContext(params.context);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.disable');
this.#bluetoothDevices.clear();
this.#bluetoothCharacteristics.clear();
this.#bluetoothDescriptors.clear();
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.enable', {
state: params.state,
leSupported: params.leSupported ?? true,
});
return {};
}
async disableSimulation(params) {
const context = this.#browsingContextStorage.getContext(params.context);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.disable');
this.#bluetoothDevices.clear();
this.#bluetoothCharacteristics.clear();
this.#bluetoothDescriptors.clear();
return {};
}
async simulatePreconnectedPeripheral(params) {
if (this.#bluetoothDevices.has(params.address)) {
throw new InvalidArgumentException(`Bluetooth device with address ${params.address} already exists`);
}
const context = this.#browsingContextStorage.getContext(params.context);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulatePreconnectedPeripheral', {
address: params.address,
name: params.name,
knownServiceUuids: params.knownServiceUuids,
manufacturerData: params.manufacturerData,
});
this.#bluetoothDevices.set(params.address, new BluetoothDevice(params.address));
return {};
}
async simulateAdvertisement(params) {
const context = this.#browsingContextStorage.getContext(params.context);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateAdvertisement', {
entry: params.scanEntry,
});
return {};
}
async simulateCharacteristic(params) {
const device = this.#getDevice(params.address);
const service = this.#getService(device, params.serviceUuid);
const context = this.#browsingContextStorage.getContext(params.context);
switch (params.type) {
case 'add': {
if (params.characteristicProperties === undefined) {
throw new InvalidArgumentException(`Parameter "characteristicProperties" is required for adding a Bluetooth characteristic`);
}
if (service.characteristics.has(params.characteristicUuid)) {
throw new InvalidArgumentException(`Characteristic with UUID ${params.characteristicUuid} already exists`);
}
const response = await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.addCharacteristic', {
serviceId: service.id,
characteristicUuid: params.characteristicUuid,
properties: params.characteristicProperties,
});
const characteristic = new BluetoothCharacteristic(response.characteristicId, params.characteristicUuid, service);
service.characteristics.set(params.characteristicUuid, characteristic);
this.#bluetoothCharacteristics.set(characteristic.id, characteristic);
return {};
}
case 'remove': {
if (params.characteristicProperties !== undefined) {
throw new InvalidArgumentException(`Parameter "characteristicProperties" should not be provided for removing a Bluetooth characteristic`);
}
const characteristic = this.#getCharacteristic(service, params.characteristicUuid);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.removeCharacteristic', {
characteristicId: characteristic.id,
});
service.characteristics.delete(params.characteristicUuid);
this.#bluetoothCharacteristics.delete(characteristic.id);
return {};
}
default:
throw new InvalidArgumentException(`Parameter "type" of ${params.type} is not supported`);
}
}
async simulateCharacteristicResponse(params) {
const context = this.#browsingContextStorage.getContext(params.context);
const device = this.#getDevice(params.address);
const service = this.#getService(device, params.serviceUuid);
const characteristic = this.#getCharacteristic(service, params.characteristicUuid);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateCharacteristicOperationResponse', {
characteristicId: characteristic.id,
type: params.type,
code: params.code,
...(params.data && {
data: btoa(String.fromCharCode(...params.data)),
}),
});
return {};
}
async simulateDescriptor(params) {
const device = this.#getDevice(params.address);
const service = this.#getService(device, params.serviceUuid);
const characteristic = this.#getCharacteristic(service, params.characteristicUuid);
const context = this.#browsingContextStorage.getContext(params.context);
switch (params.type) {
case 'add': {
if (characteristic.descriptors.has(params.descriptorUuid)) {
throw new InvalidArgumentException(`Descriptor with UUID ${params.descriptorUuid} already exists`);
}
const response = await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.addDescriptor', {
characteristicId: characteristic.id,
descriptorUuid: params.descriptorUuid,
});
const descriptor = new BluetoothDescriptor(response.descriptorId, params.descriptorUuid, characteristic);
characteristic.descriptors.set(params.descriptorUuid, descriptor);
this.#bluetoothDescriptors.set(descriptor.id, descriptor);
return {};
}
case 'remove': {
const descriptor = this.#getDescriptor(characteristic, params.descriptorUuid);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.removeDescriptor', {
descriptorId: descriptor.id,
});
characteristic.descriptors.delete(params.descriptorUuid);
this.#bluetoothDescriptors.delete(descriptor.id);
return {};
}
default:
throw new InvalidArgumentException(`Parameter "type" of ${params.type} is not supported`);
}
}
async simulateDescriptorResponse(params) {
const context = this.#browsingContextStorage.getContext(params.context);
const device = this.#getDevice(params.address);
const service = this.#getService(device, params.serviceUuid);
const characteristic = this.#getCharacteristic(service, params.characteristicUuid);
const descriptor = this.#getDescriptor(characteristic, params.descriptorUuid);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateDescriptorOperationResponse', {
descriptorId: descriptor.id,
type: params.type,
code: params.code,
...(params.data && {
data: btoa(String.fromCharCode(...params.data)),
}),
});
return {};
}
async simulateGattConnectionResponse(params) {
const context = this.#browsingContextStorage.getContext(params.context);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateGATTOperationResponse', {
address: params.address,
type: 'connection',
code: params.code,
});
return {};
}
async simulateGattDisconnection(params) {
const context = this.#browsingContextStorage.getContext(params.context);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateGATTDisconnection', {
address: params.address,
});
return {};
}
async simulateService(params) {
const device = this.#getDevice(params.address);
const context = this.#browsingContextStorage.getContext(params.context);
switch (params.type) {
case 'add': {
if (device.services.has(params.uuid)) {
throw new InvalidArgumentException(`Service with UUID ${params.uuid} already exists`);
}
const response = await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.addService', {
address: params.address,
serviceUuid: params.uuid,
});
device.services.set(params.uuid, new BluetoothService(response.serviceId, params.uuid, device));
return {};
}
case 'remove': {
const service = this.#getService(device, params.uuid);
await context.cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.removeService', {
serviceId: service.id,
});
device.services.delete(params.uuid);
return {};
}
default:
throw new InvalidArgumentException(`Parameter "type" of ${params.type} is not supported`);
}
}
onCdpTargetCreated(cdpTarget) {
cdpTarget.cdpClient.on('DeviceAccess.deviceRequestPrompted', (event) => {
this.#eventManager.registerEvent({
type: 'event',
method: 'bluetooth.requestDevicePromptUpdated',
params: {
context: cdpTarget.id,
prompt: event.id,
devices: event.devices,
},
}, cdpTarget.id);
});
cdpTarget.browserCdpClient.on('BluetoothEmulation.gattOperationReceived', async (event) => {
switch (event.type) {
case 'connection':
this.#eventManager.registerEvent({
type: 'event',
method: 'bluetooth.gattConnectionAttempted',
params: {
context: cdpTarget.id,
address: event.address,
},
}, cdpTarget.id);
return;
case 'discovery':
await cdpTarget.browserCdpClient.sendCommand('BluetoothEmulation.simulateGATTOperationResponse', {
address: event.address,
type: 'discovery',
code: 0x0,
});
}
});
cdpTarget.browserCdpClient.on('BluetoothEmulation.characteristicOperationReceived', (event) => {
if (!this.#bluetoothCharacteristics.has(event.characteristicId)) {
return;
}
let type;
if (event.type === 'write') {
if (event.writeType === 'write-default-deprecated') {
return;
}
type = event.writeType;
}
else {
type = event.type;
}
const characteristic = this.#bluetoothCharacteristics.get(event.characteristicId);
this.#eventManager.registerEvent({
type: 'event',
method: 'bluetooth.characteristicEventGenerated',
params: {
context: cdpTarget.id,
address: characteristic.service.device.address,
serviceUuid: characteristic.service.uuid,
characteristicUuid: characteristic.uuid,
type,
...(event.data && {
data: Array.from(atob(event.data), (c) => c.charCodeAt(0)),
}),
},
}, cdpTarget.id);
});
cdpTarget.browserCdpClient.on('BluetoothEmulation.descriptorOperationReceived', (event) => {
if (!this.#bluetoothDescriptors.has(event.descriptorId)) {
return;
}
const descriptor = this.#bluetoothDescriptors.get(event.descriptorId);
this.#eventManager.registerEvent({
type: 'event',
method: 'bluetooth.descriptorEventGenerated',
params: {
context: cdpTarget.id,
address: descriptor.characteristic.service.device.address,
serviceUuid: descriptor.characteristic.service.uuid,
characteristicUuid: descriptor.characteristic.uuid,
descriptorUuid: descriptor.uuid,
type: event.type,
...(event.data && {
data: Array.from(atob(event.data), (c) => c.charCodeAt(0)),
}),
},
}, cdpTarget.id);
});
}
async handleRequestDevicePrompt(params) {
const context = this.#browsingContextStorage.getContext(params.context);
if (params.accept) {
await context.cdpTarget.cdpClient.sendCommand('DeviceAccess.selectPrompt', {
id: params.prompt,
deviceId: params.device,
});
}
else {
await context.cdpTarget.cdpClient.sendCommand('DeviceAccess.cancelPrompt', {
id: params.prompt,
});
}
return {};
}
}
/**
* Copyright 2025 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class ContextConfig {
acceptInsecureCerts;
viewport;
devicePixelRatio;
extraHeaders;
geolocation;
locale;
prerenderingDisabled;
screenOrientation;
scriptingEnabled;
timezone;
userPromptHandler;
static merge(...configs) {
const result = new ContextConfig();
for (const config of configs) {
if (!config) {
continue;
}
for (const key in config) {
const value = config[key];
if (value !== undefined) {
result[key] = value;
}
}
}
return result;
}
}
/*
* Copyright 2025 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class ContextConfigStorage {
#global = new ContextConfig();
#userContextConfigs = new Map();
#browsingContextConfigs = new Map();
updateGlobalConfig(config) {
this.#global = ContextConfig.merge(this.#global, config);
}
updateBrowsingContextConfig(browsingContextId, config) {
this.#browsingContextConfigs.set(browsingContextId, ContextConfig.merge(this.#browsingContextConfigs.get(browsingContextId), config));
}
updateUserContextConfig(userContext, config) {
this.#userContextConfigs.set(userContext, ContextConfig.merge(this.#userContextConfigs.get(userContext), config));
}
getGlobalConfig() {
return this.#global;
}
getActiveConfig(topLevelBrowsingContextId, userContext) {
return ContextConfig.merge(this.#global, this.#userContextConfigs.get(userContext), this.#browsingContextConfigs.get(topLevelBrowsingContextId));
}
}
/**
* Copyright 2025 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class UserContextStorage {
#browserClient;
constructor(browserClient) {
this.#browserClient = browserClient;
}
async getUserContexts() {
const result = await this.#browserClient.sendCommand('Target.getBrowserContexts');
return [
{
userContext: 'default',
},
...result.browserContextIds.map((id) => {
return {
userContext: id,
};
}),
];
}
async verifyUserContextIdList(userContextIds) {
const foundContexts = new Set();
if (!userContextIds.length) {
return foundContexts;
}
const userContexts = await this.getUserContexts();
const knownUserContextIds = new Set(userContexts.map((userContext) => userContext.userContext));
for (const userContextId of userContextIds) {
if (!knownUserContextIds.has(userContextId)) {
throw new NoSuchUserContextException(`User context ${userContextId} not found`);
}
foundContexts.add(userContextId);
}
return foundContexts;
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Deferred {
#isFinished = false;
#promise;
#result;
#resolve;
#reject;
get isFinished() {
return this.#isFinished;
}
get result() {
if (!this.#isFinished) {
throw new Error('Deferred is not finished yet');
}
return this.#result;
}
constructor() {
this.#promise = new Promise((resolve, reject) => {
this.#resolve = resolve;
this.#reject = reject;
});
this.#promise.catch((_error) => {
});
}
then(onFulfilled, onRejected) {
return this.#promise.then(onFulfilled, onRejected);
}
catch(onRejected) {
return this.#promise.catch(onRejected);
}
resolve(value) {
this.#result = value;
if (!this.#isFinished) {
this.#isFinished = true;
this.#resolve(value);
}
}
reject(reason) {
if (!this.#isFinished) {
this.#isFinished = true;
this.#reject(reason);
}
}
finally(onFinally) {
return this.#promise.finally(onFinally);
}
[Symbol.toStringTag] = 'Promise';
}
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function getTimestamp() {
return new Date().getTime();
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function inchesFromCm(cm) {
return cm / 2.54;
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const SHARED_ID_DIVIDER = '_element_';
function getSharedId(frameId, documentId, backendNodeId) {
return `f.${frameId}.d.${documentId}.e.${backendNodeId}`;
}
function parseLegacySharedId(sharedId) {
const match = sharedId.match(new RegExp(`(.*)${SHARED_ID_DIVIDER}(.*)`));
if (!match) {
return null;
}
const documentId = match[1];
const elementId = match[2];
if (documentId === undefined || elementId === undefined) {
return null;
}
const backendNodeId = parseInt(elementId ?? '');
if (isNaN(backendNodeId)) {
return null;
}
return {
documentId,
backendNodeId,
};
}
function parseSharedId(sharedId) {
const legacyFormattedSharedId = parseLegacySharedId(sharedId);
if (legacyFormattedSharedId !== null) {
return { ...legacyFormattedSharedId, frameId: undefined };
}
const match = sharedId.match(/f\.(.*)\.d\.(.*)\.e\.([0-9]*)/);
if (!match) {
return null;
}
const frameId = match[1];
const documentId = match[2];
const elementId = match[3];
if (frameId === undefined ||
documentId === undefined ||
elementId === undefined) {
return null;
}
const backendNodeId = parseInt(elementId ?? '');
if (isNaN(backendNodeId)) {
return null;
}
return {
frameId,
documentId,
backendNodeId,
};
}
class Realm {
#cdpClient;
#eventManager;
#executionContextId;
#logger;
#origin;
#realmId;
realmStorage;
constructor(cdpClient, eventManager, executionContextId, logger, origin, realmId, realmStorage) {
this.#cdpClient = cdpClient;
this.#eventManager = eventManager;
this.#executionContextId = executionContextId;
this.#logger = logger;
this.#origin = origin;
this.#realmId = realmId;
this.realmStorage = realmStorage;
this.realmStorage.addRealm(this);
}
cdpToBidiValue(cdpValue, resultOwnership) {
const bidiValue = this.serializeForBiDi(cdpValue.result.deepSerializedValue, new Map());
if (cdpValue.result.objectId) {
const objectId = cdpValue.result.objectId;
if (resultOwnership === "root" ) {
bidiValue.handle = objectId;
this.realmStorage.knownHandlesToRealmMap.set(objectId, this.realmId);
}
else {
void this.#releaseObject(objectId).catch((error) => this.#logger?.(LogType.debugError, error));
}
}
return bidiValue;
}
isHidden() {
return false;
}
serializeForBiDi(deepSerializedValue, internalIdMap) {
if (Object.hasOwn(deepSerializedValue, 'weakLocalObjectReference')) {
const weakLocalObjectReference = deepSerializedValue.weakLocalObjectReference;
if (!internalIdMap.has(weakLocalObjectReference)) {
internalIdMap.set(weakLocalObjectReference, uuidv4());
}
deepSerializedValue.internalId = internalIdMap.get(weakLocalObjectReference);
delete deepSerializedValue['weakLocalObjectReference'];
}
if (deepSerializedValue.type === 'node' &&
deepSerializedValue.value &&
Object.hasOwn(deepSerializedValue.value, 'frameId')) {
delete deepSerializedValue.value['frameId'];
}
if (deepSerializedValue.type === 'platformobject') {
return { type: 'object' };
}
const bidiValue = deepSerializedValue.value;
if (bidiValue === undefined) {
return deepSerializedValue;
}
if (['array', 'set', 'htmlcollection', 'nodelist'].includes(deepSerializedValue.type)) {
for (const i in bidiValue) {
bidiValue[i] = this.serializeForBiDi(bidiValue[i], internalIdMap);
}
}
if (['object', 'map'].includes(deepSerializedValue.type)) {
for (const i in bidiValue) {
bidiValue[i] = [
this.serializeForBiDi(bidiValue[i][0], internalIdMap),
this.serializeForBiDi(bidiValue[i][1], internalIdMap),
];
}
}
return deepSerializedValue;
}
get realmId() {
return this.#realmId;
}
get executionContextId() {
return this.#executionContextId;
}
get origin() {
return this.#origin;
}
get source() {
return {
realm: this.realmId,
};
}
get cdpClient() {
return this.#cdpClient;
}
get baseInfo() {
return {
realm: this.realmId,
origin: this.origin,
};
}
async evaluate(expression, awaitPromise, resultOwnership = "none" , serializationOptions = {}, userActivation = false, includeCommandLineApi = false) {
const cdpEvaluateResult = await this.cdpClient.sendCommand('Runtime.evaluate', {
contextId: this.executionContextId,
expression,
awaitPromise,
serializationOptions: Realm.#getSerializationOptions("deep" , serializationOptions),
userGesture: userActivation,
includeCommandLineAPI: includeCommandLineApi,
});
if (cdpEvaluateResult.exceptionDetails) {
return await this.#getExceptionResult(cdpEvaluateResult.exceptionDetails, 0, resultOwnership);
}
return {
realm: this.realmId,
result: this.cdpToBidiValue(cdpEvaluateResult, resultOwnership),
type: 'success',
};
}
#registerEvent(event) {
if (this.associatedBrowsingContexts.length === 0) {
this.#eventManager.registerGlobalEvent(event);
}
else {
for (const browsingContext of this.associatedBrowsingContexts) {
this.#eventManager.registerEvent(event, browsingContext.id);
}
}
}
initialize() {
if (!this.isHidden()) {
this.#registerEvent({
type: 'event',
method: Script$2.EventNames.RealmCreated,
params: this.realmInfo,
});
}
}
async serializeCdpObject(cdpRemoteObject, resultOwnership) {
const argument = Realm.#cdpRemoteObjectToCallArgument(cdpRemoteObject);
const cdpValue = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((remoteObject) => remoteObject),
awaitPromise: false,
arguments: [argument],
serializationOptions: {
serialization: "deep" ,
},
executionContextId: this.executionContextId,
});
return this.cdpToBidiValue(cdpValue, resultOwnership);
}
static #cdpRemoteObjectToCallArgument(cdpRemoteObject) {
if (cdpRemoteObject.objectId !== undefined) {
return { objectId: cdpRemoteObject.objectId };
}
if (cdpRemoteObject.unserializableValue !== undefined) {
return { unserializableValue: cdpRemoteObject.unserializableValue };
}
return { value: cdpRemoteObject.value };
}
async stringifyObject(cdpRemoteObject) {
const { result } = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((remoteObject) => String(remoteObject)),
awaitPromise: false,
arguments: [cdpRemoteObject],
returnByValue: true,
executionContextId: this.executionContextId,
});
return result.value;
}
async #flattenKeyValuePairs(mappingLocalValue) {
const keyValueArray = await Promise.all(mappingLocalValue.map(async ([key, value]) => {
let keyArg;
if (typeof key === 'string') {
keyArg = { value: key };
}
else {
keyArg = await this.deserializeForCdp(key);
}
const valueArg = await this.deserializeForCdp(value);
return [keyArg, valueArg];
}));
return keyValueArray.flat();
}
async #flattenValueList(listLocalValue) {
return await Promise.all(listLocalValue.map((localValue) => this.deserializeForCdp(localValue)));
}
async #serializeCdpExceptionDetails(cdpExceptionDetails, lineOffset, resultOwnership) {
const callFrames = cdpExceptionDetails.stackTrace?.callFrames.map((frame) => ({
url: frame.url,
functionName: frame.functionName,
lineNumber: frame.lineNumber - lineOffset,
columnNumber: frame.columnNumber,
})) ?? [];
const exception = cdpExceptionDetails.exception;
return {
exception: await this.serializeCdpObject(exception, resultOwnership),
columnNumber: cdpExceptionDetails.columnNumber,
lineNumber: cdpExceptionDetails.lineNumber - lineOffset,
stackTrace: {
callFrames,
},
text: (await this.stringifyObject(exception)) || cdpExceptionDetails.text,
};
}
async callFunction(functionDeclaration, awaitPromise, thisLocalValue = {
type: 'undefined',
}, argumentsLocalValues = [], resultOwnership = "none" , serializationOptions = {}, userActivation = false) {
const callFunctionAndSerializeScript = `(...args) => {
function callFunction(f, args) {
const deserializedThis = args.shift();
const deserializedArgs = args;
return f.apply(deserializedThis, deserializedArgs);
}
return callFunction((
${functionDeclaration}
), args);
}`;
const thisAndArgumentsList = [
await this.deserializeForCdp(thisLocalValue),
...(await Promise.all(argumentsLocalValues.map(async (argumentLocalValue) => await this.deserializeForCdp(argumentLocalValue)))),
];
let cdpCallFunctionResult;
try {
cdpCallFunctionResult = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: callFunctionAndSerializeScript,
awaitPromise,
arguments: thisAndArgumentsList,
serializationOptions: Realm.#getSerializationOptions("deep" , serializationOptions),
executionContextId: this.executionContextId,
userGesture: userActivation,
});
}
catch (error) {
if (error.code === -32e3 &&
[
'Could not find object with given id',
'Argument should belong to the same JavaScript world as target object',
'Invalid remote object id',
].includes(error.message)) {
throw new NoSuchHandleException('Handle was not found.');
}
throw error;
}
if (cdpCallFunctionResult.exceptionDetails) {
return await this.#getExceptionResult(cdpCallFunctionResult.exceptionDetails, 1, resultOwnership);
}
return {
type: 'success',
result: this.cdpToBidiValue(cdpCallFunctionResult, resultOwnership),
realm: this.realmId,
};
}
async deserializeForCdp(localValue) {
if ('handle' in localValue && localValue.handle) {
return { objectId: localValue.handle };
}
else if ('handle' in localValue || 'sharedId' in localValue) {
throw new NoSuchHandleException('Handle was not found.');
}
switch (localValue.type) {
case 'undefined':
return { unserializableValue: 'undefined' };
case 'null':
return { unserializableValue: 'null' };
case 'string':
return { value: localValue.value };
case 'number':
if (localValue.value === 'NaN') {
return { unserializableValue: 'NaN' };
}
else if (localValue.value === '-0') {
return { unserializableValue: '-0' };
}
else if (localValue.value === 'Infinity') {
return { unserializableValue: 'Infinity' };
}
else if (localValue.value === '-Infinity') {
return { unserializableValue: '-Infinity' };
}
return {
value: localValue.value,
};
case 'boolean':
return { value: Boolean(localValue.value) };
case 'bigint':
return {
unserializableValue: `BigInt(${JSON.stringify(localValue.value)})`,
};
case 'date':
return {
unserializableValue: `new Date(Date.parse(${JSON.stringify(localValue.value)}))`,
};
case 'regexp':
return {
unserializableValue: `new RegExp(${JSON.stringify(localValue.value.pattern)}, ${JSON.stringify(localValue.value.flags)})`,
};
case 'map': {
const keyValueArray = await this.#flattenKeyValuePairs(localValue.value);
const { result } = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((...args) => {
const result = new Map();
for (let i = 0; i < args.length; i += 2) {
result.set(args[i], args[i + 1]);
}
return result;
}),
awaitPromise: false,
arguments: keyValueArray,
returnByValue: false,
executionContextId: this.executionContextId,
});
return { objectId: result.objectId };
}
case 'object': {
const keyValueArray = await this.#flattenKeyValuePairs(localValue.value);
const { result } = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((...args) => {
const result = {};
for (let i = 0; i < args.length; i += 2) {
const key = args[i];
result[key] = args[i + 1];
}
return result;
}),
awaitPromise: false,
arguments: keyValueArray,
returnByValue: false,
executionContextId: this.executionContextId,
});
return { objectId: result.objectId };
}
case 'array': {
const args = await this.#flattenValueList(localValue.value);
const { result } = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((...args) => args),
awaitPromise: false,
arguments: args,
returnByValue: false,
executionContextId: this.executionContextId,
});
return { objectId: result.objectId };
}
case 'set': {
const args = await this.#flattenValueList(localValue.value);
const { result } = await this.cdpClient.sendCommand('Runtime.callFunctionOn', {
functionDeclaration: String((...args) => new Set(args)),
awaitPromise: false,
arguments: args,
returnByValue: false,
executionContextId: this.executionContextId,
});
return { objectId: result.objectId };
}
case 'channel': {
const channelProxy = new ChannelProxy(localValue.value, this.#logger);
const channelProxySendMessageHandle = await channelProxy.init(this, this.#eventManager);
return { objectId: channelProxySendMessageHandle };
}
}
throw new Error(`Value ${JSON.stringify(localValue)} is not deserializable.`);
}
async #getExceptionResult(exceptionDetails, lineOffset, resultOwnership) {
return {
exceptionDetails: await this.#serializeCdpExceptionDetails(exceptionDetails, lineOffset, resultOwnership),
realm: this.realmId,
type: 'exception',
};
}
static #getSerializationOptions(serialization, serializationOptions) {
return {
serialization,
additionalParameters: Realm.#getAdditionalSerializationParameters(serializationOptions),
...Realm.#getMaxObjectDepth(serializationOptions),
};
}
static #getAdditionalSerializationParameters(serializationOptions) {
const additionalParameters = {};
if (serializationOptions.maxDomDepth !== undefined) {
additionalParameters['maxNodeDepth'] =
serializationOptions.maxDomDepth === null
? 1000
: serializationOptions.maxDomDepth;
}
if (serializationOptions.includeShadowTree !== undefined) {
additionalParameters['includeShadowTree'] =
serializationOptions.includeShadowTree;
}
return additionalParameters;
}
static #getMaxObjectDepth(serializationOptions) {
return serializationOptions.maxObjectDepth === undefined ||
serializationOptions.maxObjectDepth === null
? {}
: { maxDepth: serializationOptions.maxObjectDepth };
}
async #releaseObject(handle) {
try {
await this.cdpClient.sendCommand('Runtime.releaseObject', {
objectId: handle,
});
}
catch (error) {
if (!(error.code === -32e3 &&
error.message === 'Invalid remote object id')) {
throw error;
}
}
}
async disown(handle) {
if (this.realmStorage.knownHandlesToRealmMap.get(handle) !== this.realmId) {
return;
}
await this.#releaseObject(handle);
this.realmStorage.knownHandlesToRealmMap.delete(handle);
}
dispose() {
this.#registerEvent({
type: 'event',
method: Script$2.EventNames.RealmDestroyed,
params: {
realm: this.realmId,
},
});
}
}
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class WindowRealm extends Realm {
#browsingContextId;
#browsingContextStorage;
sandbox;
constructor(browsingContextId, browsingContextStorage, cdpClient, eventManager, executionContextId, logger, origin, realmId, realmStorage, sandbox) {
super(cdpClient, eventManager, executionContextId, logger, origin, realmId, realmStorage);
this.#browsingContextId = browsingContextId;
this.#browsingContextStorage = browsingContextStorage;
this.sandbox = sandbox;
this.initialize();
}
#getBrowsingContextId(navigableId) {
const maybeBrowsingContext = this.#browsingContextStorage
.getAllContexts()
.find((context) => context.navigableId === navigableId);
return maybeBrowsingContext?.id ?? 'UNKNOWN';
}
get browsingContext() {
return this.#browsingContextStorage.getContext(this.#browsingContextId);
}
isHidden() {
return this.realmStorage.hiddenSandboxes.has(this.sandbox);
}
get associatedBrowsingContexts() {
return [this.browsingContext];
}
get realmType() {
return 'window';
}
get realmInfo() {
return {
...this.baseInfo,
type: this.realmType,
context: this.#browsingContextId,
sandbox: this.sandbox,
};
}
get source() {
return {
realm: this.realmId,
context: this.browsingContext.id,
};
}
serializeForBiDi(deepSerializedValue, internalIdMap) {
const bidiValue = deepSerializedValue.value;
if (deepSerializedValue.type === 'node' && bidiValue !== undefined) {
if (Object.hasOwn(bidiValue, 'backendNodeId')) {
let navigableId = this.browsingContext.navigableId ?? 'UNKNOWN';
if (Object.hasOwn(bidiValue, 'loaderId')) {
navigableId = bidiValue.loaderId;
delete bidiValue['loaderId'];
}
deepSerializedValue.sharedId =
getSharedId(this.#getBrowsingContextId(navigableId), navigableId, bidiValue.backendNodeId);
delete bidiValue['backendNodeId'];
}
if (Object.hasOwn(bidiValue, 'children')) {
for (const i in bidiValue.children) {
bidiValue.children[i] = this.serializeForBiDi(bidiValue.children[i], internalIdMap);
}
}
if (Object.hasOwn(bidiValue, 'shadowRoot') &&
bidiValue.shadowRoot !== null) {
bidiValue.shadowRoot = this.serializeForBiDi(bidiValue.shadowRoot, internalIdMap);
}
if (bidiValue.namespaceURI === '') {
bidiValue.namespaceURI = null;
}
}
return super.serializeForBiDi(deepSerializedValue, internalIdMap);
}
async deserializeForCdp(localValue) {
if ('sharedId' in localValue && localValue.sharedId) {
const parsedSharedId = parseSharedId(localValue.sharedId);
if (parsedSharedId === null) {
throw new NoSuchNodeException(`SharedId "${localValue.sharedId}" was not found.`);
}
const { documentId, backendNodeId } = parsedSharedId;
if (this.browsingContext.navigableId !== documentId) {
throw new NoSuchNodeException(`SharedId "${localValue.sharedId}" belongs to different document. Current document is ${this.browsingContext.navigableId}.`);
}
try {
const { object } = await this.cdpClient.sendCommand('DOM.resolveNode', {
backendNodeId,
executionContextId: this.executionContextId,
});
return { objectId: object.objectId };
}
catch (error) {
if (error.code === -32e3 &&
error.message === 'No node with given id found') {
throw new NoSuchNodeException(`SharedId "${localValue.sharedId}" was not found.`);
}
throw new UnknownErrorException(error.message, error.stack);
}
}
return await super.deserializeForCdp(localValue);
}
async evaluate(expression, awaitPromise, resultOwnership, serializationOptions, userActivation, includeCommandLineApi) {
await this.#browsingContextStorage
.getContext(this.#browsingContextId)
.targetUnblockedOrThrow();
return await super.evaluate(expression, awaitPromise, resultOwnership, serializationOptions, userActivation, includeCommandLineApi);
}
async callFunction(functionDeclaration, awaitPromise, thisLocalValue, argumentsLocalValues, resultOwnership, serializationOptions, userActivation) {
await this.#browsingContextStorage
.getContext(this.#browsingContextId)
.targetUnblockedOrThrow();
return await super.callFunction(functionDeclaration, awaitPromise, thisLocalValue, argumentsLocalValues, resultOwnership, serializationOptions, userActivation);
}
}
/*
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
function urlMatchesAboutBlank(url) {
if (url === '') {
return true;
}
try {
const parsedUrl = new URL(url);
const schema = parsedUrl.protocol.replace(/:$/, '');
return (schema.toLowerCase() === 'about' &&
parsedUrl.pathname.toLowerCase() === 'blank' &&
parsedUrl.username === '' &&
parsedUrl.password === '' &&
parsedUrl.host === '');
}
catch (err) {
if (err instanceof TypeError) {
return false;
}
throw err;
}
}
/*
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
class NavigationResult {
eventName;
message;
constructor(eventName, message) {
this.eventName = eventName;
this.message = message;
}
}
class NavigationState {
navigationId = uuidv4();
#browsingContextId;
#started = false;
#finished = new Deferred();
url;
loaderId;
#isInitial;
#eventManager;
committed = new Deferred();
isFragmentNavigation;
get finished() {
return this.#finished;
}
constructor(url, browsingContextId, isInitial, eventManager) {
this.#browsingContextId = browsingContextId;
this.url = url;
this.#isInitial = isInitial;
this.#eventManager = eventManager;
}
navigationInfo() {
return {
context: this.#browsingContextId,
navigation: this.navigationId,
timestamp: getTimestamp(),
url: this.url,
};
}
start() {
if (
!this.#isInitial &&
!this.#started &&
!this.isFragmentNavigation) {
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.NavigationStarted,
params: this.navigationInfo(),
}, this.#browsingContextId);
}
this.#started = true;
}
#finish(navigationResult) {
this.#started = true;
if (!this.#isInitial &&
!this.#finished.isFinished &&
navigationResult.eventName !== "browsingContext.load" ) {
this.#eventManager.registerEvent({
type: 'event',
method: navigationResult.eventName,
params: this.navigationInfo(),
}, this.#browsingContextId);
}
this.#finished.resolve(navigationResult);
}
frameNavigated() {
this.committed.resolve();
if (!this.#isInitial) {
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.NavigationCommitted,
params: this.navigationInfo(),
}, this.#browsingContextId);
}
}
fragmentNavigated() {
this.committed.resolve();
this.#finish(new NavigationResult("browsingContext.fragmentNavigated" ));
}
load() {
this.#finish(new NavigationResult("browsingContext.load" ));
}
fail(message) {
this.#finish(new NavigationResult(this.committed.isFinished
? "browsingContext.navigationAborted"
: "browsingContext.navigationFailed" , message));
}
}
class NavigationTracker {
#eventManager;
#logger;
#loaderIdToNavigationsMap = new Map();
#browsingContextId;
#lastCommittedNavigation;
#pendingNavigation;
#isInitialNavigation = true;
constructor(url, browsingContextId, eventManager, logger) {
this.#browsingContextId = browsingContextId;
this.#eventManager = eventManager;
this.#logger = logger;
this.#isInitialNavigation = true;
this.#lastCommittedNavigation = new NavigationState(url, browsingContextId, urlMatchesAboutBlank(url), this.#eventManager);
}
get currentNavigationId() {
if (this.#pendingNavigation?.isFragmentNavigation === false) {
return this.#pendingNavigation.navigationId;
}
return this.#lastCommittedNavigation.navigationId;
}
get isInitialNavigation() {
return this.#isInitialNavigation;
}
get url() {
return this.#lastCommittedNavigation.url;
}
createPendingNavigation(url, canBeInitialNavigation = false) {
this.#logger?.(LogType.debug, 'createCommandNavigation');
this.#isInitialNavigation =
canBeInitialNavigation &&
this.#isInitialNavigation &&
urlMatchesAboutBlank(url);
this.#pendingNavigation?.fail('navigation canceled by concurrent navigation');
const navigation = new NavigationState(url, this.#browsingContextId, this.#isInitialNavigation, this.#eventManager);
this.#pendingNavigation = navigation;
return navigation;
}
dispose() {
this.#pendingNavigation?.fail('navigation canceled by context disposal');
this.#lastCommittedNavigation.fail('navigation canceled by context disposal');
}
onTargetInfoChanged(url) {
this.#logger?.(LogType.debug, `onTargetInfoChanged ${url}`);
this.#lastCommittedNavigation.url = url;
}
#getNavigationForFrameNavigated(url, loaderId) {
if (this.#loaderIdToNavigationsMap.has(loaderId)) {
return this.#loaderIdToNavigationsMap.get(loaderId);
}
if (this.#pendingNavigation !== undefined &&
this.#pendingNavigation.loaderId === undefined) {
return this.#pendingNavigation;
}
return this.createPendingNavigation(url, true);
}
frameNavigated(url, loaderId, unreachableUrl) {
this.#logger?.(LogType.debug, `frameNavigated ${url}`);
if (unreachableUrl !== undefined) {
const navigation = this.#loaderIdToNavigationsMap.get(loaderId) ??
this.#pendingNavigation ??
this.createPendingNavigation(unreachableUrl, true);
navigation.url = unreachableUrl;
navigation.start();
navigation.fail('the requested url is unreachable');
return;
}
const navigation = this.#getNavigationForFrameNavigated(url, loaderId);
if (navigation !== this.#lastCommittedNavigation) {
this.#lastCommittedNavigation.fail('navigation canceled by concurrent navigation');
}
navigation.url = url;
navigation.loaderId = loaderId;
this.#loaderIdToNavigationsMap.set(loaderId, navigation);
navigation.start();
navigation.frameNavigated();
this.#lastCommittedNavigation = navigation;
if (this.#pendingNavigation === navigation) {
this.#pendingNavigation = undefined;
}
}
navigatedWithinDocument(url, navigationType) {
this.#logger?.(LogType.debug, `navigatedWithinDocument ${url}, ${navigationType}`);
this.#lastCommittedNavigation.url = url;
if (navigationType !== 'fragment') {
return;
}
const fragmentNavigation = this.#pendingNavigation?.isFragmentNavigation === true
? this.#pendingNavigation
: new NavigationState(url, this.#browsingContextId, false, this.#eventManager);
fragmentNavigation.fragmentNavigated();
if (fragmentNavigation === this.#pendingNavigation) {
this.#pendingNavigation = undefined;
}
}
loadPageEvent(loaderId) {
this.#logger?.(LogType.debug, 'loadPageEvent');
this.#isInitialNavigation = false;
this.#loaderIdToNavigationsMap.get(loaderId)?.load();
}
failNavigation(navigation, errorText) {
this.#logger?.(LogType.debug, 'failCommandNavigation');
navigation.fail(errorText);
}
navigationCommandFinished(navigation, loaderId) {
this.#logger?.(LogType.debug, `finishCommandNavigation ${navigation.navigationId}, ${loaderId}`);
if (loaderId !== undefined) {
navigation.loaderId = loaderId;
this.#loaderIdToNavigationsMap.set(loaderId, navigation);
}
navigation.isFragmentNavigation = loaderId === undefined;
}
frameStartedNavigating(url, loaderId, navigationType) {
this.#logger?.(LogType.debug, `frameStartedNavigating ${url}, ${loaderId}`);
if (this.#pendingNavigation &&
this.#pendingNavigation?.loaderId !== undefined &&
this.#pendingNavigation?.loaderId !== loaderId) {
this.#pendingNavigation?.fail('navigation canceled by concurrent navigation');
this.#pendingNavigation = undefined;
}
if (this.#loaderIdToNavigationsMap.has(loaderId)) {
const existingNavigation = this.#loaderIdToNavigationsMap.get(loaderId);
existingNavigation.isFragmentNavigation =
NavigationTracker.#isFragmentNavigation(navigationType);
this.#pendingNavigation = existingNavigation;
return;
}
const pendingNavigation = this.#pendingNavigation ?? this.createPendingNavigation(url, true);
this.#loaderIdToNavigationsMap.set(loaderId, pendingNavigation);
pendingNavigation.isFragmentNavigation =
NavigationTracker.#isFragmentNavigation(navigationType);
pendingNavigation.url = url;
pendingNavigation.loaderId = loaderId;
pendingNavigation.start();
}
static #isFragmentNavigation(navigationType) {
return ['historySameDocument', 'sameDocument'].includes(navigationType);
}
networkLoadingFailed(loaderId, errorText) {
this.#loaderIdToNavigationsMap.get(loaderId)?.fail(errorText);
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var _a$5;
class BrowsingContextImpl {
static LOGGER_PREFIX = `${LogType.debug}:browsingContext`;
#children = new Set();
#id;
userContext;
#hiddenSandbox = uuidv4();
#downloadIdToUrlMap = new Map();
#loaderId;
#parentId = null;
#originalOpener;
#lifecycle = {
DOMContentLoaded: new Deferred(),
load: new Deferred(),
};
#cdpTarget;
#defaultRealmDeferred = new Deferred();
#browsingContextStorage;
#eventManager;
#logger;
#navigationTracker;
#realmStorage;
#configStorage;
#lastUserPromptType;
constructor(id, parentId, userContext, cdpTarget, eventManager, browsingContextStorage, realmStorage, configStorage, url, originalOpener, logger) {
this.#cdpTarget = cdpTarget;
this.#id = id;
this.#parentId = parentId;
this.userContext = userContext;
this.#eventManager = eventManager;
this.#browsingContextStorage = browsingContextStorage;
this.#realmStorage = realmStorage;
this.#configStorage = configStorage;
this.#logger = logger;
this.#originalOpener = originalOpener;
this.#realmStorage.hiddenSandboxes.add(this.#hiddenSandbox);
this.#navigationTracker = new NavigationTracker(url, id, eventManager, logger);
}
static create(id, parentId, userContext, cdpTarget, eventManager, browsingContextStorage, realmStorage, configStorage, url, originalOpener, logger) {
const context = new _a$5(id, parentId, userContext, cdpTarget, eventManager, browsingContextStorage, realmStorage, configStorage, url, originalOpener, logger);
context.#initListeners();
browsingContextStorage.addContext(context);
if (!context.isTopLevelContext()) {
context.parent.addChild(context.id);
}
eventManager.registerPromiseEvent(context.targetUnblockedOrThrow().then(() => {
return {
kind: 'success',
value: {
type: 'event',
method: BrowsingContext$2.EventNames.ContextCreated,
params: {
...context.serializeToBidiValue(),
url,
},
},
};
}, (error) => {
return {
kind: 'error',
error,
};
}), context.id, BrowsingContext$2.EventNames.ContextCreated);
return context;
}
get navigableId() {
return this.#loaderId;
}
get navigationId() {
return this.#navigationTracker.currentNavigationId;
}
dispose(emitContextDestroyed) {
this.#navigationTracker.dispose();
this.#realmStorage.deleteRealms({
browsingContextId: this.id,
});
if (!this.isTopLevelContext()) {
this.parent.#children.delete(this.id);
}
this.#failLifecycleIfNotFinished();
if (emitContextDestroyed) {
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.ContextDestroyed,
params: this.serializeToBidiValue(null),
}, this.id);
}
this.#deleteAllChildren();
this.#eventManager.clearBufferedEvents(this.id);
this.#browsingContextStorage.deleteContextById(this.id);
}
get id() {
return this.#id;
}
get parentId() {
return this.#parentId;
}
set parentId(parentId) {
if (this.#parentId !== null) {
this.#logger?.(LogType.debugError, 'Parent context already set');
return;
}
this.#parentId = parentId;
if (!this.isTopLevelContext()) {
this.parent.addChild(this.id);
}
}
get parent() {
if (this.parentId === null) {
return null;
}
return this.#browsingContextStorage.getContext(this.parentId);
}
get directChildren() {
return [...this.#children].map((id) => this.#browsingContextStorage.getContext(id));
}
get allChildren() {
const children = this.directChildren;
return children.concat(...children.map((child) => child.allChildren));
}
isTopLevelContext() {
return this.#parentId === null;
}
get top() {
let topContext = this;
let parent = topContext.parent;
while (parent) {
topContext = parent;
parent = topContext.parent;
}
return topContext;
}
addChild(childId) {
this.#children.add(childId);
}
#deleteAllChildren(emitContextDestroyed = false) {
this.directChildren.map((child) => child.dispose(emitContextDestroyed));
}
get cdpTarget() {
return this.#cdpTarget;
}
updateCdpTarget(cdpTarget) {
this.#cdpTarget = cdpTarget;
this.#initListeners();
}
get url() {
return this.#navigationTracker.url;
}
async lifecycleLoaded() {
await this.#lifecycle.load;
}
async targetUnblockedOrThrow() {
const result = await this.#cdpTarget.unblocked;
if (result.kind === 'error') {
throw result.error;
}
}
async getOrCreateHiddenSandbox() {
return await this.#getOrCreateSandboxInternal(this.#hiddenSandbox);
}
async getOrCreateUserSandbox(sandbox) {
const realm = await this.#getOrCreateSandboxInternal(sandbox);
if (realm.isHidden()) {
throw new NoSuchFrameException(`Realm "${sandbox}" not found`);
}
return realm;
}
async #getOrCreateSandboxInternal(sandbox) {
if (sandbox === undefined || sandbox === '') {
return await this.#defaultRealmDeferred;
}
let maybeSandboxes = this.#realmStorage.findRealms({
browsingContextId: this.id,
sandbox,
});
if (maybeSandboxes.length === 0) {
await this.#cdpTarget.cdpClient.sendCommand('Page.createIsolatedWorld', {
frameId: this.id,
worldName: sandbox,
});
maybeSandboxes = this.#realmStorage.findRealms({
browsingContextId: this.id,
sandbox,
});
assert(maybeSandboxes.length !== 0);
}
return maybeSandboxes[0];
}
serializeToBidiValue(maxDepth = 0, addParentField = true) {
return {
context: this.#id,
url: this.url,
userContext: this.userContext,
originalOpener: this.#originalOpener ?? null,
clientWindow: `${this.cdpTarget.windowId}`,
children: maxDepth === null || maxDepth > 0
? this.directChildren.map((c) => c.serializeToBidiValue(maxDepth === null ? maxDepth : maxDepth - 1, false))
: null,
...(addParentField ? { parent: this.#parentId } : {}),
};
}
onTargetInfoChanged(params) {
this.#navigationTracker.onTargetInfoChanged(params.targetInfo.url);
}
#initListeners() {
this.#cdpTarget.cdpClient.on('Network.loadingFailed', (params) => {
this.#navigationTracker.networkLoadingFailed(params.requestId, params.errorText);
});
this.#cdpTarget.cdpClient.on('Page.fileChooserOpened', (params) => {
if (this.id !== params.frameId) {
return;
}
if (this.#loaderId === undefined) {
this.#logger?.(LogType.debugError, 'LoaderId should be defined when file upload is shown', params);
return;
}
const element = params.backendNodeId === undefined
? undefined
: {
sharedId: getSharedId(this.id, this.#loaderId, params.backendNodeId),
};
this.#eventManager.registerEvent({
type: 'event',
method: Input$2.EventNames.FileDialogOpened,
params: {
context: this.id,
multiple: params.mode === 'selectMultiple',
element,
},
}, this.id);
});
this.#cdpTarget.cdpClient.on('Page.frameNavigated', (params) => {
if (this.id !== params.frame.id) {
return;
}
this.#navigationTracker.frameNavigated(params.frame.url + (params.frame.urlFragment ?? ''), params.frame.loaderId,
params.frame.unreachableUrl);
this.#deleteAllChildren();
this.#documentChanged(params.frame.loaderId);
});
this.#cdpTarget.cdpClient.on('Page.frameStartedNavigating', (params) => {
if (this.id !== params.frameId) {
return;
}
this.#navigationTracker.frameStartedNavigating(params.url, params.loaderId, params.navigationType);
});
this.#cdpTarget.cdpClient.on('Page.navigatedWithinDocument', (params) => {
if (this.id !== params.frameId) {
return;
}
this.#navigationTracker.navigatedWithinDocument(params.url, params.navigationType);
if (params.navigationType === 'historyApi') {
this.#eventManager.registerEvent({
type: 'event',
method: 'browsingContext.historyUpdated',
params: {
context: this.id,
timestamp: getTimestamp(),
url: this.#navigationTracker.url,
},
}, this.id);
return;
}
});
this.#cdpTarget.cdpClient.on('Page.lifecycleEvent', (params) => {
if (this.id !== params.frameId) {
return;
}
if (params.name === 'init') {
this.#documentChanged(params.loaderId);
return;
}
if (params.name === 'commit') {
this.#loaderId = params.loaderId;
return;
}
if (!this.#loaderId) {
this.#loaderId = params.loaderId;
}
if (params.loaderId !== this.#loaderId) {
return;
}
switch (params.name) {
case 'DOMContentLoaded':
if (!this.#navigationTracker.isInitialNavigation) {
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.DomContentLoaded,
params: {
context: this.id,
navigation: this.#navigationTracker.currentNavigationId,
timestamp: getTimestamp(),
url: this.#navigationTracker.url,
},
}, this.id);
}
this.#lifecycle.DOMContentLoaded.resolve();
break;
case 'load':
if (!this.#navigationTracker.isInitialNavigation) {
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.Load,
params: {
context: this.id,
navigation: this.#navigationTracker.currentNavigationId,
timestamp: getTimestamp(),
url: this.#navigationTracker.url,
},
}, this.id);
}
this.#navigationTracker.loadPageEvent(params.loaderId);
this.#lifecycle.load.resolve();
break;
}
});
this.#cdpTarget.cdpClient.on('Runtime.executionContextCreated', (params) => {
const { auxData, name, uniqueId, id } = params.context;
if (!auxData || auxData.frameId !== this.id) {
return;
}
let origin;
let sandbox;
switch (auxData.type) {
case 'isolated':
sandbox = name;
if (!this.#defaultRealmDeferred.isFinished) {
this.#logger?.(LogType.debugError, 'Unexpectedly, isolated realm created before the default one');
}
origin = this.#defaultRealmDeferred.isFinished
? this.#defaultRealmDeferred.result.origin
:
'';
break;
case 'default':
origin = serializeOrigin(params.context.origin);
break;
default:
return;
}
const realm = new WindowRealm(this.id, this.#browsingContextStorage, this.#cdpTarget.cdpClient, this.#eventManager, id, this.#logger, origin, uniqueId, this.#realmStorage, sandbox);
if (auxData.isDefault) {
this.#defaultRealmDeferred.resolve(realm);
void Promise.all(this.#cdpTarget
.getChannels()
.map((channel) => channel.startListenerFromWindow(realm, this.#eventManager)));
}
});
this.#cdpTarget.cdpClient.on('Runtime.executionContextDestroyed', (params) => {
if (this.#defaultRealmDeferred.isFinished &&
this.#defaultRealmDeferred.result.executionContextId ===
params.executionContextId) {
this.#defaultRealmDeferred = new Deferred();
}
this.#realmStorage.deleteRealms({
cdpSessionId: this.#cdpTarget.cdpSessionId,
executionContextId: params.executionContextId,
});
});
this.#cdpTarget.cdpClient.on('Runtime.executionContextsCleared', () => {
if (!this.#defaultRealmDeferred.isFinished) {
this.#defaultRealmDeferred.reject(new UnknownErrorException('execution contexts cleared'));
}
this.#defaultRealmDeferred = new Deferred();
this.#realmStorage.deleteRealms({
cdpSessionId: this.#cdpTarget.cdpSessionId,
});
});
this.#cdpTarget.cdpClient.on('Page.javascriptDialogClosed', (params) => {
if (params.frameId && this.id !== params.frameId) {
return;
}
if (!params.frameId &&
this.#parentId &&
this.#cdpTarget.cdpClient !==
this.#browsingContextStorage.getContext(this.#parentId)?.cdpTarget
.cdpClient) {
return;
}
const accepted = params.result;
if (this.#lastUserPromptType === undefined) {
this.#logger?.(LogType.debugError, 'Unexpectedly no opening prompt event before closing one');
}
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.UserPromptClosed,
params: {
context: this.id,
accepted,
type: this.#lastUserPromptType ??
'UNKNOWN',
userText: accepted && params.userInput ? params.userInput : undefined,
},
}, this.id);
this.#lastUserPromptType = undefined;
});
this.#cdpTarget.cdpClient.on('Page.javascriptDialogOpening', (params) => {
if (params.frameId && this.id !== params.frameId) {
return;
}
if (!params.frameId &&
this.#parentId &&
this.#cdpTarget.cdpClient !==
this.#browsingContextStorage.getContext(this.#parentId)?.cdpTarget
.cdpClient) {
return;
}
const promptType = _a$5.#getPromptType(params.type);
this.#lastUserPromptType = promptType;
const promptHandler = this.#getPromptHandler(promptType);
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.UserPromptOpened,
params: {
context: this.id,
handler: promptHandler,
type: promptType,
message: params.message,
...(params.type === 'prompt'
? { defaultValue: params.defaultPrompt }
: {}),
},
}, this.id);
switch (promptHandler) {
case "accept" :
void this.handleUserPrompt(true);
break;
case "dismiss" :
void this.handleUserPrompt(false);
break;
}
});
this.#cdpTarget.browserCdpClient.on('Browser.downloadWillBegin', (params) => {
if (this.id !== params.frameId) {
return;
}
this.#downloadIdToUrlMap.set(params.guid, params.url);
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.DownloadWillBegin,
params: {
context: this.id,
suggestedFilename: params.suggestedFilename,
navigation: params.guid,
timestamp: getTimestamp(),
url: params.url,
},
}, this.id);
});
this.#cdpTarget.browserCdpClient.on('Browser.downloadProgress', (params) => {
if (!this.#downloadIdToUrlMap.has(params.guid)) {
return;
}
if (params.state === 'inProgress') {
return;
}
const url = this.#downloadIdToUrlMap.get(params.guid);
switch (params.state) {
case 'canceled':
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.DownloadEnd,
params: {
status: 'canceled',
context: this.id,
navigation: params.guid,
timestamp: getTimestamp(),
url,
},
}, this.id);
break;
case 'completed':
this.#eventManager.registerEvent({
type: 'event',
method: BrowsingContext$2.EventNames.DownloadEnd,
params: {
filepath: params.filePath ?? null,
status: 'complete',
context: this.id,
navigation: params.guid,
timestamp: getTimestamp(),
url,
},
}, this.id);
break;
default:
throw new UnknownErrorException(`Unknown download state: ${params.state}`);
}
});
}
static #getPromptType(cdpType) {
switch (cdpType) {
case 'alert':
return "alert" ;
case 'beforeunload':
return "beforeunload" ;
case 'confirm':
return "confirm" ;
case 'prompt':
return "prompt" ;
}
}
#getPromptHandler(promptType) {
const defaultPromptHandler = "dismiss" ;
const contextConfig = this.#configStorage.getActiveConfig(this.top.id, this.userContext);
switch (promptType) {
case "alert" :
return (contextConfig.userPromptHandler?.alert ??
contextConfig.userPromptHandler?.default ??
defaultPromptHandler);
case "beforeunload" :
return (contextConfig.userPromptHandler?.beforeUnload ??
contextConfig.userPromptHandler?.default ??
"accept" );
case "confirm" :
return (contextConfig.userPromptHandler?.confirm ??
contextConfig.userPromptHandler?.default ??
defaultPromptHandler);
case "prompt" :
return (contextConfig.userPromptHandler?.prompt ??
contextConfig.userPromptHandler?.default ??
defaultPromptHandler);
}
}
#documentChanged(loaderId) {
if (loaderId === undefined || this.#loaderId === loaderId) {
return;
}
this.#resetLifecycleIfFinished();
this.#loaderId = loaderId;
this.#deleteAllChildren(true);
}
#resetLifecycleIfFinished() {
if (this.#lifecycle.DOMContentLoaded.isFinished) {
this.#lifecycle.DOMContentLoaded = new Deferred();
}
else {
this.#logger?.(_a$5.LOGGER_PREFIX, 'Document changed (DOMContentLoaded)');
}
if (this.#lifecycle.load.isFinished) {
this.#lifecycle.load = new Deferred();
}
else {
this.#logger?.(_a$5.LOGGER_PREFIX, 'Document changed (load)');
}
}
#failLifecycleIfNotFinished() {
if (!this.#lifecycle.DOMContentLoaded.isFinished) {
this.#lifecycle.DOMContentLoaded.reject(new UnknownErrorException('navigation canceled'));
}
if (!this.#lifecycle.load.isFinished) {
this.#lifecycle.load.reject(new UnknownErrorException('navigation canceled'));
}
}
async navigate(url, wait) {
try {
new URL(url);
}
catch {
throw new InvalidArgumentException(`Invalid URL: ${url}`);
}
const navigationState = this.#navigationTracker.createPendingNavigation(url);
const cdpNavigatePromise = (async () => {
const cdpNavigateResult = await this.#cdpTarget.cdpClient.sendCommand('Page.navigate', {
url,
frameId: this.id,
});
if (cdpNavigateResult.errorText) {
this.#navigationTracker.failNavigation(navigationState, cdpNavigateResult.errorText);
throw new UnknownErrorException(cdpNavigateResult.errorText);
}
this.#navigationTracker.navigationCommandFinished(navigationState, cdpNavigateResult.loaderId);
this.#documentChanged(cdpNavigateResult.loaderId);
})();
const result = await Promise.race([
this.#waitNavigation(wait, cdpNavigatePromise, navigationState),
navigationState.finished,
]);
if (result instanceof NavigationResult) {
if (
result.eventName === "browsingContext.navigationAborted" ||
result.eventName === "browsingContext.navigationFailed" ) {
throw new UnknownErrorException(result.message ?? 'unknown exception');
}
}
return {
navigation: navigationState.navigationId,
url: navigationState.url,
};
}
async #waitNavigation(wait, cdpCommandPromise, navigationState) {
await Promise.all([navigationState.committed, cdpCommandPromise]);
if (wait === "none" ) {
return;
}
if (navigationState.isFragmentNavigation === true) {
await navigationState.finished;
return;
}
if (wait === "interactive" ) {
await this.#lifecycle.DOMContentLoaded;
return;
}
if (wait === "complete" ) {
await this.#lifecycle.load;
return;
}
throw new InvalidArgumentException(`Wait condition ${wait} is not supported`);
}
async reload(ignoreCache, wait) {
await this.targetUnblockedOrThrow();
this.#resetLifecycleIfFinished();
const navigationState = this.#navigationTracker.createPendingNavigation(this.#navigationTracker.url);
const cdpReloadPromise = this.#cdpTarget.cdpClient.sendCommand('Page.reload', {
ignoreCache,
});
const result = await Promise.race([
this.#waitNavigation(wait, cdpReloadPromise, navigationState),
navigationState.finished,
]);
if (result instanceof NavigationResult) {
if (result.eventName === "browsingContext.navigationAborted" ||
result.eventName === "browsingContext.navigationFailed" ) {
throw new UnknownErrorException(result.message ?? 'unknown exception');
}
}
return {
navigation: navigationState.navigationId,
url: navigationState.url,
};
}
async setViewport(viewport, devicePixelRatio) {
await this.cdpTarget.setViewport(viewport, devicePixelRatio);
}
async handleUserPrompt(accept, userText) {
await this.top.#cdpTarget.cdpClient.sendCommand('Page.handleJavaScriptDialog', {
accept: accept ?? true,
promptText: userText,
});
}
async activate() {
await this.#cdpTarget.cdpClient.sendCommand('Page.bringToFront');
}
async captureScreenshot(params) {
if (!this.isTopLevelContext()) {
throw new UnsupportedOperationException(`Non-top-level 'context' (${params.context}) is currently not supported`);
}
const formatParameters = getImageFormatParameters(params);
let captureBeyondViewport = false;
let script;
params.origin ??= 'viewport';
switch (params.origin) {
case 'document': {
script = String(() => {
const element = document.documentElement;
return {
x: 0,
y: 0,
width: element.scrollWidth,
height: element.scrollHeight,
};
});
captureBeyondViewport = true;
break;
}
case 'viewport': {
script = String(() => {
const viewport = window.visualViewport;
return {
x: viewport.pageLeft,
y: viewport.pageTop,
width: viewport.width,
height: viewport.height,
};
});
break;
}
}
const hiddenSandboxRealm = await this.getOrCreateHiddenSandbox();
const originResult = await hiddenSandboxRealm.callFunction(script, false);
assert(originResult.type === 'success');
const origin = deserializeDOMRect(originResult.result);
assert(origin);
let rect = origin;
if (params.clip) {
const clip = params.clip;
if (params.origin === 'viewport' && clip.type === 'box') {
clip.x += origin.x;
clip.y += origin.y;
}
rect = getIntersectionRect(await this.#parseRect(clip), origin);
}
if (rect.width === 0 || rect.height === 0) {
throw new UnableToCaptureScreenException(`Unable to capture screenshot with zero dimensions: width=${rect.width}, height=${rect.height}`);
}
return await this.#cdpTarget.cdpClient.sendCommand('Page.captureScreenshot', {
clip: { ...rect, scale: 1.0 },
...formatParameters,
captureBeyondViewport,
});
}
async print(params) {
if (!this.isTopLevelContext()) {
throw new UnsupportedOperationException('Printing of non-top level contexts is not supported');
}
const cdpParams = {};
if (params.background !== undefined) {
cdpParams.printBackground = params.background;
}
if (params.margin?.bottom !== undefined) {
cdpParams.marginBottom = inchesFromCm(params.margin.bottom);
}
if (params.margin?.left !== undefined) {
cdpParams.marginLeft = inchesFromCm(params.margin.left);
}
if (params.margin?.right !== undefined) {
cdpParams.marginRight = inchesFromCm(params.margin.right);
}
if (params.margin?.top !== undefined) {
cdpParams.marginTop = inchesFromCm(params.margin.top);
}
if (params.orientation !== undefined) {
cdpParams.landscape = params.orientation === 'landscape';
}
if (params.page?.height !== undefined) {
cdpParams.paperHeight = inchesFromCm(params.page.height);
}
if (params.page?.width !== undefined) {
cdpParams.paperWidth = inchesFromCm(params.page.width);
}
if (params.pageRanges !== undefined) {
for (const range of params.pageRanges) {
if (typeof range === 'number') {
continue;
}
const rangeParts = range.split('-');
if (rangeParts.length < 1 || rangeParts.length > 2) {
throw new InvalidArgumentException(`Invalid page range: ${range} is not a valid integer range.`);
}
if (rangeParts.length === 1) {
void parseInteger(rangeParts[0] ?? '');
continue;
}
let lowerBound;
let upperBound;
const [rangeLowerPart = '', rangeUpperPart = ''] = rangeParts;
if (rangeLowerPart === '') {
lowerBound = 1;
}
else {
lowerBound = parseInteger(rangeLowerPart);
}
if (rangeUpperPart === '') {
upperBound = Number.MAX_SAFE_INTEGER;
}
else {
upperBound = parseInteger(rangeUpperPart);
}
if (lowerBound > upperBound) {
throw new InvalidArgumentException(`Invalid page range: ${rangeLowerPart} > ${rangeUpperPart}`);
}
}
cdpParams.pageRanges = params.pageRanges.join(',');
}
if (params.scale !== undefined) {
cdpParams.scale = params.scale;
}
if (params.shrinkToFit !== undefined) {
cdpParams.preferCSSPageSize = !params.shrinkToFit;
}
try {
const result = await this.#cdpTarget.cdpClient.sendCommand('Page.printToPDF', cdpParams);
return {
data: result.data,
};
}
catch (error) {
if (error.message ===
'invalid print parameters: content area is empty') {
throw new UnsupportedOperationException(error.message);
}
throw error;
}
}
async #parseRect(clip) {
switch (clip.type) {
case 'box':
return { x: clip.x, y: clip.y, width: clip.width, height: clip.height };
case 'element': {
const hiddenSandboxRealm = await this.getOrCreateHiddenSandbox();
const result = await hiddenSandboxRealm.callFunction(String((element) => {
return element instanceof Element;
}), false, { type: 'undefined' }, [clip.element]);
if (result.type === 'exception') {
throw new NoSuchElementException(`Element '${clip.element.sharedId}' was not found`);
}
assert(result.result.type === 'boolean');
if (!result.result.value) {
throw new NoSuchElementException(`Node '${clip.element.sharedId}' is not an Element`);
}
{
const result = await hiddenSandboxRealm.callFunction(String((element) => {
const rect = element.getBoundingClientRect();
return {
x: rect.x,
y: rect.y,
height: rect.height,
width: rect.width,
};
}), false, { type: 'undefined' }, [clip.element]);
assert(result.type === 'success');
const rect = deserializeDOMRect(result.result);
if (!rect) {
throw new UnableToCaptureScreenException(`Could not get bounding box for Element '${clip.element.sharedId}'`);
}
return rect;
}
}
}
}
async close() {
await this.#cdpTarget.cdpClient.sendCommand('Page.close');
}
async traverseHistory(delta) {
if (delta === 0) {
return;
}
const history = await this.#cdpTarget.cdpClient.sendCommand('Page.getNavigationHistory');
const entry = history.entries[history.currentIndex + delta];
if (!entry) {
throw new NoSuchHistoryEntryException(`No history entry at delta ${delta}`);
}
await this.#cdpTarget.cdpClient.sendCommand('Page.navigateToHistoryEntry', {
entryId: entry.id,
});
}
async toggleModulesIfNeeded() {
await Promise.all([
this.#cdpTarget.toggleNetworkIfNeeded(),
this.#cdpTarget.toggleDeviceAccessIfNeeded(),
]);
}
async locateNodes(params) {
return await this.#locateNodesByLocator(await this.#defaultRealmDeferred, params.locator, params.startNodes ?? [], params.maxNodeCount, params.serializationOptions);
}
async #getLocatorDelegate(realm, locator, maxNodeCount, startNodes) {
switch (locator.type) {
case 'context':
throw new Error('Unreachable');
case 'css':
return {
functionDeclaration: String((cssSelector, maxNodeCount, ...startNodes) => {
const locateNodesUsingCss = (element) => {
if (!(element instanceof HTMLElement ||
element instanceof Document ||
element instanceof DocumentFragment ||
element instanceof SVGElement)) {
throw new Error('startNodes in css selector should be HTMLElement, SVGElement or Document or DocumentFragment');
}
return [...element.querySelectorAll(cssSelector)];
};
startNodes = startNodes.length > 0 ? startNodes : [document];
const returnedNodes = startNodes
.map((startNode) =>
locateNodesUsingCss(startNode))
.flat(1);
return maxNodeCount === 0
? returnedNodes
: returnedNodes.slice(0, maxNodeCount);
}),
argumentsLocalValues: [
{ type: 'string', value: locator.value },
{ type: 'number', value: maxNodeCount ?? 0 },
...startNodes,
],
};
case 'xpath':
return {
functionDeclaration: String((xPathSelector, maxNodeCount, ...startNodes) => {
const evaluator = new XPathEvaluator();
const expression = evaluator.createExpression(xPathSelector);
const locateNodesUsingXpath = (element) => {
const xPathResult = expression.evaluate(element, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
const returnedNodes = [];
for (let i = 0; i < xPathResult.snapshotLength; i++) {
returnedNodes.push(xPathResult.snapshotItem(i));
}
return returnedNodes;
};
startNodes = startNodes.length > 0 ? startNodes : [document];
const returnedNodes = startNodes
.map((startNode) =>
locateNodesUsingXpath(startNode))
.flat(1);
return maxNodeCount === 0
? returnedNodes
: returnedNodes.slice(0, maxNodeCount);
}),
argumentsLocalValues: [
{ type: 'string', value: locator.value },
{ type: 'number', value: maxNodeCount ?? 0 },
...startNodes,
],
};
case 'innerText':
if (locator.value === '') {
throw new InvalidSelectorException('innerText locator cannot be empty');
}
return {
functionDeclaration: String((innerTextSelector, fullMatch, ignoreCase, maxNodeCount, maxDepth, ...startNodes) => {
const searchText = ignoreCase
? innerTextSelector.toUpperCase()
: innerTextSelector;
const locateNodesUsingInnerText = (node, currentMaxDepth) => {
const returnedNodes = [];
if (node instanceof DocumentFragment ||
node instanceof Document) {
const children = [...node.children];
children.forEach((child) =>
returnedNodes.push(...locateNodesUsingInnerText(child, currentMaxDepth)));
return returnedNodes;
}
if (!(node instanceof HTMLElement)) {
return [];
}
const element = node;
const nodeInnerText = ignoreCase
? element.innerText?.toUpperCase()
: element.innerText;
if (!nodeInnerText.includes(searchText)) {
return [];
}
const childNodes = [];
for (const child of element.children) {
if (child instanceof HTMLElement) {
childNodes.push(child);
}
}
if (childNodes.length === 0) {
if (fullMatch && nodeInnerText === searchText) {
returnedNodes.push(element);
}
else {
if (!fullMatch) {
returnedNodes.push(element);
}
}
}
else {
const childNodeMatches =
currentMaxDepth <= 0
? []
: childNodes
.map((child) => locateNodesUsingInnerText(child, currentMaxDepth - 1))
.flat(1);
if (childNodeMatches.length === 0) {
if (!fullMatch || nodeInnerText === searchText) {
returnedNodes.push(element);
}
}
else {
returnedNodes.push(...childNodeMatches);
}
}
return returnedNodes;
};
startNodes = startNodes.length > 0 ? startNodes : [document];
const returnedNodes = startNodes
.map((startNode) =>
locateNodesUsingInnerText(startNode, maxDepth))
.flat(1);
return maxNodeCount === 0
? returnedNodes
: returnedNodes.slice(0, maxNodeCount);
}),
argumentsLocalValues: [
{ type: 'string', value: locator.value },
{ type: 'boolean', value: locator.matchType !== 'partial' },
{ type: 'boolean', value: locator.ignoreCase === true },
{ type: 'number', value: maxNodeCount ?? 0 },
{ type: 'number', value: locator.maxDepth ?? 1000 },
...startNodes,
],
};
case 'accessibility': {
if (!locator.value.name && !locator.value.role) {
throw new InvalidSelectorException('Either name or role has to be specified');
}
await Promise.all([
this.#cdpTarget.cdpClient.sendCommand('Accessibility.enable'),
this.#cdpTarget.cdpClient.sendCommand('Accessibility.getRootAXNode'),
]);
const bindings = await realm.evaluate(
'({getAccessibleName, getAccessibleRole})',
false, "root" ,
undefined,
false,
true);
if (bindings.type !== 'success') {
throw new Error('Could not get bindings');
}
if (bindings.result.type !== 'object') {
throw new Error('Could not get bindings');
}
return {
functionDeclaration: String((name, role, bindings, maxNodeCount, ...startNodes) => {
const returnedNodes = [];
let aborted = false;
function collect(contextNodes, selector) {
if (aborted) {
return;
}
for (const contextNode of contextNodes) {
let match = true;
if (selector.role) {
const role = bindings.getAccessibleRole(contextNode);
if (selector.role !== role) {
match = false;
}
}
if (selector.name) {
const name = bindings.getAccessibleName(contextNode);
if (selector.name !== name) {
match = false;
}
}
if (match) {
if (maxNodeCount !== 0 &&
returnedNodes.length === maxNodeCount) {
aborted = true;
break;
}
returnedNodes.push(contextNode);
}
const childNodes = [];
for (const child of contextNode.children) {
if (child instanceof HTMLElement) {
childNodes.push(child);
}
}
collect(childNodes, selector);
}
}
startNodes =
startNodes.length > 0
? startNodes
: Array.from(document.documentElement.children).filter((c) => c instanceof HTMLElement);
collect(startNodes, {
role,
name,
});
return returnedNodes;
}),
argumentsLocalValues: [
{ type: 'string', value: locator.value.name || '' },
{ type: 'string', value: locator.value.role || '' },
{ handle: bindings.result.handle },
{ type: 'number', value: maxNodeCount ?? 0 },
...startNodes,
],
};
}
}
}
async #locateNodesByLocator(realm, locator, startNodes, maxNodeCount, serializationOptions) {
if (locator.type === 'context') {
if (startNodes.length !== 0) {
throw new InvalidArgumentException('Start nodes are not supported');
}
const contextId = locator.value.context;
if (!contextId) {
throw new InvalidSelectorException('Invalid context');
}
const context = this.#browsingContextStorage.getContext(contextId);
const parent = context.parent;
if (!parent) {
throw new InvalidArgumentException('This context has no container');
}
try {
const { backendNodeId } = await parent.#cdpTarget.cdpClient.sendCommand('DOM.getFrameOwner', {
frameId: contextId,
});
const { object } = await parent.#cdpTarget.cdpClient.sendCommand('DOM.resolveNode', {
backendNodeId,
});
const locatorResult = await realm.callFunction(`function () { return this; }`, false, { handle: object.objectId }, [], "none" , serializationOptions);
if (locatorResult.type === 'exception') {
throw new Error('Unknown exception');
}
return { nodes: [locatorResult.result] };
}
catch {
throw new InvalidArgumentException('Context does not exist');
}
}
const locatorDelegate = await this.#getLocatorDelegate(realm, locator, maxNodeCount, startNodes);
serializationOptions = {
...serializationOptions,
maxObjectDepth: 1,
};
const locatorResult = await realm.callFunction(locatorDelegate.functionDeclaration, false, { type: 'undefined' }, locatorDelegate.argumentsLocalValues, "none" , serializationOptions);
if (locatorResult.type !== 'success') {
this.#logger?.(_a$5.LOGGER_PREFIX, 'Failed locateNodesByLocator', locatorResult);
if (
locatorResult.exceptionDetails.text?.endsWith('is not a valid selector.') ||
locatorResult.exceptionDetails.text?.endsWith('is not a valid XPath expression.')) {
throw new InvalidSelectorException(`Not valid selector ${typeof locator.value === 'string' ? locator.value : JSON.stringify(locator.value)}`);
}
if (locatorResult.exceptionDetails.text ===
'Error: startNodes in css selector should be HTMLElement, SVGElement or Document or DocumentFragment') {
throw new InvalidArgumentException('startNodes in css selector should be HTMLElement, SVGElement or Document or DocumentFragment');
}
throw new UnknownErrorException(`Unexpected error in selector script: ${locatorResult.exceptionDetails.text}`);
}
if (locatorResult.result.type !== 'array') {
throw new UnknownErrorException(`Unexpected selector script result type: ${locatorResult.result.type}`);
}
const nodes = locatorResult.result.value.map((value) => {
if (value.type !== 'node') {
throw new UnknownErrorException(`Unexpected selector script result element: ${value.type}`);
}
return value;
});
return { nodes };
}
#getAllRelatedCdpTargets() {
const targets = new Set();
targets.add(this.cdpTarget);
this.allChildren.forEach((c) => targets.add(c.cdpTarget));
return Array.from(targets);
}
async setTimezoneOverride(timezone) {
await Promise.all(this.#getAllRelatedCdpTargets().map(async (cdpTarget) => await cdpTarget.setTimezoneOverride(timezone)));
}
async setLocaleOverride(locale) {
await Promise.all(this.#getAllRelatedCdpTargets().map(async (cdpTarget) => await cdpTarget.setLocaleOverride(locale)));
}
async setGeolocationOverride(geolocation) {
await Promise.all(this.#getAllRelatedCdpTargets().map(async (cdpTarget) => await cdpTarget.setGeolocationOverride(geolocation)));
}
async setScreenOrientationOverride(screenOrientation) {
await this.#cdpTarget.setScreenOrientationOverride(screenOrientation);
}
async setScriptingEnabled(scriptingEnabled) {
await Promise.all(this.#getAllRelatedCdpTargets().map(async (cdpTarget) => await cdpTarget.setScriptingEnabled(scriptingEnabled)));
}
}
_a$5 = BrowsingContextImpl;
function serializeOrigin(origin) {
if (['://', ''].includes(origin)) {
origin = 'null';
}
return origin;
}
function getImageFormatParameters(params) {
const { quality, type } = params.format ?? {
type: 'image/png',
};
switch (type) {
case 'image/png': {
return { format: 'png' };
}
case 'image/jpeg': {
return {
format: 'jpeg',
...(quality === undefined ? {} : { quality: Math.round(quality * 100) }),
};
}
case 'image/webp': {
return {
format: 'webp',
...(quality === undefined ? {} : { quality: Math.round(quality * 100) }),
};
}
}
throw new InvalidArgumentException(`Image format '${type}' is not a supported format`);
}
function deserializeDOMRect(result) {
if (result.type !== 'object' || result.value === undefined) {
return;
}
const x = result.value.find(([key]) => {
return key === 'x';
})?.[1];
const y = result.value.find(([key]) => {
return key === 'y';
})?.[1];
const height = result.value.find(([key]) => {
return key === 'height';
})?.[1];
const width = result.value.find(([key]) => {
return key === 'width';
})?.[1];
if (x?.type !== 'number' ||
y?.type !== 'number' ||
height?.type !== 'number' ||
width?.type !== 'number') {
return;
}
return {
x: x.value,
y: y.value,
width: width.value,
height: height.value,
};
}
function normalizeRect(box) {
return {
...(box.width < 0
? {
x: box.x + box.width,
width: -box.width,
}
: {
x: box.x,
width: box.width,
}),
...(box.height < 0
? {
y: box.y + box.height,
height: -box.height,
}
: {
y: box.y,
height: box.height,
}),
};
}
function getIntersectionRect(first, second) {
first = normalizeRect(first);
second = normalizeRect(second);
const x = Math.max(first.x, second.x);
const y = Math.max(first.y, second.y);
return {
x,
y,
width: Math.max(Math.min(first.x + first.width, second.x + second.width) - x, 0),
height: Math.max(Math.min(first.y + first.height, second.y + second.height) - y, 0),
};
}
function parseInteger(value) {
value = value.trim();
if (!/^[0-9]+$/.test(value)) {
throw new InvalidArgumentException(`Invalid integer: ${value}`);
}
return parseInt(value);
}
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class WorkerRealm extends Realm {
#realmType;
#ownerRealms;
constructor(cdpClient, eventManager, executionContextId, logger, origin, ownerRealms, realmId, realmStorage, realmType) {
super(cdpClient, eventManager, executionContextId, logger, origin, realmId, realmStorage);
this.#ownerRealms = ownerRealms;
this.#realmType = realmType;
this.initialize();
}
get associatedBrowsingContexts() {
return this.#ownerRealms.flatMap((realm) => realm.associatedBrowsingContexts);
}
get realmType() {
return this.#realmType;
}
get source() {
return {
realm: this.realmId,
context: this.associatedBrowsingContexts[0]?.id,
};
}
get realmInfo() {
const owners = this.#ownerRealms.map((realm) => realm.realmId);
const { realmType } = this;
switch (realmType) {
case 'dedicated-worker': {
const owner = owners[0];
if (owner === undefined || owners.length !== 1) {
throw new Error('Dedicated worker must have exactly one owner');
}
return {
...this.baseInfo,
type: realmType,
owners: [owner],
};
}
case 'service-worker':
case 'shared-worker': {
return {
...this.baseInfo,
type: realmType,
};
}
}
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const specifiers = ['%s', '%d', '%i', '%f', '%o', '%O', '%c'];
function isFormatSpecifier(str) {
return specifiers.some((spec) => str.includes(spec));
}
function logMessageFormatter(args) {
let output = '';
const argFormat = args[0].value.toString();
const argValues = args.slice(1, undefined);
const tokens = argFormat.split(new RegExp(specifiers.map((spec) => `(${spec})`).join('|'), 'g'));
for (const token of tokens) {
if (token === undefined || token === '') {
continue;
}
if (isFormatSpecifier(token)) {
const arg = argValues.shift();
assert(arg, `Less value is provided: "${getRemoteValuesText(args, false)}"`);
if (token === '%s') {
output += stringFromArg(arg);
}
else if (token === '%d' || token === '%i') {
if (arg.type === 'bigint' ||
arg.type === 'number' ||
arg.type === 'string') {
output += parseInt(arg.value.toString(), 10);
}
else {
output += 'NaN';
}
}
else if (token === '%f') {
if (arg.type === 'bigint' ||
arg.type === 'number' ||
arg.type === 'string') {
output += parseFloat(arg.value.toString());
}
else {
output += 'NaN';
}
}
else {
output += toJson(arg);
}
}
else {
output += token;
}
}
if (argValues.length > 0) {
throw new Error(`More value is provided: "${getRemoteValuesText(args, false)}"`);
}
return output;
}
function toJson(arg) {
if (arg.type !== 'array' &&
arg.type !== 'bigint' &&
arg.type !== 'date' &&
arg.type !== 'number' &&
arg.type !== 'object' &&
arg.type !== 'string') {
return stringFromArg(arg);
}
if (arg.type === 'bigint') {
return `${arg.value.toString()}n`;
}
if (arg.type === 'number') {
return arg.value.toString();
}
if (['date', 'string'].includes(arg.type)) {
return JSON.stringify(arg.value);
}
if (arg.type === 'object') {
return `{${arg.value
.map((pair) => {
return `${JSON.stringify(pair[0])}:${toJson(pair[1])}`;
})
.join(',')}}`;
}
if (arg.type === 'array') {
return `[${arg.value?.map((val) => toJson(val)).join(',') ?? ''}]`;
}
throw Error(`Invalid value type: ${arg}`);
}
function stringFromArg(arg) {
if (!Object.hasOwn(arg, 'value')) {
return arg.type;
}
switch (arg.type) {
case 'string':
case 'number':
case 'boolean':
case 'bigint':
return String(arg.value);
case 'regexp':
return `/${arg.value.pattern}/${arg.value.flags ?? ''}`;
case 'date':
return new Date(arg.value).toString();
case 'object':
return `Object(${arg.value?.length ?? ''})`;
case 'array':
return `Array(${arg.value?.length ?? ''})`;
case 'map':
return `Map(${arg.value?.length})`;
case 'set':
return `Set(${arg.value?.length})`;
default:
return arg.type;
}
}
function getRemoteValuesText(args, formatText) {
const arg = args[0];
if (!arg) {
return '';
}
if (arg.type === 'string' &&
isFormatSpecifier(arg.value.toString()) &&
formatText) {
return logMessageFormatter(args);
}
return args
.map((arg) => {
return stringFromArg(arg);
})
.join('\u0020');
}
var _a$4;
function getBidiStackTrace(cdpStackTrace) {
const stackFrames = cdpStackTrace?.callFrames.map((callFrame) => {
return {
columnNumber: callFrame.columnNumber,
functionName: callFrame.functionName,
lineNumber: callFrame.lineNumber,
url: callFrame.url,
};
});
return stackFrames ? { callFrames: stackFrames } : undefined;
}
function getLogLevel(consoleApiType) {
if (["error" , 'assert'].includes(consoleApiType)) {
return "error" ;
}
if (["debug" , 'trace'].includes(consoleApiType)) {
return "debug" ;
}
if (["warn" , 'warning'].includes(consoleApiType)) {
return "warn" ;
}
return "info" ;
}
function getLogMethod(consoleApiType) {
switch (consoleApiType) {
case 'warning':
return 'warn';
case 'startGroup':
return 'group';
case 'startGroupCollapsed':
return 'groupCollapsed';
case 'endGroup':
return 'groupEnd';
}
return consoleApiType;
}
class LogManager {
#eventManager;
#realmStorage;
#cdpTarget;
#logger;
constructor(cdpTarget, realmStorage, eventManager, logger) {
this.#cdpTarget = cdpTarget;
this.#realmStorage = realmStorage;
this.#eventManager = eventManager;
this.#logger = logger;
}
static create(cdpTarget, realmStorage, eventManager, logger) {
const logManager = new _a$4(cdpTarget, realmStorage, eventManager, logger);
logManager.#initializeEntryAddedEventListener();
return logManager;
}
async #heuristicSerializeArg(arg, realm) {
switch (arg.type) {
case 'undefined':
return { type: 'undefined' };
case 'boolean':
return { type: 'boolean', value: arg.value };
case 'string':
return { type: 'string', value: arg.value };
case 'number':
return { type: 'number', value: arg.unserializableValue ?? arg.value };
case 'bigint':
if (arg.unserializableValue !== undefined &&
arg.unserializableValue[arg.unserializableValue.length - 1] === 'n') {
return {
type: arg.type,
value: arg.unserializableValue.slice(0, -1),
};
}
break;
case 'object':
if (arg.subtype === 'null') {
return { type: 'null' };
}
break;
}
return await realm.serializeCdpObject(arg, "none" );
}
#initializeEntryAddedEventListener() {
this.#cdpTarget.cdpClient.on('Runtime.consoleAPICalled', (params) => {
const realm = this.#realmStorage.findRealm({
cdpSessionId: this.#cdpTarget.cdpSessionId,
executionContextId: params.executionContextId,
});
if (realm === undefined) {
this.#logger?.(LogType.cdp, params);
return;
}
const argsPromise = Promise.all(params.args.map((arg) => this.#heuristicSerializeArg(arg, realm)));
for (const browsingContext of realm.associatedBrowsingContexts) {
this.#eventManager.registerPromiseEvent(argsPromise.then((args) => ({
kind: 'success',
value: {
type: 'event',
method: Log$1.EventNames.LogEntryAdded,
params: {
level: getLogLevel(params.type),
source: realm.source,
text: getRemoteValuesText(args, true),
timestamp: Math.round(params.timestamp),
stackTrace: getBidiStackTrace(params.stackTrace),
type: 'console',
method: getLogMethod(params.type),
args,
},
},
}), (error) => ({
kind: 'error',
error,
})), browsingContext.id, Log$1.EventNames.LogEntryAdded);
}
});
this.#cdpTarget.cdpClient.on('Runtime.exceptionThrown', (params) => {
const realm = this.#realmStorage.findRealm({
cdpSessionId: this.#cdpTarget.cdpSessionId,
executionContextId: params.exceptionDetails.executionContextId,
});
if (realm === undefined) {
this.#logger?.(LogType.cdp, params);
return;
}
for (const browsingContext of realm.associatedBrowsingContexts) {
this.#eventManager.registerPromiseEvent(_a$4.#getExceptionText(params, realm).then((text) => ({
kind: 'success',
value: {
type: 'event',
method: Log$1.EventNames.LogEntryAdded,
params: {
level: "error" ,
source: realm.source,
text,
timestamp: Math.round(params.timestamp),
stackTrace: getBidiStackTrace(params.exceptionDetails.stackTrace),
type: 'javascript',
},
},
}), (error) => ({
kind: 'error',
error,
})), browsingContext.id, Log$1.EventNames.LogEntryAdded);
}
});
}
static async #getExceptionText(params, realm) {
if (!params.exceptionDetails.exception) {
return params.exceptionDetails.text;
}
if (realm === undefined) {
return JSON.stringify(params.exceptionDetails.exception);
}
return await realm.stringifyObject(params.exceptionDetails.exception);
}
}
_a$4 = LogManager;
class CdpTarget {
#id;
#userContext;
#cdpClient;
#browserCdpClient;
#parentCdpClient;
#realmStorage;
#eventManager;
#preloadScriptStorage;
#browsingContextStorage;
#networkStorage;
contextConfigStorage;
#unblocked = new Deferred();
#logger;
#previousDeviceMetricsOverride = {
width: 0,
height: 0,
deviceScaleFactor: 0,
mobile: false,
dontSetVisibleSize: true,
};
#windowId;
#deviceAccessEnabled = false;
#cacheDisableState = false;
#fetchDomainStages = {
request: false,
response: false,
auth: false,
};
static create(targetId, cdpClient, browserCdpClient, parentCdpClient, realmStorage, eventManager, preloadScriptStorage, browsingContextStorage, networkStorage, configStorage, userContext, logger) {
const cdpTarget = new CdpTarget(targetId, cdpClient, browserCdpClient, parentCdpClient, eventManager, realmStorage, preloadScriptStorage, browsingContextStorage, configStorage, networkStorage, userContext, logger);
LogManager.create(cdpTarget, realmStorage, eventManager, logger);
cdpTarget.#setEventListeners();
void cdpTarget.#unblock();
return cdpTarget;
}
constructor(targetId, cdpClient, browserCdpClient, parentCdpClient, eventManager, realmStorage, preloadScriptStorage, browsingContextStorage, configStorage, networkStorage, userContext, logger) {
this.#userContext = userContext;
this.#id = targetId;
this.#cdpClient = cdpClient;
this.#browserCdpClient = browserCdpClient;
this.#parentCdpClient = parentCdpClient;
this.#eventManager = eventManager;
this.#realmStorage = realmStorage;
this.#preloadScriptStorage = preloadScriptStorage;
this.#networkStorage = networkStorage;
this.#browsingContextStorage = browsingContextStorage;
this.contextConfigStorage = configStorage;
this.#logger = logger;
}
get unblocked() {
return this.#unblocked;
}
get id() {
return this.#id;
}
get cdpClient() {
return this.#cdpClient;
}
get parentCdpClient() {
return this.#parentCdpClient;
}
get browserCdpClient() {
return this.#browserCdpClient;
}
get cdpSessionId() {
return this.#cdpClient.sessionId;
}
get windowId() {
if (this.#windowId === undefined) {
this.#logger?.(LogType.debugError, 'Getting windowId before it was set, returning 0');
}
return this.#windowId ?? 0;
}
async #unblock() {
try {
await Promise.all([
this.#cdpClient.sendCommand('Page.enable', {
enableFileChooserOpenedEvent: true,
}),
...(this.#ignoreFileDialog()
? []
: [
this.#cdpClient.sendCommand('Page.setInterceptFileChooserDialog', {
enabled: true,
cancel: true,
}),
]),
this.#cdpClient
.sendCommand('Page.getFrameTree')
.then((frameTree) => this.#restoreFrameTreeState(frameTree.frameTree)),
this.#cdpClient.sendCommand('Runtime.enable'),
this.#cdpClient.sendCommand('Page.setLifecycleEventsEnabled', {
enabled: true,
}),
this.#cdpClient
.sendCommand('Network.enable')
.then(() => this.toggleNetworkIfNeeded()),
this.#cdpClient.sendCommand('Target.setAutoAttach', {
autoAttach: true,
waitForDebuggerOnStart: true,
flatten: true,
}),
this.#updateWindowId(),
this.#setUserContextConfig(),
this.#initAndEvaluatePreloadScripts(),
this.#cdpClient.sendCommand('Runtime.runIfWaitingForDebugger'),
this.#parentCdpClient.sendCommand('Runtime.runIfWaitingForDebugger'),
this.toggleDeviceAccessIfNeeded(),
]);
}
catch (error) {
this.#logger?.(LogType.debugError, 'Failed to unblock target', error);
if (!this.#cdpClient.isCloseError(error)) {
this.#unblocked.resolve({
kind: 'error',
error,
});
return;
}
}
this.#unblocked.resolve({
kind: 'success',
value: undefined,
});
}
#restoreFrameTreeState(frameTree) {
const frame = frameTree.frame;
const maybeContext = this.#browsingContextStorage.findContext(frame.id);
if (maybeContext !== undefined) {
if (maybeContext.parentId === null &&
frame.parentId !== null &&
frame.parentId !== undefined) {
maybeContext.parentId = frame.parentId;
}
}
if (maybeContext === undefined && frame.parentId !== undefined) {
const parentBrowsingContext = this.#browsingContextStorage.getContext(frame.parentId);
BrowsingContextImpl.create(frame.id, frame.parentId, this.#userContext, parentBrowsingContext.cdpTarget, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, this.contextConfigStorage, frame.url, undefined, this.#logger);
}
frameTree.childFrames?.map((frameTree) => this.#restoreFrameTreeState(frameTree));
}
async toggleFetchIfNeeded() {
const stages = this.#networkStorage.getInterceptionStages(this.topLevelId);
if (this.#fetchDomainStages.request === stages.request &&
this.#fetchDomainStages.response === stages.response &&
this.#fetchDomainStages.auth === stages.auth) {
return;
}
const patterns = [];
this.#fetchDomainStages = stages;
if (stages.request || stages.auth) {
patterns.push({
urlPattern: '*',
requestStage: 'Request',
});
}
if (stages.response) {
patterns.push({
urlPattern: '*',
requestStage: 'Response',
});
}
if (patterns.length) {
await this.#cdpClient.sendCommand('Fetch.enable', {
patterns,
handleAuthRequests: stages.auth,
});
}
else {
const blockedRequest = this.#networkStorage
.getRequestsByTarget(this)
.filter((request) => request.interceptPhase);
void Promise.allSettled(blockedRequest.map((request) => request.waitNextPhase))
.then(async () => {
const blockedRequest = this.#networkStorage
.getRequestsByTarget(this)
.filter((request) => request.interceptPhase);
if (blockedRequest.length) {
return await this.toggleFetchIfNeeded();
}
return await this.#cdpClient.sendCommand('Fetch.disable');
})
.catch((error) => {
this.#logger?.(LogType.bidi, 'Disable failed', error);
});
}
}
async toggleNetworkIfNeeded() {
try {
await Promise.all([
this.toggleSetCacheDisabled(),
this.toggleFetchIfNeeded(),
]);
}
catch (err) {
this.#logger?.(LogType.debugError, err);
if (!this.#isExpectedError(err)) {
throw err;
}
}
}
async toggleSetCacheDisabled(disable) {
const defaultCacheDisabled = this.#networkStorage.defaultCacheBehavior === 'bypass';
const cacheDisabled = disable ?? defaultCacheDisabled;
if (this.#cacheDisableState === cacheDisabled) {
return;
}
this.#cacheDisableState = cacheDisabled;
try {
await this.#cdpClient.sendCommand('Network.setCacheDisabled', {
cacheDisabled,
});
}
catch (err) {
this.#logger?.(LogType.debugError, err);
this.#cacheDisableState = !cacheDisabled;
if (!this.#isExpectedError(err)) {
throw err;
}
}
}
async toggleDeviceAccessIfNeeded() {
const enabled = this.isSubscribedTo(Bluetooth$2.EventNames.RequestDevicePromptUpdated);
if (this.#deviceAccessEnabled === enabled) {
return;
}
this.#deviceAccessEnabled = enabled;
try {
await this.#cdpClient.sendCommand(enabled ? 'DeviceAccess.enable' : 'DeviceAccess.disable');
}
catch (err) {
this.#logger?.(LogType.debugError, err);
this.#deviceAccessEnabled = !enabled;
if (!this.#isExpectedError(err)) {
throw err;
}
}
}
#isExpectedError(err) {
const error = err;
return ((error.code === -32001 &&
error.message === 'Session with given id not found.') ||
this.#cdpClient.isCloseError(err));
}
#setEventListeners() {
this.#cdpClient.on('*', (event, params) => {
if (typeof event !== 'string') {
return;
}
this.#eventManager.registerEvent({
type: 'event',
method: `goog:cdp.${event}`,
params: {
event,
params,
session: this.cdpSessionId,
},
}, this.id);
});
}
async #enableFetch(stages) {
const patterns = [];
if (stages.request || stages.auth) {
patterns.push({
urlPattern: '*',
requestStage: 'Request',
});
}
if (stages.response) {
patterns.push({
urlPattern: '*',
requestStage: 'Response',
});
}
if (patterns.length) {
const oldStages = this.#fetchDomainStages;
this.#fetchDomainStages = stages;
try {
await this.#cdpClient.sendCommand('Fetch.enable', {
patterns,
handleAuthRequests: stages.auth,
});
}
catch {
this.#fetchDomainStages = oldStages;
}
}
}
async #disableFetch() {
const blockedRequest = this.#networkStorage
.getRequestsByTarget(this)
.filter((request) => request.interceptPhase);
if (blockedRequest.length === 0) {
this.#fetchDomainStages = {
request: false,
response: false,
auth: false,
};
await this.#cdpClient.sendCommand('Fetch.disable');
}
}
async toggleNetwork() {
const stages = this.#networkStorage.getInterceptionStages(this.topLevelId);
const fetchEnable = Object.values(stages).some((value) => value);
const fetchChanged = this.#fetchDomainStages.request !== stages.request ||
this.#fetchDomainStages.response !== stages.response ||
this.#fetchDomainStages.auth !== stages.auth;
this.#logger?.(LogType.debugInfo, 'Toggle Network', `Fetch (${fetchEnable}) ${fetchChanged}`);
if (fetchEnable && fetchChanged) {
await this.#enableFetch(stages);
}
if (!fetchEnable && fetchChanged) {
await this.#disableFetch();
}
}
getChannels() {
return this.#preloadScriptStorage
.find()
.flatMap((script) => script.channels);
}
async #updateWindowId() {
const { windowId } = await this.#browserCdpClient.sendCommand('Browser.getWindowForTarget', { targetId: this.id });
this.#windowId = windowId;
}
async #initAndEvaluatePreloadScripts() {
await Promise.all(this.#preloadScriptStorage
.find({
targetId: this.topLevelId,
})
.map((script) => {
return script.initInTarget(this, true);
}));
}
async setViewport(viewport, devicePixelRatio) {
if (viewport === null && devicePixelRatio === null) {
await this.cdpClient.sendCommand('Emulation.clearDeviceMetricsOverride');
return;
}
const newViewport = { ...this.#previousDeviceMetricsOverride };
if (viewport === null) {
newViewport.width = 0;
newViewport.height = 0;
}
else if (viewport !== undefined) {
newViewport.width = viewport.width;
newViewport.height = viewport.height;
}
if (devicePixelRatio === null) {
newViewport.deviceScaleFactor = 0;
}
else if (devicePixelRatio !== undefined) {
newViewport.deviceScaleFactor = devicePixelRatio;
}
try {
await this.cdpClient.sendCommand('Emulation.setDeviceMetricsOverride', newViewport);
this.#previousDeviceMetricsOverride = newViewport;
}
catch (err) {
if (err.message.startsWith(
'Width and height values must be positive')) {
throw new UnsupportedOperationException('Provided viewport dimensions are not supported');
}
throw err;
}
}
async #setUserContextConfig() {
const promises = [];
const config = this.contextConfigStorage.getActiveConfig(this.topLevelId, this.#userContext);
promises.push(this.#cdpClient
.sendCommand('Page.setPrerenderingAllowed', {
isAllowed: !config.prerenderingDisabled,
})
.catch(() => {
}));
if (config.viewport !== undefined ||
config.devicePixelRatio !== undefined) {
promises.push(this.setViewport(config.viewport, config.devicePixelRatio).catch(() => {
}));
}
if (config.screenOrientation !== undefined &&
config.screenOrientation !== null) {
promises.push(this.setScreenOrientationOverride(config.screenOrientation).catch(() => {
}));
}
if (config.geolocation !== undefined && config.geolocation !== null) {
promises.push(this.setGeolocationOverride(config.geolocation));
}
if (config.locale !== undefined) {
promises.push(this.setLocaleOverride(config.locale));
}
if (config.timezone !== undefined) {
promises.push(this.setTimezoneOverride(config.timezone));
}
if (config.extraHeaders !== undefined) {
promises.push(this.setExtraHeaders(config.extraHeaders));
}
if (config.scriptingEnabled !== undefined) {
promises.push(this.setScriptingEnabled(config.scriptingEnabled));
}
if (config.acceptInsecureCerts !== undefined) {
promises.push(this.cdpClient.sendCommand('Security.setIgnoreCertificateErrors', {
ignore: config.acceptInsecureCerts,
}));
}
await Promise.all(promises);
}
get topLevelId() {
return (this.#browsingContextStorage.findTopLevelContextId(this.id) ?? this.id);
}
isSubscribedTo(moduleOrEvent) {
return this.#eventManager.subscriptionManager.isSubscribedTo(moduleOrEvent, this.topLevelId);
}
#ignoreFileDialog() {
const config = this.contextConfigStorage.getActiveConfig(this.topLevelId, this.#userContext);
return ((config.userPromptHandler?.file ??
config.userPromptHandler?.default ??
"ignore" ) ===
"ignore" );
}
async setGeolocationOverride(geolocation) {
if (geolocation === null) {
await this.cdpClient.sendCommand('Emulation.clearGeolocationOverride');
}
else if ('type' in geolocation) {
if (geolocation.type !== 'positionUnavailable') {
throw new UnknownErrorException(`Unknown geolocation error ${geolocation.type}`);
}
await this.cdpClient.sendCommand('Emulation.setGeolocationOverride', {});
}
else if ('latitude' in geolocation) {
await this.cdpClient.sendCommand('Emulation.setGeolocationOverride', {
latitude: geolocation.latitude,
longitude: geolocation.longitude,
accuracy: geolocation.accuracy ?? 1,
altitude: geolocation.altitude ?? undefined,
altitudeAccuracy: geolocation.altitudeAccuracy ?? undefined,
heading: geolocation.heading ?? undefined,
speed: geolocation.speed ?? undefined,
});
}
else {
throw new UnknownErrorException('Unexpected geolocation coordinates value');
}
}
async setScreenOrientationOverride(screenOrientation) {
const newViewport = { ...this.#previousDeviceMetricsOverride };
if (screenOrientation === null) {
delete newViewport.screenOrientation;
}
else {
newViewport.screenOrientation =
this.#toCdpScreenOrientationAngle(screenOrientation);
}
await this.cdpClient.sendCommand('Emulation.setDeviceMetricsOverride', newViewport);
this.#previousDeviceMetricsOverride = newViewport;
}
#toCdpScreenOrientationAngle(orientation) {
if (orientation.natural === "portrait" ) {
switch (orientation.type) {
case 'portrait-primary':
return {
angle: 0,
type: 'portraitPrimary',
};
case 'landscape-primary':
return {
angle: 90,
type: 'landscapePrimary',
};
case 'portrait-secondary':
return {
angle: 180,
type: 'portraitSecondary',
};
case 'landscape-secondary':
return {
angle: 270,
type: 'landscapeSecondary',
};
default:
throw new UnknownErrorException(`Unexpected screen orientation type ${orientation.type}`);
}
}
if (orientation.natural === "landscape" ) {
switch (orientation.type) {
case 'landscape-primary':
return {
angle: 0,
type: 'landscapePrimary',
};
case 'portrait-primary':
return {
angle: 90,
type: 'portraitPrimary',
};
case 'landscape-secondary':
return {
angle: 180,
type: 'landscapeSecondary',
};
case 'portrait-secondary':
return {
angle: 270,
type: 'portraitSecondary',
};
default:
throw new UnknownErrorException(`Unexpected screen orientation type ${orientation.type}`);
}
}
throw new UnknownErrorException(`Unexpected orientation natural ${orientation.natural}`);
}
async setLocaleOverride(locale) {
if (locale === null) {
await this.cdpClient.sendCommand('Emulation.setLocaleOverride', {});
}
else {
await this.cdpClient.sendCommand('Emulation.setLocaleOverride', {
locale,
});
}
}
async setScriptingEnabled(scriptingEnabled) {
await this.cdpClient.sendCommand('Emulation.setScriptExecutionDisabled', {
value: scriptingEnabled === false,
});
}
async setTimezoneOverride(timezone) {
if (timezone === null) {
await this.cdpClient.sendCommand('Emulation.setTimezoneOverride', {
timezoneId: '',
});
}
else {
await this.cdpClient.sendCommand('Emulation.setTimezoneOverride', {
timezoneId: timezone,
});
}
}
async setExtraHeaders(headers) {
await this.cdpClient.sendCommand('Network.setExtraHTTPHeaders', {
headers,
});
}
}
const cdpToBidiTargetTypes = {
service_worker: 'service-worker',
shared_worker: 'shared-worker',
worker: 'dedicated-worker',
};
class CdpTargetManager {
#browserCdpClient;
#cdpConnection;
#targetKeysToBeIgnoredByAutoAttach = new Set();
#selfTargetId;
#eventManager;
#browsingContextStorage;
#networkStorage;
#bluetoothProcessor;
#preloadScriptStorage;
#realmStorage;
#configStorage;
#defaultUserContextId;
#logger;
constructor(cdpConnection, browserCdpClient, selfTargetId, eventManager, browsingContextStorage, realmStorage, networkStorage, configStorage, bluetoothProcessor, preloadScriptStorage, defaultUserContextId, logger) {
this.#cdpConnection = cdpConnection;
this.#browserCdpClient = browserCdpClient;
this.#targetKeysToBeIgnoredByAutoAttach.add(selfTargetId);
this.#selfTargetId = selfTargetId;
this.#eventManager = eventManager;
this.#browsingContextStorage = browsingContextStorage;
this.#preloadScriptStorage = preloadScriptStorage;
this.#networkStorage = networkStorage;
this.#configStorage = configStorage;
this.#bluetoothProcessor = bluetoothProcessor;
this.#realmStorage = realmStorage;
this.#defaultUserContextId = defaultUserContextId;
this.#logger = logger;
this.#setEventListeners(browserCdpClient);
}
#setEventListeners(cdpClient) {
cdpClient.on('Target.attachedToTarget', (params) => {
this.#handleAttachedToTargetEvent(params, cdpClient);
});
cdpClient.on('Target.detachedFromTarget', this.#handleDetachedFromTargetEvent.bind(this));
cdpClient.on('Target.targetInfoChanged', this.#handleTargetInfoChangedEvent.bind(this));
cdpClient.on('Inspector.targetCrashed', () => {
this.#handleTargetCrashedEvent(cdpClient);
});
cdpClient.on('Page.frameAttached', this.#handleFrameAttachedEvent.bind(this));
cdpClient.on('Page.frameSubtreeWillBeDetached', this.#handleFrameSubtreeWillBeDetached.bind(this));
}
#handleFrameAttachedEvent(params) {
const parentBrowsingContext = this.#browsingContextStorage.findContext(params.parentFrameId);
if (parentBrowsingContext !== undefined) {
BrowsingContextImpl.create(params.frameId, params.parentFrameId, parentBrowsingContext.userContext, parentBrowsingContext.cdpTarget, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, this.#configStorage,
'about:blank', undefined, this.#logger);
}
}
#handleFrameSubtreeWillBeDetached(params) {
this.#browsingContextStorage.findContext(params.frameId)?.dispose(true);
}
#handleAttachedToTargetEvent(params, parentSessionCdpClient) {
const { sessionId, targetInfo } = params;
const targetCdpClient = this.#cdpConnection.getCdpClient(sessionId);
const detach = async () => {
await targetCdpClient
.sendCommand('Runtime.runIfWaitingForDebugger')
.then(() => parentSessionCdpClient.sendCommand('Target.detachFromTarget', params))
.catch((error) => this.#logger?.(LogType.debugError, error));
};
if (this.#selfTargetId === targetInfo.targetId) {
void detach();
return;
}
const targetKey = targetInfo.type === 'service_worker'
? `${parentSessionCdpClient.sessionId}_${targetInfo.targetId}`
: targetInfo.targetId;
if (this.#targetKeysToBeIgnoredByAutoAttach.has(targetKey)) {
return;
}
this.#targetKeysToBeIgnoredByAutoAttach.add(targetKey);
const userContext = targetInfo.browserContextId &&
targetInfo.browserContextId !== this.#defaultUserContextId
? targetInfo.browserContextId
: 'default';
switch (targetInfo.type) {
case 'tab': {
this.#setEventListeners(targetCdpClient);
void (async () => {
await targetCdpClient.sendCommand('Target.setAutoAttach', {
autoAttach: true,
waitForDebuggerOnStart: true,
flatten: true,
});
})();
return;
}
case 'page':
case 'iframe': {
const cdpTarget = this.#createCdpTarget(targetCdpClient, parentSessionCdpClient, targetInfo, userContext);
const maybeContext = this.#browsingContextStorage.findContext(targetInfo.targetId);
if (maybeContext && targetInfo.type === 'iframe') {
maybeContext.updateCdpTarget(cdpTarget);
}
else {
const parentId = this.#findFrameParentId(targetInfo, parentSessionCdpClient.sessionId);
BrowsingContextImpl.create(targetInfo.targetId, parentId, userContext, cdpTarget, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, this.#configStorage,
targetInfo.url === '' ? 'about:blank' : targetInfo.url, targetInfo.openerFrameId ?? targetInfo.openerId, this.#logger);
}
return;
}
case 'service_worker':
case 'worker': {
const realm = this.#realmStorage.findRealm({
cdpSessionId: parentSessionCdpClient.sessionId,
});
if (!realm) {
void detach();
return;
}
const cdpTarget = this.#createCdpTarget(targetCdpClient, parentSessionCdpClient, targetInfo, userContext);
this.#handleWorkerTarget(cdpToBidiTargetTypes[targetInfo.type], cdpTarget, realm);
return;
}
case 'shared_worker': {
const cdpTarget = this.#createCdpTarget(targetCdpClient, parentSessionCdpClient, targetInfo, userContext);
this.#handleWorkerTarget(cdpToBidiTargetTypes[targetInfo.type], cdpTarget);
return;
}
}
void detach();
}
#findFrameParentId(targetInfo, parentSessionId) {
if (targetInfo.type !== 'iframe') {
return null;
}
const parentId = targetInfo.openerFrameId ?? targetInfo.openerId;
if (parentId !== undefined) {
return parentId;
}
if (parentSessionId !== undefined) {
return (this.#browsingContextStorage.findContextBySession(parentSessionId)
?.id ?? null);
}
return null;
}
#createCdpTarget(targetCdpClient, parentCdpClient, targetInfo, userContext) {
this.#setEventListeners(targetCdpClient);
this.#preloadScriptStorage.onCdpTargetCreated(targetInfo.targetId, userContext);
const target = CdpTarget.create(targetInfo.targetId, targetCdpClient, this.#browserCdpClient, parentCdpClient, this.#realmStorage, this.#eventManager, this.#preloadScriptStorage, this.#browsingContextStorage, this.#networkStorage, this.#configStorage, userContext, this.#logger);
this.#networkStorage.onCdpTargetCreated(target);
this.#bluetoothProcessor.onCdpTargetCreated(target);
return target;
}
#workers = new Map();
#handleWorkerTarget(realmType, cdpTarget, ownerRealm) {
cdpTarget.cdpClient.on('Runtime.executionContextCreated', (params) => {
const { uniqueId, id, origin } = params.context;
const workerRealm = new WorkerRealm(cdpTarget.cdpClient, this.#eventManager, id, this.#logger, serializeOrigin(origin), ownerRealm ? [ownerRealm] : [], uniqueId, this.#realmStorage, realmType);
this.#workers.set(cdpTarget.cdpSessionId, workerRealm);
});
}
#handleDetachedFromTargetEvent({ sessionId, targetId, }) {
if (targetId) {
this.#preloadScriptStorage.find({ targetId }).map((preloadScript) => {
preloadScript.dispose(targetId);
});
}
const context = this.#browsingContextStorage.findContextBySession(sessionId);
if (context) {
context.dispose(true);
return;
}
const worker = this.#workers.get(sessionId);
if (worker) {
this.#realmStorage.deleteRealms({
cdpSessionId: worker.cdpClient.sessionId,
});
}
}
#handleTargetInfoChangedEvent(params) {
const context = this.#browsingContextStorage.findContext(params.targetInfo.targetId);
if (context) {
context.onTargetInfoChanged(params);
}
}
#handleTargetCrashedEvent(cdpClient) {
const realms = this.#realmStorage.findRealms({
cdpSessionId: cdpClient.sessionId,
});
for (const realm of realms) {
realm.dispose();
}
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class BrowsingContextStorage {
#contexts = new Map();
#eventEmitter = new EventEmitter();
getTopLevelContexts() {
return this.getAllContexts().filter((context) => context.isTopLevelContext());
}
getAllContexts() {
return Array.from(this.#contexts.values());
}
deleteContextById(id) {
this.#contexts.delete(id);
}
deleteContext(context) {
this.#contexts.delete(context.id);
}
addContext(context) {
this.#contexts.set(context.id, context);
this.#eventEmitter.emit("added" , {
browsingContext: context,
});
}
waitForContext(browsingContextId) {
if (this.#contexts.has(browsingContextId)) {
return Promise.resolve(this.getContext(browsingContextId));
}
return new Promise((resolve) => {
const listener = (event) => {
if (event.browsingContext.id === browsingContextId) {
this.#eventEmitter.off("added" , listener);
resolve(event.browsingContext);
}
};
this.#eventEmitter.on("added" , listener);
});
}
hasContext(id) {
return this.#contexts.has(id);
}
findContext(id) {
return this.#contexts.get(id);
}
findTopLevelContextId(id) {
if (id === null) {
return null;
}
const maybeContext = this.findContext(id);
if (!maybeContext) {
return null;
}
const parentId = maybeContext.parentId ?? null;
if (parentId === null) {
return id;
}
return this.findTopLevelContextId(parentId);
}
findContextBySession(sessionId) {
for (const context of this.#contexts.values()) {
if (context.cdpTarget.cdpSessionId === sessionId) {
return context;
}
}
return;
}
getContext(id) {
const result = this.findContext(id);
if (result === undefined) {
throw new NoSuchFrameException(`Context ${id} not found`);
}
return result;
}
verifyTopLevelContextsList(contexts) {
const foundContexts = new Set();
if (!contexts) {
return foundContexts;
}
for (const contextId of contexts) {
const context = this.getContext(contextId);
if (context.isTopLevelContext()) {
foundContexts.add(context);
}
else {
throw new InvalidArgumentException(`Non top-level context '${contextId}' given.`);
}
}
return foundContexts;
}
verifyContextsList(contexts) {
if (!contexts.length) {
return;
}
for (const contextId of contexts) {
this.getContext(contextId);
}
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DefaultMap extends Map {
#getDefaultValue;
constructor(getDefaultValue, entries) {
super(entries);
this.#getDefaultValue = getDefaultValue;
}
get(key) {
if (!this.has(key)) {
this.set(key, this.#getDefaultValue(key));
}
return super.get(key);
}
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
var _a$3;
const REALM_REGEX = /(?<=realm=").*(?=")/;
class NetworkRequest {
static unknownParameter = 'UNKNOWN';
#id;
#fetchId;
#interceptPhase;
#servedFromCache = false;
#redirectCount;
#request = {};
#requestOverrides;
#responseOverrides;
#response = {};
#eventManager;
#networkStorage;
#cdpTarget;
#logger;
#emittedEvents = {
[Network$2.EventNames.AuthRequired]: false,
[Network$2.EventNames.BeforeRequestSent]: false,
[Network$2.EventNames.FetchError]: false,
[Network$2.EventNames.ResponseCompleted]: false,
[Network$2.EventNames.ResponseStarted]: false,
};
waitNextPhase = new Deferred();
constructor(id, eventManager, networkStorage, cdpTarget, redirectCount = 0, logger) {
this.#id = id;
this.#eventManager = eventManager;
this.#networkStorage = networkStorage;
this.#cdpTarget = cdpTarget;
this.#redirectCount = redirectCount;
this.#logger = logger;
}
get id() {
return this.#id;
}
get fetchId() {
return this.#fetchId;
}
get interceptPhase() {
return this.#interceptPhase;
}
get url() {
const fragment = this.#request.info?.request.urlFragment ??
this.#request.paused?.request.urlFragment ??
'';
const url = this.#response.paused?.request.url ??
this.#requestOverrides?.url ??
this.#response.info?.url ??
this.#request.auth?.request.url ??
this.#request.info?.request.url ??
this.#request.paused?.request.url ??
_a$3.unknownParameter;
return `${url}${fragment}`;
}
get redirectCount() {
return this.#redirectCount;
}
get cdpTarget() {
return this.#cdpTarget;
}
get cdpClient() {
return this.#cdpTarget.cdpClient;
}
isRedirecting() {
return Boolean(this.#request.info);
}
#isDataUrl() {
return this.url.startsWith('data:');
}
get #method() {
return (this.#requestOverrides?.method ??
this.#request.info?.request.method ??
this.#request.paused?.request.method ??
this.#request.auth?.request.method ??
this.#response.paused?.request.method);
}
get #navigationId() {
if (!this.#request.info ||
!this.#request.info.loaderId ||
this.#request.info.loaderId !== this.#request.info.requestId) {
return null;
}
return this.#networkStorage.getNavigationId(this.#context ?? undefined);
}
get #cookies() {
let cookies = [];
if (this.#request.extraInfo) {
cookies = this.#request.extraInfo.associatedCookies
.filter(({ blockedReasons }) => {
return !Array.isArray(blockedReasons) || blockedReasons.length === 0;
})
.map(({ cookie }) => cdpToBiDiCookie(cookie));
}
return cookies;
}
get #bodySize() {
let bodySize = 0;
if (typeof this.#requestOverrides?.bodySize === 'number') {
bodySize = this.#requestOverrides.bodySize;
}
else {
bodySize = bidiBodySizeFromCdpPostDataEntries(this.#request.info?.request.postDataEntries ?? []);
}
return bodySize;
}
get #context() {
const result = this.#response.paused?.frameId ??
this.#request.info?.frameId ??
this.#request.paused?.frameId ??
this.#request.auth?.frameId;
if (result !== undefined) {
return result;
}
if (this.#request?.info?.initiator.type === 'preflight' &&
this.#request?.info?.initiator.requestId !== undefined) {
const maybeInitiator = this.#networkStorage.getRequestById(this.#request?.info?.initiator.requestId);
if (maybeInitiator !== undefined) {
return maybeInitiator.#request.info?.frameId ?? null;
}
}
return null;
}
get #statusCode() {
return (this.#responseOverrides?.statusCode ??
this.#response.paused?.responseStatusCode ??
this.#response.extraInfo?.statusCode ??
this.#response.info?.status);
}
get #requestHeaders() {
let headers = [];
if (this.#requestOverrides?.headers) {
const headerMap = new DefaultMap(() => []);
for (const header of this.#requestOverrides.headers) {
headerMap.get(header.name).push(header.value.value);
}
for (const [name, value] of headerMap.entries()) {
headers.push({
name,
value: {
type: 'string',
value: value.join('\n').trimEnd(),
},
});
}
}
else {
headers = [
...bidiNetworkHeadersFromCdpNetworkHeaders(this.#request.info?.request.headers),
...bidiNetworkHeadersFromCdpNetworkHeaders(this.#request.extraInfo?.headers),
];
}
return headers;
}
get #authChallenges() {
if (!this.#response.info) {
return;
}
if (!(this.#statusCode === 401 || this.#statusCode === 407)) {
return undefined;
}
const headerName = this.#statusCode === 401 ? 'WWW-Authenticate' : 'Proxy-Authenticate';
const authChallenges = [];
for (const [header, value] of Object.entries(this.#response.info.headers)) {
if (header.localeCompare(headerName, undefined, { sensitivity: 'base' }) === 0) {
authChallenges.push({
scheme: value.split(' ').at(0) ?? '',
realm: value.match(REALM_REGEX)?.at(0) ?? '',
});
}
}
return authChallenges;
}
get #timings() {
const responseTimeOffset = getTiming(getTiming(this.#response.info?.timing?.requestTime) -
getTiming(this.#request.info?.timestamp));
return {
timeOrigin: Math.round(getTiming(this.#request.info?.wallTime) * 1000),
requestTime: 0,
redirectStart: 0,
redirectEnd: 0,
fetchStart: getTiming(this.#response.info?.timing?.workerFetchStart, responseTimeOffset),
dnsStart: getTiming(this.#response.info?.timing?.dnsStart, responseTimeOffset),
dnsEnd: getTiming(this.#response.info?.timing?.dnsEnd, responseTimeOffset),
connectStart: getTiming(this.#response.info?.timing?.connectStart, responseTimeOffset),
connectEnd: getTiming(this.#response.info?.timing?.connectEnd, responseTimeOffset),
tlsStart: getTiming(this.#response.info?.timing?.sslStart, responseTimeOffset),
requestStart: getTiming(this.#response.info?.timing?.sendStart, responseTimeOffset),
responseStart: getTiming(this.#response.info?.timing?.receiveHeadersStart, responseTimeOffset),
responseEnd: getTiming(this.#response.info?.timing?.receiveHeadersEnd, responseTimeOffset),
};
}
#phaseChanged() {
this.waitNextPhase.resolve();
this.waitNextPhase = new Deferred();
}
#interceptsInPhase(phase) {
if (!this.#cdpTarget.isSubscribedTo(`network.${phase}`)) {
return new Set();
}
return this.#networkStorage.getInterceptsForPhase(this, phase);
}
#isBlockedInPhase(phase) {
return this.#interceptsInPhase(phase).size > 0;
}
handleRedirect(event) {
this.#response.hasExtraInfo = false;
this.#response.info = event.redirectResponse;
this.#emitEventsIfReady({
wasRedirected: true,
});
}
#emitEventsIfReady(options = {}) {
const requestExtraInfoCompleted =
options.wasRedirected ||
options.hasFailed ||
this.#isDataUrl() ||
Boolean(this.#request.extraInfo) ||
this.#servedFromCache ||
Boolean(this.#response.info && !this.#response.hasExtraInfo);
const noInterceptionExpected =
this.#isDataUrl() ||
this.#servedFromCache;
const requestInterceptionExpected = !noInterceptionExpected &&
this.#isBlockedInPhase("beforeRequestSent" );
const requestInterceptionCompleted = !requestInterceptionExpected ||
(requestInterceptionExpected && Boolean(this.#request.paused));
if (Boolean(this.#request.info) &&
(requestInterceptionExpected
? requestInterceptionCompleted
: requestExtraInfoCompleted)) {
this.#emitEvent(this.#getBeforeRequestEvent.bind(this));
}
const responseExtraInfoCompleted = Boolean(this.#response.extraInfo) ||
this.#servedFromCache ||
Boolean(this.#response.info && !this.#response.hasExtraInfo);
const responseInterceptionExpected = !noInterceptionExpected &&
this.#isBlockedInPhase("responseStarted" );
if (this.#response.info ||
(responseInterceptionExpected && Boolean(this.#response.paused))) {
this.#emitEvent(this.#getResponseStartedEvent.bind(this));
}
const responseInterceptionCompleted = !responseInterceptionExpected ||
(responseInterceptionExpected && Boolean(this.#response.paused));
if (Boolean(this.#response.info) &&
responseExtraInfoCompleted &&
responseInterceptionCompleted) {
this.#emitEvent(this.#getResponseReceivedEvent.bind(this));
this.#networkStorage.disposeRequest(this.id);
}
}
onRequestWillBeSentEvent(event) {
this.#request.info = event;
this.#emitEventsIfReady();
}
onRequestWillBeSentExtraInfoEvent(event) {
this.#request.extraInfo = event;
this.#emitEventsIfReady();
}
onResponseReceivedExtraInfoEvent(event) {
if (event.statusCode >= 300 &&
event.statusCode <= 399 &&
this.#request.info &&
event.headers['location'] === this.#request.info.request.url) {
return;
}
this.#response.extraInfo = event;
this.#emitEventsIfReady();
}
onResponseReceivedEvent(event) {
this.#response.hasExtraInfo = event.hasExtraInfo;
this.#response.info = event.response;
this.#networkStorage.markRequestCollectedIfNeeded(this);
this.#emitEventsIfReady();
}
onServedFromCache() {
this.#servedFromCache = true;
this.#emitEventsIfReady();
}
onLoadingFailedEvent(event) {
this.#emitEventsIfReady({
hasFailed: true,
});
this.#emitEvent(() => {
return {
method: Network$2.EventNames.FetchError,
params: {
...this.#getBaseEventParams(),
errorText: event.errorText,
},
};
});
}
async failRequest(errorReason) {
assert(this.#fetchId, 'Network Interception not set-up.');
await this.cdpClient.sendCommand('Fetch.failRequest', {
requestId: this.#fetchId,
errorReason,
});
this.#interceptPhase = undefined;
}
onRequestPaused(event) {
this.#fetchId = event.requestId;
if (event.responseStatusCode || event.responseErrorReason) {
this.#response.paused = event;
if (this.#isBlockedInPhase("responseStarted" ) &&
!this.#emittedEvents[Network$2.EventNames.ResponseStarted] &&
this.#fetchId !== this.id) {
this.#interceptPhase = "responseStarted" ;
}
else {
void this.#continueResponse();
}
}
else {
this.#request.paused = event;
if (this.#isBlockedInPhase("beforeRequestSent" ) &&
!this.#emittedEvents[Network$2.EventNames.BeforeRequestSent] &&
this.#fetchId !== this.id) {
this.#interceptPhase = "beforeRequestSent" ;
}
else {
void this.#continueRequest();
}
}
this.#emitEventsIfReady();
}
onAuthRequired(event) {
this.#fetchId = event.requestId;
this.#request.auth = event;
if (this.#isBlockedInPhase("authRequired" ) &&
this.#fetchId !== this.id) {
this.#interceptPhase = "authRequired" ;
}
else {
void this.#continueWithAuth({
response: 'Default',
});
}
this.#emitEvent(() => {
return {
method: Network$2.EventNames.AuthRequired,
params: {
...this.#getBaseEventParams("authRequired" ),
response: this.#getResponseEventParams(),
},
};
});
}
async continueRequest(overrides = {}) {
const overrideHeaders = this.#getOverrideHeader(overrides.headers, overrides.cookies);
const headers = cdpFetchHeadersFromBidiNetworkHeaders(overrideHeaders);
const postData = getCdpBodyFromBiDiBytesValue(overrides.body);
await this.#continueRequest({
url: overrides.url,
method: overrides.method,
headers,
postData,
});
this.#requestOverrides = {
url: overrides.url,
method: overrides.method,
headers: overrides.headers,
cookies: overrides.cookies,
bodySize: getSizeFromBiDiBytesValue(overrides.body),
};
}
async #continueRequest(overrides = {}) {
assert(this.#fetchId, 'Network Interception not set-up.');
await this.cdpClient.sendCommand('Fetch.continueRequest', {
requestId: this.#fetchId,
url: overrides.url,
method: overrides.method,
headers: overrides.headers,
postData: overrides.postData,
});
this.#interceptPhase = undefined;
}
async continueResponse(overrides = {}) {
if (this.interceptPhase === "authRequired" ) {
if (overrides.credentials) {
await Promise.all([
this.waitNextPhase,
await this.#continueWithAuth({
response: 'ProvideCredentials',
username: overrides.credentials.username,
password: overrides.credentials.password,
}),
]);
}
else {
return await this.#continueWithAuth({
response: 'ProvideCredentials',
});
}
}
if (this.#interceptPhase === "responseStarted" ) {
const overrideHeaders = this.#getOverrideHeader(overrides.headers, overrides.cookies);
const responseHeaders = cdpFetchHeadersFromBidiNetworkHeaders(overrideHeaders);
await this.#continueResponse({
responseCode: overrides.statusCode ?? this.#response.paused?.responseStatusCode,
responsePhrase: overrides.reasonPhrase ?? this.#response.paused?.responseStatusText,
responseHeaders: responseHeaders ?? this.#response.paused?.responseHeaders,
});
this.#responseOverrides = {
statusCode: overrides.statusCode,
headers: overrideHeaders,
};
}
}
async #continueResponse({ responseCode, responsePhrase, responseHeaders, } = {}) {
assert(this.#fetchId, 'Network Interception not set-up.');
await this.cdpClient.sendCommand('Fetch.continueResponse', {
requestId: this.#fetchId,
responseCode,
responsePhrase,
responseHeaders,
});
this.#interceptPhase = undefined;
}
async continueWithAuth(authChallenge) {
let username;
let password;
if (authChallenge.action === 'provideCredentials') {
const { credentials } = authChallenge;
username = credentials.username;
password = credentials.password;
}
const response = cdpAuthChallengeResponseFromBidiAuthContinueWithAuthAction(authChallenge.action);
await this.#continueWithAuth({
response,
username,
password,
});
}
async provideResponse(overrides) {
assert(this.#fetchId, 'Network Interception not set-up.');
if (this.interceptPhase === "authRequired" ) {
return await this.#continueWithAuth({
response: 'ProvideCredentials',
});
}
if (!overrides.body && !overrides.headers) {
return await this.#continueRequest();
}
const overrideHeaders = this.#getOverrideHeader(overrides.headers, overrides.cookies);
const responseHeaders = cdpFetchHeadersFromBidiNetworkHeaders(overrideHeaders);
const responseCode = overrides.statusCode ?? this.#statusCode ?? 200;
await this.cdpClient.sendCommand('Fetch.fulfillRequest', {
requestId: this.#fetchId,
responseCode,
responsePhrase: overrides.reasonPhrase,
responseHeaders,
body: getCdpBodyFromBiDiBytesValue(overrides.body),
});
this.#interceptPhase = undefined;
}
dispose() {
this.waitNextPhase.reject(new Error('waitNextPhase disposed'));
}
async #continueWithAuth(authChallengeResponse) {
assert(this.#fetchId, 'Network Interception not set-up.');
await this.cdpClient.sendCommand('Fetch.continueWithAuth', {
requestId: this.#fetchId,
authChallengeResponse,
});
this.#interceptPhase = undefined;
}
#emitEvent(getEvent) {
let event;
try {
event = getEvent();
}
catch (error) {
this.#logger?.(LogType.debugError, error);
return;
}
if (this.#isIgnoredEvent() ||
(this.#emittedEvents[event.method] &&
event.method !== Network$2.EventNames.AuthRequired)) {
return;
}
this.#phaseChanged();
this.#emittedEvents[event.method] = true;
if (this.#context) {
this.#eventManager.registerEvent(Object.assign(event, {
type: 'event',
}), this.#context);
}
else {
this.#eventManager.registerGlobalEvent(Object.assign(event, {
type: 'event',
}));
}
}
#getBaseEventParams(phase) {
const interceptProps = {
isBlocked: false,
};
if (phase) {
const blockedBy = this.#interceptsInPhase(phase);
interceptProps.isBlocked = blockedBy.size > 0;
if (interceptProps.isBlocked) {
interceptProps.intercepts = [...blockedBy];
}
}
return {
context: this.#context,
navigation: this.#navigationId,
redirectCount: this.#redirectCount,
request: this.#getRequestData(),
timestamp: Math.round(getTiming(this.#request.info?.wallTime) * 1000),
...interceptProps,
};
}
#getResponseEventParams() {
if (this.#response.info?.fromDiskCache) {
this.#response.extraInfo = undefined;
}
const headers = [
...bidiNetworkHeadersFromCdpNetworkHeaders(this.#response.info?.headers),
...bidiNetworkHeadersFromCdpNetworkHeaders(this.#response.extraInfo?.headers),
];
const authChallenges = this.#authChallenges;
const response = {
url: this.url,
protocol: this.#response.info?.protocol ?? '',
status: this.#statusCode ?? -1,
statusText: this.#response.info?.statusText ||
this.#response.paused?.responseStatusText ||
'',
fromCache: this.#response.info?.fromDiskCache ||
this.#response.info?.fromPrefetchCache ||
this.#servedFromCache,
headers: this.#responseOverrides?.headers ?? headers,
mimeType: this.#response.info?.mimeType || '',
bytesReceived: this.#response.info?.encodedDataLength || 0,
headersSize: computeHeadersSize(headers),
bodySize: 0,
content: {
size: 0,
},
...(authChallenges ? { authChallenges } : {}),
};
return {
...response,
'goog:securityDetails': this.#response.info?.securityDetails,
};
}
#getRequestData() {
const headers = this.#requestHeaders;
const request = {
request: this.#id,
url: this.url,
method: this.#method ?? _a$3.unknownParameter,
headers,
cookies: this.#cookies,
headersSize: computeHeadersSize(headers),
bodySize: this.#bodySize,
destination: this.#getDestination(),
initiatorType: this.#getInitiatorType(),
timings: this.#timings,
};
return {
...request,
'goog:postData': this.#request.info?.request?.postData,
'goog:hasPostData': this.#request.info?.request?.hasPostData,
'goog:resourceType': this.#request.info?.type,
'goog:resourceInitiator': this.#request.info?.initiator,
};
}
#getDestination() {
switch (this.#request.info?.type) {
case 'Script':
return 'script';
case 'Stylesheet':
return 'style';
case 'Image':
return 'image';
case 'Document':
return this.#request.info?.initiator.type === 'parser' ? 'iframe' : '';
default:
return '';
}
}
#getInitiatorType() {
if (this.#request.info?.initiator.type === 'parser') {
switch (this.#request.info?.type) {
case 'Document':
return 'iframe';
case 'Font':
return this.#request.info?.initiator?.url ===
this.#request.info?.documentURL
? 'font'
: 'css';
case 'Image':
return this.#request.info?.initiator?.url ===
this.#request.info?.documentURL
? 'img'
: 'css';
case 'Script':
return 'script';
case 'Stylesheet':
return 'link';
default:
return null;
}
}
if (this.#request?.info?.type === 'Fetch') {
return 'fetch';
}
return null;
}
#getBeforeRequestEvent() {
assert(this.#request.info, 'RequestWillBeSentEvent is not set');
return {
method: Network$2.EventNames.BeforeRequestSent,
params: {
...this.#getBaseEventParams("beforeRequestSent" ),
initiator: {
type: _a$3.#getInitiator(this.#request.info.initiator.type),
columnNumber: this.#request.info.initiator.columnNumber,
lineNumber: this.#request.info.initiator.lineNumber,
stackTrace: this.#request.info.initiator.stack,
request: this.#request.info.initiator.requestId,
},
},
};
}
#getResponseStartedEvent() {
return {
method: Network$2.EventNames.ResponseStarted,
params: {
...this.#getBaseEventParams("responseStarted" ),
response: this.#getResponseEventParams(),
},
};
}
#getResponseReceivedEvent() {
return {
method: Network$2.EventNames.ResponseCompleted,
params: {
...this.#getBaseEventParams(),
response: this.#getResponseEventParams(),
},
};
}
#isIgnoredEvent() {
const faviconUrl = '/favicon.ico';
return (this.#request.paused?.request.url.endsWith(faviconUrl) ??
this.#request.info?.request.url.endsWith(faviconUrl) ??
false);
}
#getOverrideHeader(headers, cookies) {
if (!headers && !cookies) {
return undefined;
}
let overrideHeaders = headers;
const cookieHeader = networkHeaderFromCookieHeaders(cookies);
if (cookieHeader && !overrideHeaders) {
overrideHeaders = this.#requestHeaders;
}
if (cookieHeader && overrideHeaders) {
overrideHeaders.filter((header) => header.name.localeCompare('cookie', undefined, {
sensitivity: 'base',
}) !== 0);
overrideHeaders.push(cookieHeader);
}
return overrideHeaders;
}
static #getInitiator(initiatorType) {
switch (initiatorType) {
case 'parser':
case 'script':
case 'preflight':
return initiatorType;
default:
return 'other';
}
}
}
_a$3 = NetworkRequest;
function getCdpBodyFromBiDiBytesValue(body) {
let parsedBody;
if (body?.type === 'string') {
parsedBody = stringToBase64(body.value);
}
else if (body?.type === 'base64') {
parsedBody = body.value;
}
return parsedBody;
}
function getSizeFromBiDiBytesValue(body) {
if (body?.type === 'string') {
return body.value.length;
}
else if (body?.type === 'base64') {
return atob(body.value).length;
}
return 0;
}
class NetworkStorage {
#browsingContextStorage;
#eventManager;
#logger;
#requests = new Map();
#intercepts = new Map();
#collectors = new Map();
#requestCollectors = new Map();
#defaultCacheBehavior = 'default';
constructor(eventManager, browsingContextStorage, browserClient, logger) {
this.#browsingContextStorage = browsingContextStorage;
this.#eventManager = eventManager;
browserClient.on('Target.detachedFromTarget', ({ sessionId }) => {
this.disposeRequestMap(sessionId);
});
this.#logger = logger;
}
#getOrCreateNetworkRequest(id, cdpTarget, redirectCount) {
let request = this.getRequestById(id);
if (request) {
return request;
}
request = new NetworkRequest(id, this.#eventManager, this, cdpTarget, redirectCount, this.#logger);
this.addRequest(request);
return request;
}
onCdpTargetCreated(cdpTarget) {
const cdpClient = cdpTarget.cdpClient;
const listeners = [
[
'Network.requestWillBeSent',
(params) => {
const request = this.getRequestById(params.requestId);
if (request && request.isRedirecting()) {
request.handleRedirect(params);
this.disposeRequest(params.requestId);
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget, request.redirectCount + 1).onRequestWillBeSentEvent(params);
}
else {
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget).onRequestWillBeSentEvent(params);
}
},
],
[
'Network.requestWillBeSentExtraInfo',
(params) => {
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget).onRequestWillBeSentExtraInfoEvent(params);
},
],
[
'Network.responseReceived',
(params) => {
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget).onResponseReceivedEvent(params);
},
],
[
'Network.responseReceivedExtraInfo',
(params) => {
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget).onResponseReceivedExtraInfoEvent(params);
},
],
[
'Network.requestServedFromCache',
(params) => {
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget).onServedFromCache();
},
],
[
'Network.loadingFailed',
(params) => {
this.#getOrCreateNetworkRequest(params.requestId, cdpTarget).onLoadingFailedEvent(params);
},
],
[
'Fetch.requestPaused',
(event) => {
this.#getOrCreateNetworkRequest(
event.networkId ?? event.requestId, cdpTarget).onRequestPaused(event);
},
],
[
'Fetch.authRequired',
(event) => {
let request = this.getRequestByFetchId(event.requestId);
if (!request) {
request = this.#getOrCreateNetworkRequest(event.requestId, cdpTarget);
}
request.onAuthRequired(event);
},
],
];
for (const [event, listener] of listeners) {
cdpClient.on(event, listener);
}
}
getCollectorsForBrowsingContext(browsingContextId) {
if (!this.#browsingContextStorage.hasContext(browsingContextId)) {
this.#logger?.(LogType.debugError, 'trying to get collector for unknown browsing context');
return [];
}
const userContext = this.#browsingContextStorage.getContext(browsingContextId).userContext;
const collectors = new Set();
for (const collector of this.#collectors.values()) {
if (collector.contexts?.includes(browsingContextId)) {
collectors.add(collector);
}
if (collector.userContexts?.includes(userContext)) {
collectors.add(collector);
}
if (collector.userContexts === undefined &&
collector.contexts === undefined) {
collectors.add(collector);
}
}
return [...collectors.values()];
}
async getCollectedData(params) {
if (params.collector !== undefined &&
!this.#collectors.has(params.collector)) {
throw new NoSuchNetworkCollectorException(`Unknown collector ${params.collector}`);
}
const requestCollectors = this.#requestCollectors.get(params.request);
if (requestCollectors === undefined) {
throw new NoSuchNetworkDataException(`No collected data for request ${params.request}`);
}
if (params.collector !== undefined &&
!requestCollectors.has(params.collector)) {
throw new NoSuchNetworkDataException(`Collector ${params.collector} didn't collect data for request ${params.request}`);
}
if (params.disown && params.collector === undefined) {
throw new InvalidArgumentException('Cannot disown collected data without collector ID');
}
const request = this.getRequestById(params.request);
if (request === undefined) {
throw new NoSuchNetworkDataException(`No collected data for request ${params.request}`);
}
const responseBody = await request.cdpClient.sendCommand('Network.getResponseBody', { requestId: request.id });
if (params.disown && params.collector !== undefined) {
this.#requestCollectors.delete(params.request);
this.disposeRequest(request.id);
}
return {
bytes: {
type: responseBody.base64Encoded ? 'base64' : 'string',
value: responseBody.body,
},
};
}
#getCollectorIdsForRequest(request) {
const collectors = new Set();
for (const collectorId of this.#collectors.keys()) {
const collector = this.#collectors.get(collectorId);
if (!collector.userContexts && !collector.contexts) {
collectors.add(collectorId);
}
if (collector.contexts?.includes(request.cdpTarget.topLevelId)) {
collectors.add(collectorId);
}
if (collector.userContexts?.includes(this.#browsingContextStorage.getContext(request.cdpTarget.topLevelId)
.userContext)) {
collectors.add(collectorId);
}
}
this.#logger?.(LogType.debug, `Request ${request.id} has ${collectors.size} collectors`);
return [...collectors.values()];
}
markRequestCollectedIfNeeded(request) {
const collectorIds = this.#getCollectorIdsForRequest(request);
if (collectorIds.length > 0) {
this.#requestCollectors.set(request.id, new Set(collectorIds));
}
}
getInterceptionStages(browsingContextId) {
const stages = {
request: false,
response: false,
auth: false,
};
for (const intercept of this.#intercepts.values()) {
if (intercept.contexts &&
!intercept.contexts.includes(browsingContextId)) {
continue;
}
stages.request ||= intercept.phases.includes("beforeRequestSent" );
stages.response ||= intercept.phases.includes("responseStarted" );
stages.auth ||= intercept.phases.includes("authRequired" );
}
return stages;
}
getInterceptsForPhase(request, phase) {
if (request.url === NetworkRequest.unknownParameter) {
return new Set();
}
const intercepts = new Set();
for (const [interceptId, intercept] of this.#intercepts.entries()) {
if (!intercept.phases.includes(phase) ||
(intercept.contexts &&
!intercept.contexts.includes(request.cdpTarget.topLevelId))) {
continue;
}
if (intercept.urlPatterns.length === 0) {
intercepts.add(interceptId);
continue;
}
for (const pattern of intercept.urlPatterns) {
if (matchUrlPattern(pattern, request.url)) {
intercepts.add(interceptId);
break;
}
}
}
return intercepts;
}
disposeRequestMap(sessionId) {
for (const request of this.#requests.values()) {
if (request.cdpClient.sessionId === sessionId) {
this.#requests.delete(request.id);
request.dispose();
}
}
}
addIntercept(value) {
const interceptId = uuidv4();
this.#intercepts.set(interceptId, value);
return interceptId;
}
removeIntercept(intercept) {
if (!this.#intercepts.has(intercept)) {
throw new NoSuchInterceptException(`Intercept '${intercept}' does not exist.`);
}
this.#intercepts.delete(intercept);
}
getRequestsByTarget(target) {
const requests = [];
for (const request of this.#requests.values()) {
if (request.cdpTarget === target) {
requests.push(request);
}
}
return requests;
}
getRequestById(id) {
return this.#requests.get(id);
}
getRequestByFetchId(fetchId) {
for (const request of this.#requests.values()) {
if (request.fetchId === fetchId) {
return request;
}
}
return;
}
addRequest(request) {
this.#requests.set(request.id, request);
}
disposeRequest(id) {
if (this.#requestCollectors.get(id)?.size ?? 0 > 0) {
return;
}
this.#requests.delete(id);
}
getNavigationId(contextId) {
if (contextId === undefined) {
return null;
}
return (this.#browsingContextStorage.findContext(contextId)?.navigationId ?? null);
}
set defaultCacheBehavior(behavior) {
this.#defaultCacheBehavior = behavior;
}
get defaultCacheBehavior() {
return this.#defaultCacheBehavior;
}
addDataCollector(params) {
const collectorId = uuidv4();
this.#collectors.set(collectorId, params);
return collectorId;
}
removeDataCollector(params) {
const collectorId = params.collector;
if (!this.#collectors.has(collectorId)) {
throw new NoSuchNetworkCollectorException(`Collector ${params.collector} does not exist`);
}
this.#collectors.delete(params.collector);
for (const [requestId, collectorIds] of this.#requestCollectors) {
if (collectorIds.has(collectorId)) {
collectorIds.delete(collectorId);
if (collectorIds.size === 0) {
this.#requestCollectors.delete(requestId);
this.disposeRequest(requestId);
}
}
}
}
disownData(params) {
const collectorId = params.collector;
const requestId = params.request;
if (!this.#collectors.has(collectorId)) {
throw new NoSuchNetworkCollectorException(`Collector ${collectorId} does not exist`);
}
if (!this.#requestCollectors.has(requestId)) {
throw new NoSuchNetworkDataException(`No collected data for request ${requestId}`);
}
const collectorIds = this.#requestCollectors.get(requestId);
if (!collectorIds.has(collectorId)) {
throw new NoSuchNetworkDataException(`No collected data for request ${requestId} and collector ${collectorId}`);
}
collectorIds.delete(collectorId);
if (collectorIds.size === 0) {
this.#requestCollectors.delete(requestId);
this.disposeRequest(requestId);
}
}
}
/*
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PreloadScriptStorage {
#scripts = new Set();
find(filter) {
if (!filter) {
return [...this.#scripts];
}
return [...this.#scripts].filter((script) => {
if (script.contexts === undefined && script.userContexts === undefined) {
return true;
}
if (filter.targetId !== undefined &&
script.targetIds.has(filter.targetId)) {
return true;
}
return false;
});
}
add(preloadScript) {
this.#scripts.add(preloadScript);
}
remove(id) {
const script = [...this.#scripts].find((script) => script.id === id);
if (script === undefined) {
throw new NoSuchScriptException(`No preload script with id '${id}'`);
}
this.#scripts.delete(script);
}
getPreloadScript(id) {
const script = [...this.#scripts].find((script) => script.id === id);
if (script === undefined) {
throw new NoSuchScriptException(`No preload script with id '${id}'`);
}
return script;
}
onCdpTargetCreated(targetId, userContext) {
const scriptInUserContext = [...this.#scripts].filter((script) => {
if (!script.userContexts && !script.contexts) {
return true;
}
return script.userContexts?.includes(userContext);
});
for (const script of scriptInUserContext) {
script.targetIds.add(targetId);
}
}
}
class RealmStorage {
#knownHandlesToRealmMap = new Map();
#realmMap = new Map();
hiddenSandboxes = new Set();
get knownHandlesToRealmMap() {
return this.#knownHandlesToRealmMap;
}
addRealm(realm) {
this.#realmMap.set(realm.realmId, realm);
}
findRealms(filter) {
return Array.from(this.#realmMap.values()).filter((realm) => {
if (filter.realmId !== undefined && filter.realmId !== realm.realmId) {
return false;
}
if (filter.browsingContextId !== undefined &&
!realm.associatedBrowsingContexts
.map((browsingContext) => browsingContext.id)
.includes(filter.browsingContextId)) {
return false;
}
if (filter.sandbox !== undefined &&
(!(realm instanceof WindowRealm) || filter.sandbox !== realm.sandbox)) {
return false;
}
if (filter.executionContextId !== undefined &&
filter.executionContextId !== realm.executionContextId) {
return false;
}
if (filter.origin !== undefined && filter.origin !== realm.origin) {
return false;
}
if (filter.type !== undefined && filter.type !== realm.realmType) {
return false;
}
if (filter.cdpSessionId !== undefined &&
filter.cdpSessionId !== realm.cdpClient.sessionId) {
return false;
}
if (filter.isHidden !== undefined &&
filter.isHidden !== realm.isHidden()) {
return false;
}
return true;
});
}
findRealm(filter) {
const maybeRealms = this.findRealms(filter);
if (maybeRealms.length !== 1) {
return undefined;
}
return maybeRealms[0];
}
getRealm(filter) {
const maybeRealm = this.findRealm(filter);
if (maybeRealm === undefined) {
throw new NoSuchFrameException(`Realm ${JSON.stringify(filter)} not found`);
}
return maybeRealm;
}
deleteRealms(filter) {
this.findRealms(filter).map((realm) => {
realm.dispose();
this.#realmMap.delete(realm.realmId);
Array.from(this.knownHandlesToRealmMap.entries())
.filter(([, r]) => r === realm.realmId)
.map(([handle]) => this.knownHandlesToRealmMap.delete(handle));
});
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
let Buffer$1 = class Buffer {
#capacity;
#entries = [];
#onItemRemoved;
constructor(capacity, onItemRemoved) {
this.#capacity = capacity;
this.#onItemRemoved = onItemRemoved;
}
get() {
return this.#entries;
}
add(value) {
this.#entries.push(value);
while (this.#entries.length > this.#capacity) {
const item = this.#entries.shift();
if (item !== undefined) {
this.#onItemRemoved?.(item);
}
}
}
};
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class IdWrapper {
static #counter = 0;
#id;
constructor() {
this.#id = ++IdWrapper.#counter;
}
get id() {
return this.#id;
}
}
/**
* Copyright 2023 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function isCdpEvent(name) {
return (name.split('.').at(0)?.startsWith(BiDiModule.Cdp) ?? false);
}
function assertSupportedEvent(name) {
if (!EVENT_NAMES.has(name) && !isCdpEvent(name)) {
throw new InvalidArgumentException(`Unknown event: ${name}`);
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function unrollEvents(events) {
const allEvents = new Set();
function addEvents(events) {
for (const event of events) {
allEvents.add(event);
}
}
for (const event of events) {
switch (event) {
case BiDiModule.Bluetooth:
addEvents(Object.values(Bluetooth$2.EventNames));
break;
case BiDiModule.BrowsingContext:
addEvents(Object.values(BrowsingContext$2.EventNames));
break;
case BiDiModule.Input:
addEvents(Object.values(Input$2.EventNames));
break;
case BiDiModule.Log:
addEvents(Object.values(Log$1.EventNames));
break;
case BiDiModule.Network:
addEvents(Object.values(Network$2.EventNames));
break;
case BiDiModule.Script:
addEvents(Object.values(Script$2.EventNames));
break;
default:
allEvents.add(event);
}
}
return allEvents.values();
}
class SubscriptionManager {
#subscriptions = [];
#knownSubscriptionIds = new Set();
#browsingContextStorage;
constructor(browsingContextStorage) {
this.#browsingContextStorage = browsingContextStorage;
}
getGoogChannelsSubscribedToEvent(eventName, contextId) {
const googChannels = new Set();
for (const subscription of this.#subscriptions) {
if (this.#isSubscribedTo(subscription, eventName, contextId)) {
googChannels.add(subscription.googChannel);
}
}
return Array.from(googChannels);
}
getGoogChannelsSubscribedToEventGlobally(eventName) {
const googChannels = new Set();
for (const subscription of this.#subscriptions) {
if (this.#isSubscribedTo(subscription, eventName)) {
googChannels.add(subscription.googChannel);
}
}
return Array.from(googChannels);
}
#isSubscribedTo(subscription, moduleOrEvent, browsingContextId) {
let includesEvent = false;
for (const eventName of subscription.eventNames) {
if (
eventName === moduleOrEvent ||
eventName === moduleOrEvent.split('.').at(0) ||
eventName.split('.').at(0) === moduleOrEvent) {
includesEvent = true;
break;
}
}
if (!includesEvent) {
return false;
}
if (subscription.userContextIds.size !== 0) {
if (!browsingContextId) {
return false;
}
const context = this.#browsingContextStorage.findContext(browsingContextId);
if (!context) {
return false;
}
return subscription.userContextIds.has(context.userContext);
}
if (subscription.topLevelTraversableIds.size !== 0) {
if (!browsingContextId) {
return false;
}
const topLevelContext = this.#browsingContextStorage.findTopLevelContextId(browsingContextId);
return (topLevelContext !== null &&
subscription.topLevelTraversableIds.has(topLevelContext));
}
return true;
}
isSubscribedTo(moduleOrEvent, contextId) {
for (const subscription of this.#subscriptions) {
if (this.#isSubscribedTo(subscription, moduleOrEvent, contextId)) {
return true;
}
}
return false;
}
subscribe(eventNames, contextIds, userContextIds, googChannel) {
const subscription = {
id: uuidv4(),
eventNames: new Set(unrollEvents(eventNames)),
topLevelTraversableIds: new Set(contextIds.map((contextId) => {
const topLevelContext = this.#browsingContextStorage.findTopLevelContextId(contextId);
if (!topLevelContext) {
throw new NoSuchFrameException(`Top-level navigable not found for context id ${contextId}`);
}
return topLevelContext;
})),
userContextIds: new Set(userContextIds),
googChannel,
};
this.#subscriptions.push(subscription);
this.#knownSubscriptionIds.add(subscription.id);
return subscription;
}
unsubscribe(inputEventNames, inputContextIds, googChannel) {
const eventNames = new Set(unrollEvents(inputEventNames));
this.#browsingContextStorage.verifyContextsList(inputContextIds);
const topLevelTraversables = new Set(inputContextIds.map((contextId) => {
const topLevelContext = this.#browsingContextStorage.findTopLevelContextId(contextId);
if (!topLevelContext) {
throw new NoSuchFrameException(`Top-level navigable not found for context id ${contextId}`);
}
return topLevelContext;
}));
const isGlobalUnsubscribe = topLevelTraversables.size === 0;
const newSubscriptions = [];
const eventsMatched = new Set();
const contextsMatched = new Set();
for (const subscription of this.#subscriptions) {
if (subscription.googChannel !== googChannel) {
newSubscriptions.push(subscription);
continue;
}
if (subscription.userContextIds.size !== 0) {
newSubscriptions.push(subscription);
continue;
}
if (intersection(subscription.eventNames, eventNames).size === 0) {
newSubscriptions.push(subscription);
continue;
}
if (isGlobalUnsubscribe) {
if (subscription.topLevelTraversableIds.size !== 0) {
newSubscriptions.push(subscription);
continue;
}
const subscriptionEventNames = new Set(subscription.eventNames);
for (const eventName of eventNames) {
if (subscriptionEventNames.has(eventName)) {
eventsMatched.add(eventName);
subscriptionEventNames.delete(eventName);
}
}
if (subscriptionEventNames.size !== 0) {
newSubscriptions.push({
...subscription,
eventNames: subscriptionEventNames,
});
}
}
else {
if (subscription.topLevelTraversableIds.size === 0) {
newSubscriptions.push(subscription);
continue;
}
const eventMap = new Map();
for (const eventName of subscription.eventNames) {
eventMap.set(eventName, new Set(subscription.topLevelTraversableIds));
}
for (const eventName of eventNames) {
const eventContextSet = eventMap.get(eventName);
if (!eventContextSet) {
continue;
}
for (const toRemoveId of topLevelTraversables) {
if (eventContextSet.has(toRemoveId)) {
contextsMatched.add(toRemoveId);
eventsMatched.add(eventName);
eventContextSet.delete(toRemoveId);
}
}
if (eventContextSet.size === 0) {
eventMap.delete(eventName);
}
}
for (const [eventName, remainingContextIds] of eventMap) {
const partialSubscription = {
id: subscription.id,
googChannel: subscription.googChannel,
eventNames: new Set([eventName]),
topLevelTraversableIds: remainingContextIds,
userContextIds: new Set(),
};
newSubscriptions.push(partialSubscription);
}
}
}
if (!equal(eventsMatched, eventNames)) {
throw new InvalidArgumentException('No subscription found');
}
if (!isGlobalUnsubscribe && !equal(contextsMatched, topLevelTraversables)) {
throw new InvalidArgumentException('No subscription found');
}
this.#subscriptions = newSubscriptions;
}
unsubscribeById(subscriptionIds) {
const subscriptionIdsSet = new Set(subscriptionIds);
const unknownIds = difference(subscriptionIdsSet, this.#knownSubscriptionIds);
if (unknownIds.size !== 0) {
throw new InvalidArgumentException('No subscription found');
}
this.#subscriptions = this.#subscriptions.filter((subscription) => {
return !subscriptionIdsSet.has(subscription.id);
});
this.#knownSubscriptionIds = difference(this.#knownSubscriptionIds, subscriptionIdsSet);
}
}
function intersection(setA, setB) {
const result = new Set();
for (const a of setA) {
if (setB.has(a)) {
result.add(a);
}
}
return result;
}
function difference(setA, setB) {
const result = new Set();
for (const a of setA) {
if (!setB.has(a)) {
result.add(a);
}
}
return result;
}
function equal(setA, setB) {
if (setA.size !== setB.size) {
return false;
}
for (const a of setA) {
if (!setB.has(a)) {
return false;
}
}
return true;
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var _a$2;
class EventWrapper {
#idWrapper = new IdWrapper();
#contextId;
#event;
constructor(event, contextId) {
this.#event = event;
this.#contextId = contextId;
}
get id() {
return this.#idWrapper.id;
}
get contextId() {
return this.#contextId;
}
get event() {
return this.#event;
}
}
const eventBufferLength = new Map([[Log$1.EventNames.LogEntryAdded, 100]]);
class EventManager extends EventEmitter {
#eventToContextsMap = new DefaultMap(() => new Set());
#eventBuffers = new Map();
#lastMessageSent = new Map();
#subscriptionManager;
#browsingContextStorage;
#subscribeHooks;
#userContextStorage;
constructor(browsingContextStorage, userContextStorage) {
super();
this.#browsingContextStorage = browsingContextStorage;
this.#userContextStorage = userContextStorage;
this.#subscriptionManager = new SubscriptionManager(browsingContextStorage);
this.#subscribeHooks = new DefaultMap(() => []);
}
get subscriptionManager() {
return this.#subscriptionManager;
}
static #getMapKey(eventName, browsingContext) {
return JSON.stringify({ eventName, browsingContext });
}
addSubscribeHook(event, hook) {
this.#subscribeHooks.get(event).push(hook);
}
registerEvent(event, contextId) {
this.registerPromiseEvent(Promise.resolve({
kind: 'success',
value: event,
}), contextId, event.method);
}
registerGlobalEvent(event) {
this.registerGlobalPromiseEvent(Promise.resolve({
kind: 'success',
value: event,
}), event.method);
}
registerPromiseEvent(event, contextId, eventName) {
const eventWrapper = new EventWrapper(event, contextId);
const sortedGoogChannels = this.#subscriptionManager.getGoogChannelsSubscribedToEvent(eventName, contextId);
this.#bufferEvent(eventWrapper, eventName);
for (const googChannel of sortedGoogChannels) {
this.emit("event" , {
message: OutgoingMessage.createFromPromise(event, googChannel),
event: eventName,
});
this.#markEventSent(eventWrapper, googChannel, eventName);
}
}
registerGlobalPromiseEvent(event, eventName) {
const eventWrapper = new EventWrapper(event, null);
const sortedGoogChannels = this.#subscriptionManager.getGoogChannelsSubscribedToEventGlobally(eventName);
this.#bufferEvent(eventWrapper, eventName);
for (const googChannel of sortedGoogChannels) {
this.emit("event" , {
message: OutgoingMessage.createFromPromise(event, googChannel),
event: eventName,
});
this.#markEventSent(eventWrapper, googChannel, eventName);
}
}
async subscribe(eventNames, contextIds, userContextIds, googChannel) {
for (const name of eventNames) {
assertSupportedEvent(name);
}
if (userContextIds.length && contextIds.length) {
throw new InvalidArgumentException('Both userContexts and contexts cannot be specified.');
}
this.#browsingContextStorage.verifyContextsList(contextIds);
await this.#userContextStorage.verifyUserContextIdList(userContextIds);
const unrolledEventNames = new Set(unrollEvents(eventNames));
const subscribeStepEvents = new Map();
const subscriptionNavigableIds = new Set(contextIds.length
? contextIds.map((contextId) => {
const id = this.#browsingContextStorage.findTopLevelContextId(contextId);
if (!id) {
throw new InvalidArgumentException('Invalid context id');
}
return id;
})
: this.#browsingContextStorage.getTopLevelContexts().map((c) => c.id));
for (const eventName of unrolledEventNames) {
const subscribedNavigableIds = new Set(this.#browsingContextStorage
.getTopLevelContexts()
.map((c) => c.id)
.filter((id) => {
return this.#subscriptionManager.isSubscribedTo(eventName, id);
}));
subscribeStepEvents.set(eventName, difference(subscriptionNavigableIds, subscribedNavigableIds));
}
const subscription = this.#subscriptionManager.subscribe(eventNames, contextIds, userContextIds, googChannel);
for (const eventName of subscription.eventNames) {
for (const contextId of subscriptionNavigableIds) {
for (const eventWrapper of this.#getBufferedEvents(eventName, contextId, googChannel)) {
this.emit("event" , {
message: OutgoingMessage.createFromPromise(eventWrapper.event, googChannel),
event: eventName,
});
this.#markEventSent(eventWrapper, googChannel, eventName);
}
}
}
for (const [eventName, contextIds] of subscribeStepEvents) {
for (const contextId of contextIds) {
this.#subscribeHooks.get(eventName).forEach((hook) => hook(contextId));
}
}
await this.toggleModulesIfNeeded();
return subscription.id;
}
async unsubscribe(eventNames, contextIds, googChannel) {
for (const name of eventNames) {
assertSupportedEvent(name);
}
this.#subscriptionManager.unsubscribe(eventNames, contextIds, googChannel);
await this.toggleModulesIfNeeded();
}
async unsubscribeByIds(subscriptionIds) {
this.#subscriptionManager.unsubscribeById(subscriptionIds);
await this.toggleModulesIfNeeded();
}
async toggleModulesIfNeeded() {
await Promise.all(this.#browsingContextStorage.getAllContexts().map(async (context) => {
return await context.toggleModulesIfNeeded();
}));
}
clearBufferedEvents(contextId) {
for (const eventName of eventBufferLength.keys()) {
const bufferMapKey = _a$2.#getMapKey(eventName, contextId);
this.#eventBuffers.delete(bufferMapKey);
}
}
#bufferEvent(eventWrapper, eventName) {
if (!eventBufferLength.has(eventName)) {
return;
}
const bufferMapKey = _a$2.#getMapKey(eventName, eventWrapper.contextId);
if (!this.#eventBuffers.has(bufferMapKey)) {
this.#eventBuffers.set(bufferMapKey, new Buffer$1(eventBufferLength.get(eventName)));
}
this.#eventBuffers.get(bufferMapKey).add(eventWrapper);
this.#eventToContextsMap.get(eventName).add(eventWrapper.contextId);
}
#markEventSent(eventWrapper, googChannel, eventName) {
if (!eventBufferLength.has(eventName)) {
return;
}
const lastSentMapKey = _a$2.#getMapKey(eventName, eventWrapper.contextId);
const lastId = Math.max(this.#lastMessageSent.get(lastSentMapKey)?.get(googChannel) ?? 0, eventWrapper.id);
const googChannelMap = this.#lastMessageSent.get(lastSentMapKey);
if (googChannelMap) {
googChannelMap.set(googChannel, lastId);
}
else {
this.#lastMessageSent.set(lastSentMapKey, new Map([[googChannel, lastId]]));
}
}
#getBufferedEvents(eventName, contextId, googChannel) {
const bufferMapKey = _a$2.#getMapKey(eventName, contextId);
const lastSentMessageId = this.#lastMessageSent.get(bufferMapKey)?.get(googChannel) ?? -Infinity;
const result = this.#eventBuffers
.get(bufferMapKey)
?.get()
.filter((wrapper) => wrapper.id > lastSentMessageId) ?? [];
if (contextId === null) {
Array.from(this.#eventToContextsMap.get(eventName).keys())
.filter((_contextId) =>
_contextId !== null &&
this.#browsingContextStorage.hasContext(_contextId))
.map((_contextId) => this.#getBufferedEvents(eventName, _contextId, googChannel))
.forEach((events) => result.push(...events));
}
return result.sort((e1, e2) => e1.id - e2.id);
}
}
_a$2 = EventManager;
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class BidiServer extends EventEmitter {
#messageQueue;
#transport;
#commandProcessor;
#eventManager;
#browsingContextStorage = new BrowsingContextStorage();
#realmStorage = new RealmStorage();
#preloadScriptStorage = new PreloadScriptStorage();
#bluetoothProcessor;
#logger;
#handleIncomingMessage = (message) => {
void this.#commandProcessor.processCommand(message).catch((error) => {
this.#logger?.(LogType.debugError, error);
});
};
#processOutgoingMessage = async (messageEntry) => {
const message = messageEntry.message;
if (messageEntry.googChannel !== null) {
message['goog:channel'] = messageEntry.googChannel;
}
await this.#transport.sendMessage(message);
};
constructor(bidiTransport, cdpConnection, browserCdpClient, selfTargetId, defaultUserContextId, parser, logger) {
super();
this.#logger = logger;
this.#messageQueue = new ProcessingQueue(this.#processOutgoingMessage, this.#logger);
this.#transport = bidiTransport;
this.#transport.setOnMessage(this.#handleIncomingMessage);
const contextConfigStorage = new ContextConfigStorage();
const userContextStorage = new UserContextStorage(browserCdpClient);
this.#eventManager = new EventManager(this.#browsingContextStorage, userContextStorage);
const networkStorage = new NetworkStorage(this.#eventManager, this.#browsingContextStorage, browserCdpClient, logger);
this.#bluetoothProcessor = new BluetoothProcessor(this.#eventManager, this.#browsingContextStorage);
this.#commandProcessor = new CommandProcessor(cdpConnection, browserCdpClient, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, this.#preloadScriptStorage, networkStorage, contextConfigStorage, this.#bluetoothProcessor, userContextStorage, parser, async (options) => {
await browserCdpClient.sendCommand('Security.setIgnoreCertificateErrors', {
ignore: options.acceptInsecureCerts ?? false,
});
contextConfigStorage.updateGlobalConfig({
acceptInsecureCerts: options.acceptInsecureCerts ?? false,
userPromptHandler: options.unhandledPromptBehavior,
prerenderingDisabled: options?.['goog:prerenderingDisabled'] ?? false,
});
new CdpTargetManager(cdpConnection, browserCdpClient, selfTargetId, this.#eventManager, this.#browsingContextStorage, this.#realmStorage, networkStorage, contextConfigStorage, this.#bluetoothProcessor, this.#preloadScriptStorage, defaultUserContextId, logger);
await browserCdpClient.sendCommand('Target.setDiscoverTargets', {
discover: true,
});
await browserCdpClient.sendCommand('Target.setAutoAttach', {
autoAttach: true,
waitForDebuggerOnStart: true,
flatten: true,
filter: [
{
type: 'page',
exclude: true,
},
{},
],
});
await this.#topLevelContextsLoaded();
}, this.#logger);
this.#eventManager.on("event" , ({ message, event }) => {
this.emitOutgoingMessage(message, event);
});
this.#commandProcessor.on("response" , ({ message, event }) => {
this.emitOutgoingMessage(message, event);
});
}
static async createAndStart(bidiTransport, cdpConnection, browserCdpClient, selfTargetId, parser, logger) {
const [{ browserContextIds }, { targetInfos }] = await Promise.all([
browserCdpClient.sendCommand('Target.getBrowserContexts'),
browserCdpClient.sendCommand('Target.getTargets'),
browserCdpClient.sendCommand('Browser.setDownloadBehavior', {
behavior: 'default',
eventsEnabled: true,
}),
]);
let defaultUserContextId = 'default';
for (const info of targetInfos) {
if (info.browserContextId &&
!browserContextIds.includes(info.browserContextId)) {
defaultUserContextId = info.browserContextId;
break;
}
}
const server = new BidiServer(bidiTransport, cdpConnection, browserCdpClient, selfTargetId, defaultUserContextId, parser, logger);
return server;
}
emitOutgoingMessage(messageEntry, event) {
this.#messageQueue.add(messageEntry, event);
}
close() {
this.#transport.close();
}
async #topLevelContextsLoaded() {
await Promise.all(this.#browsingContextStorage
.getTopLevelContexts()
.map((c) => c.lifecycleLoaded()));
}
}
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class CloseError extends Error {
}
class MapperCdpClient extends EventEmitter {
#cdpConnection;
#sessionId;
constructor(cdpConnection, sessionId) {
super();
this.#cdpConnection = cdpConnection;
this.#sessionId = sessionId;
}
get sessionId() {
return this.#sessionId;
}
sendCommand(method, ...params) {
return this.#cdpConnection.sendCommand(method, params[0], this.#sessionId);
}
isCloseError(error) {
return error instanceof CloseError;
}
}
var _a$1;
class MapperCdpConnection {
static LOGGER_PREFIX_RECV = `${LogType.cdp}:RECV ◂`;
static LOGGER_PREFIX_SEND = `${LogType.cdp}:SEND ▸`;
#mainBrowserCdpClient;
#transport;
#sessionCdpClients = new Map();
#commandCallbacks = new Map();
#logger;
#nextId = 0;
constructor(transport, logger) {
this.#transport = transport;
this.#logger = logger;
this.#transport.setOnMessage(this.#onMessage);
this.#mainBrowserCdpClient = this.#createCdpClient(undefined);
}
close() {
this.#transport.close();
for (const [, { reject, error }] of this.#commandCallbacks) {
reject(error);
}
this.#commandCallbacks.clear();
this.#sessionCdpClients.clear();
}
async createBrowserSession() {
const { sessionId } = await this.#mainBrowserCdpClient.sendCommand('Target.attachToBrowserTarget');
return this.#createCdpClient(sessionId);
}
getCdpClient(sessionId) {
const cdpClient = this.#sessionCdpClients.get(sessionId);
if (!cdpClient) {
throw new Error(`Unknown CDP session ID: ${sessionId}`);
}
return cdpClient;
}
sendCommand(method, params, sessionId) {
return new Promise((resolve, reject) => {
const id = this.#nextId++;
this.#commandCallbacks.set(id, {
sessionId,
resolve,
reject,
error: new CloseError(`${method} ${JSON.stringify(params)} ${sessionId ?? ''} call rejected because the connection has been closed.`),
});
const cdpMessage = { id, method, params };
if (sessionId) {
cdpMessage.sessionId = sessionId;
}
void this.#transport
.sendMessage(JSON.stringify(cdpMessage))
?.catch((error) => {
this.#logger?.(LogType.debugError, error);
this.#transport.close();
});
this.#logger?.(_a$1.LOGGER_PREFIX_SEND, cdpMessage);
});
}
#onMessage = (json) => {
const message = JSON.parse(json);
this.#logger?.(_a$1.LOGGER_PREFIX_RECV, message);
if (message.method === 'Target.attachedToTarget') {
const { sessionId } = message.params;
this.#createCdpClient(sessionId);
}
if (message.id !== undefined) {
const callbacks = this.#commandCallbacks.get(message.id);
this.#commandCallbacks.delete(message.id);
if (callbacks) {
if (message.result) {
callbacks.resolve(message.result);
}
else if (message.error) {
callbacks.reject(message.error);
}
}
}
else if (message.method) {
const client = this.#sessionCdpClients.get(message.sessionId ?? undefined);
client?.emit(message.method, message.params || {});
if (message.method === 'Target.detachedFromTarget') {
const { sessionId } = message.params;
const client = this.#sessionCdpClients.get(sessionId);
if (client) {
this.#sessionCdpClients.delete(sessionId);
client.removeAllListeners();
}
for (const callback of this.#commandCallbacks.values()) {
if (callback.sessionId === sessionId) {
callback.reject(callback.error);
}
}
}
}
};
#createCdpClient(sessionId) {
const cdpClient = new MapperCdpClient(this, sessionId);
this.#sessionCdpClients.set(sessionId, cdpClient);
return cdpClient;
}
}
_a$1 = MapperCdpConnection;
var util;
(function (util) {
util.assertEqual = (_) => { };
function assertIs(_arg) { }
util.assertIs = assertIs;
function assertNever(_x) {
throw new Error();
}
util.assertNever = assertNever;
util.arrayToEnum = (items) => {
const obj = {};
for (const item of items) {
obj[item] = item;
}
return obj;
};
util.getValidEnumValues = (obj) => {
const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
const filtered = {};
for (const k of validKeys) {
filtered[k] = obj[k];
}
return util.objectValues(filtered);
};
util.objectValues = (obj) => {
return util.objectKeys(obj).map(function (e) {
return obj[e];
});
};
util.objectKeys = typeof Object.keys === "function"
? (obj) => Object.keys(obj)
: (object) => {
const keys = [];
for (const key in object) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
keys.push(key);
}
}
return keys;
};
util.find = (arr, checker) => {
for (const item of arr) {
if (checker(item))
return item;
}
return undefined;
};
util.isInteger = typeof Number.isInteger === "function"
? (val) => Number.isInteger(val)
: (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
function joinValues(array, separator = " | ") {
return array.map((val) => (typeof val === "string" ? `'${val}'` : val)).join(separator);
}
util.joinValues = joinValues;
util.jsonStringifyReplacer = (_, value) => {
if (typeof value === "bigint") {
return value.toString();
}
return value;
};
})(util || (util = {}));
var objectUtil;
(function (objectUtil) {
objectUtil.mergeShapes = (first, second) => {
return {
...first,
...second,
};
};
})(objectUtil || (objectUtil = {}));
const ZodParsedType = util.arrayToEnum([
"string",
"nan",
"number",
"integer",
"float",
"boolean",
"date",
"bigint",
"symbol",
"function",
"undefined",
"null",
"array",
"object",
"unknown",
"promise",
"void",
"never",
"map",
"set",
]);
const getParsedType = (data) => {
const t = typeof data;
switch (t) {
case "undefined":
return ZodParsedType.undefined;
case "string":
return ZodParsedType.string;
case "number":
return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
case "boolean":
return ZodParsedType.boolean;
case "function":
return ZodParsedType.function;
case "bigint":
return ZodParsedType.bigint;
case "symbol":
return ZodParsedType.symbol;
case "object":
if (Array.isArray(data)) {
return ZodParsedType.array;
}
if (data === null) {
return ZodParsedType.null;
}
if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {
return ZodParsedType.promise;
}
if (typeof Map !== "undefined" && data instanceof Map) {
return ZodParsedType.map;
}
if (typeof Set !== "undefined" && data instanceof Set) {
return ZodParsedType.set;
}
if (typeof Date !== "undefined" && data instanceof Date) {
return ZodParsedType.date;
}
return ZodParsedType.object;
default:
return ZodParsedType.unknown;
}
};
const ZodIssueCode = util.arrayToEnum([
"invalid_type",
"invalid_literal",
"custom",
"invalid_union",
"invalid_union_discriminator",
"invalid_enum_value",
"unrecognized_keys",
"invalid_arguments",
"invalid_return_type",
"invalid_date",
"invalid_string",
"too_small",
"too_big",
"invalid_intersection_types",
"not_multiple_of",
"not_finite",
]);
const quotelessJson = (obj) => {
const json = JSON.stringify(obj, null, 2);
return json.replace(/"([^"]+)":/g, "$1:");
};
class ZodError extends Error {
get errors() {
return this.issues;
}
constructor(issues) {
super();
this.issues = [];
this.addIssue = (sub) => {
this.issues = [...this.issues, sub];
};
this.addIssues = (subs = []) => {
this.issues = [...this.issues, ...subs];
};
const actualProto = new.target.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(this, actualProto);
}
else {
this.__proto__ = actualProto;
}
this.name = "ZodError";
this.issues = issues;
}
format(_mapper) {
const mapper = _mapper ||
function (issue) {
return issue.message;
};
const fieldErrors = { _errors: [] };
const processError = (error) => {
for (const issue of error.issues) {
if (issue.code === "invalid_union") {
issue.unionErrors.map(processError);
}
else if (issue.code === "invalid_return_type") {
processError(issue.returnTypeError);
}
else if (issue.code === "invalid_arguments") {
processError(issue.argumentsError);
}
else if (issue.path.length === 0) {
fieldErrors._errors.push(mapper(issue));
}
else {
let curr = fieldErrors;
let i = 0;
while (i < issue.path.length) {
const el = issue.path[i];
const terminal = i === issue.path.length - 1;
if (!terminal) {
curr[el] = curr[el] || { _errors: [] };
}
else {
curr[el] = curr[el] || { _errors: [] };
curr[el]._errors.push(mapper(issue));
}
curr = curr[el];
i++;
}
}
}
};
processError(this);
return fieldErrors;
}
static assert(value) {
if (!(value instanceof ZodError)) {
throw new Error(`Not a ZodError: ${value}`);
}
}
toString() {
return this.message;
}
get message() {
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
}
get isEmpty() {
return this.issues.length === 0;
}
flatten(mapper = (issue) => issue.message) {
const fieldErrors = {};
const formErrors = [];
for (const sub of this.issues) {
if (sub.path.length > 0) {
const firstEl = sub.path[0];
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
fieldErrors[firstEl].push(mapper(sub));
}
else {
formErrors.push(mapper(sub));
}
}
return { formErrors, fieldErrors };
}
get formErrors() {
return this.flatten();
}
}
ZodError.create = (issues) => {
const error = new ZodError(issues);
return error;
};
const errorMap = (issue, _ctx) => {
let message;
switch (issue.code) {
case ZodIssueCode.invalid_type:
if (issue.received === ZodParsedType.undefined) {
message = "Required";
}
else {
message = `Expected ${issue.expected}, received ${issue.received}`;
}
break;
case ZodIssueCode.invalid_literal:
message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
break;
case ZodIssueCode.unrecognized_keys:
message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
break;
case ZodIssueCode.invalid_union:
message = `Invalid input`;
break;
case ZodIssueCode.invalid_union_discriminator:
message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
break;
case ZodIssueCode.invalid_enum_value:
message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
break;
case ZodIssueCode.invalid_arguments:
message = `Invalid function arguments`;
break;
case ZodIssueCode.invalid_return_type:
message = `Invalid function return type`;
break;
case ZodIssueCode.invalid_date:
message = `Invalid date`;
break;
case ZodIssueCode.invalid_string:
if (typeof issue.validation === "object") {
if ("includes" in issue.validation) {
message = `Invalid input: must include "${issue.validation.includes}"`;
if (typeof issue.validation.position === "number") {
message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
}
}
else if ("startsWith" in issue.validation) {
message = `Invalid input: must start with "${issue.validation.startsWith}"`;
}
else if ("endsWith" in issue.validation) {
message = `Invalid input: must end with "${issue.validation.endsWith}"`;
}
else {
util.assertNever(issue.validation);
}
}
else if (issue.validation !== "regex") {
message = `Invalid ${issue.validation}`;
}
else {
message = "Invalid";
}
break;
case ZodIssueCode.too_small:
if (issue.type === "array")
message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
else if (issue.type === "string")
message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
else if (issue.type === "number")
message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
else if (issue.type === "bigint")
message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
else if (issue.type === "date")
message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
else
message = "Invalid input";
break;
case ZodIssueCode.too_big:
if (issue.type === "array")
message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
else if (issue.type === "string")
message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
else if (issue.type === "number")
message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
else if (issue.type === "bigint")
message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
else if (issue.type === "date")
message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
else
message = "Invalid input";
break;
case ZodIssueCode.custom:
message = `Invalid input`;
break;
case ZodIssueCode.invalid_intersection_types:
message = `Intersection results could not be merged`;
break;
case ZodIssueCode.not_multiple_of:
message = `Number must be a multiple of ${issue.multipleOf}`;
break;
case ZodIssueCode.not_finite:
message = "Number must be finite";
break;
default:
message = _ctx.defaultError;
util.assertNever(issue);
}
return { message };
};
let overrideErrorMap = errorMap;
function setErrorMap(map) {
overrideErrorMap = map;
}
function getErrorMap() {
return overrideErrorMap;
}
const makeIssue = (params) => {
const { data, path, errorMaps, issueData } = params;
const fullPath = [...path, ...(issueData.path || [])];
const fullIssue = {
...issueData,
path: fullPath,
};
if (issueData.message !== undefined) {
return {
...issueData,
path: fullPath,
message: issueData.message,
};
}
let errorMessage = "";
const maps = errorMaps
.filter((m) => !!m)
.slice()
.reverse();
for (const map of maps) {
errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;
}
return {
...issueData,
path: fullPath,
message: errorMessage,
};
};
const EMPTY_PATH = [];
function addIssueToContext(ctx, issueData) {
const overrideMap = getErrorMap();
const issue = makeIssue({
issueData: issueData,
data: ctx.data,
path: ctx.path,
errorMaps: [
ctx.common.contextualErrorMap,
ctx.schemaErrorMap,
overrideMap,
overrideMap === errorMap ? undefined : errorMap,
].filter((x) => !!x),
});
ctx.common.issues.push(issue);
}
class ParseStatus {
constructor() {
this.value = "valid";
}
dirty() {
if (this.value === "valid")
this.value = "dirty";
}
abort() {
if (this.value !== "aborted")
this.value = "aborted";
}
static mergeArray(status, results) {
const arrayValue = [];
for (const s of results) {
if (s.status === "aborted")
return INVALID;
if (s.status === "dirty")
status.dirty();
arrayValue.push(s.value);
}
return { status: status.value, value: arrayValue };
}
static async mergeObjectAsync(status, pairs) {
const syncPairs = [];
for (const pair of pairs) {
const key = await pair.key;
const value = await pair.value;
syncPairs.push({
key,
value,
});
}
return ParseStatus.mergeObjectSync(status, syncPairs);
}
static mergeObjectSync(status, pairs) {
const finalObject = {};
for (const pair of pairs) {
const { key, value } = pair;
if (key.status === "aborted")
return INVALID;
if (value.status === "aborted")
return INVALID;
if (key.status === "dirty")
status.dirty();
if (value.status === "dirty")
status.dirty();
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
finalObject[key.value] = value.value;
}
}
return { status: status.value, value: finalObject };
}
}
const INVALID = Object.freeze({
status: "aborted",
});
const DIRTY = (value) => ({ status: "dirty", value });
const OK = (value) => ({ status: "valid", value });
const isAborted = (x) => x.status === "aborted";
const isDirty = (x) => x.status === "dirty";
const isValid = (x) => x.status === "valid";
const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
var errorUtil;
(function (errorUtil) {
errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
errorUtil.toString = (message) => typeof message === "string" ? message : message?.message;
})(errorUtil || (errorUtil = {}));
class ParseInputLazyPath {
constructor(parent, value, path, key) {
this._cachedPath = [];
this.parent = parent;
this.data = value;
this._path = path;
this._key = key;
}
get path() {
if (!this._cachedPath.length) {
if (Array.isArray(this._key)) {
this._cachedPath.push(...this._path, ...this._key);
}
else {
this._cachedPath.push(...this._path, this._key);
}
}
return this._cachedPath;
}
}
const handleResult = (ctx, result) => {
if (isValid(result)) {
return { success: true, data: result.value };
}
else {
if (!ctx.common.issues.length) {
throw new Error("Validation failed but no issues detected.");
}
return {
success: false,
get error() {
if (this._error)
return this._error;
const error = new ZodError(ctx.common.issues);
this._error = error;
return this._error;
},
};
}
};
function processCreateParams(params) {
if (!params)
return {};
const { errorMap, invalid_type_error, required_error, description } = params;
if (errorMap && (invalid_type_error || required_error)) {
throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
}
if (errorMap)
return { errorMap: errorMap, description };
const customMap = (iss, ctx) => {
const { message } = params;
if (iss.code === "invalid_enum_value") {
return { message: message ?? ctx.defaultError };
}
if (typeof ctx.data === "undefined") {
return { message: message ?? required_error ?? ctx.defaultError };
}
if (iss.code !== "invalid_type")
return { message: ctx.defaultError };
return { message: message ?? invalid_type_error ?? ctx.defaultError };
};
return { errorMap: customMap, description };
}
class ZodType {
get description() {
return this._def.description;
}
_getType(input) {
return getParsedType(input.data);
}
_getOrReturnCtx(input, ctx) {
return (ctx || {
common: input.parent.common,
data: input.data,
parsedType: getParsedType(input.data),
schemaErrorMap: this._def.errorMap,
path: input.path,
parent: input.parent,
});
}
_processInputParams(input) {
return {
status: new ParseStatus(),
ctx: {
common: input.parent.common,
data: input.data,
parsedType: getParsedType(input.data),
schemaErrorMap: this._def.errorMap,
path: input.path,
parent: input.parent,
},
};
}
_parseSync(input) {
const result = this._parse(input);
if (isAsync(result)) {
throw new Error("Synchronous parse encountered promise.");
}
return result;
}
_parseAsync(input) {
const result = this._parse(input);
return Promise.resolve(result);
}
parse(data, params) {
const result = this.safeParse(data, params);
if (result.success)
return result.data;
throw result.error;
}
safeParse(data, params) {
const ctx = {
common: {
issues: [],
async: params?.async ?? false,
contextualErrorMap: params?.errorMap,
},
path: params?.path || [],
schemaErrorMap: this._def.errorMap,
parent: null,
data,
parsedType: getParsedType(data),
};
const result = this._parseSync({ data, path: ctx.path, parent: ctx });
return handleResult(ctx, result);
}
"~validate"(data) {
const ctx = {
common: {
issues: [],
async: !!this["~standard"].async,
},
path: [],
schemaErrorMap: this._def.errorMap,
parent: null,
data,
parsedType: getParsedType(data),
};
if (!this["~standard"].async) {
try {
const result = this._parseSync({ data, path: [], parent: ctx });
return isValid(result)
? {
value: result.value,
}
: {
issues: ctx.common.issues,
};
}
catch (err) {
if (err?.message?.toLowerCase()?.includes("encountered")) {
this["~standard"].async = true;
}
ctx.common = {
issues: [],
async: true,
};
}
}
return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result)
? {
value: result.value,
}
: {
issues: ctx.common.issues,
});
}
async parseAsync(data, params) {
const result = await this.safeParseAsync(data, params);
if (result.success)
return result.data;
throw result.error;
}
async safeParseAsync(data, params) {
const ctx = {
common: {
issues: [],
contextualErrorMap: params?.errorMap,
async: true,
},
path: params?.path || [],
schemaErrorMap: this._def.errorMap,
parent: null,
data,
parsedType: getParsedType(data),
};
const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
return handleResult(ctx, result);
}
refine(check, message) {
const getIssueProperties = (val) => {
if (typeof message === "string" || typeof message === "undefined") {
return { message };
}
else if (typeof message === "function") {
return message(val);
}
else {
return message;
}
};
return this._refinement((val, ctx) => {
const result = check(val);
const setError = () => ctx.addIssue({
code: ZodIssueCode.custom,
...getIssueProperties(val),
});
if (typeof Promise !== "undefined" && result instanceof Promise) {
return result.then((data) => {
if (!data) {
setError();
return false;
}
else {
return true;
}
});
}
if (!result) {
setError();
return false;
}
else {
return true;
}
});
}
refinement(check, refinementData) {
return this._refinement((val, ctx) => {
if (!check(val)) {
ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
return false;
}
else {
return true;
}
});
}
_refinement(refinement) {
return new ZodEffects({
schema: this,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect: { type: "refinement", refinement },
});
}
superRefine(refinement) {
return this._refinement(refinement);
}
constructor(def) {
this.spa = this.safeParseAsync;
this._def = def;
this.parse = this.parse.bind(this);
this.safeParse = this.safeParse.bind(this);
this.parseAsync = this.parseAsync.bind(this);
this.safeParseAsync = this.safeParseAsync.bind(this);
this.spa = this.spa.bind(this);
this.refine = this.refine.bind(this);
this.refinement = this.refinement.bind(this);
this.superRefine = this.superRefine.bind(this);
this.optional = this.optional.bind(this);
this.nullable = this.nullable.bind(this);
this.nullish = this.nullish.bind(this);
this.array = this.array.bind(this);
this.promise = this.promise.bind(this);
this.or = this.or.bind(this);
this.and = this.and.bind(this);
this.transform = this.transform.bind(this);
this.brand = this.brand.bind(this);
this.default = this.default.bind(this);
this.catch = this.catch.bind(this);
this.describe = this.describe.bind(this);
this.pipe = this.pipe.bind(this);
this.readonly = this.readonly.bind(this);
this.isNullable = this.isNullable.bind(this);
this.isOptional = this.isOptional.bind(this);
this["~standard"] = {
version: 1,
vendor: "zod",
validate: (data) => this["~validate"](data),
};
}
optional() {
return ZodOptional.create(this, this._def);
}
nullable() {
return ZodNullable.create(this, this._def);
}
nullish() {
return this.nullable().optional();
}
array() {
return ZodArray.create(this);
}
promise() {
return ZodPromise.create(this, this._def);
}
or(option) {
return ZodUnion.create([this, option], this._def);
}
and(incoming) {
return ZodIntersection.create(this, incoming, this._def);
}
transform(transform) {
return new ZodEffects({
...processCreateParams(this._def),
schema: this,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect: { type: "transform", transform },
});
}
default(def) {
const defaultValueFunc = typeof def === "function" ? def : () => def;
return new ZodDefault({
...processCreateParams(this._def),
innerType: this,
defaultValue: defaultValueFunc,
typeName: ZodFirstPartyTypeKind.ZodDefault,
});
}
brand() {
return new ZodBranded({
typeName: ZodFirstPartyTypeKind.ZodBranded,
type: this,
...processCreateParams(this._def),
});
}
catch(def) {
const catchValueFunc = typeof def === "function" ? def : () => def;
return new ZodCatch({
...processCreateParams(this._def),
innerType: this,
catchValue: catchValueFunc,
typeName: ZodFirstPartyTypeKind.ZodCatch,
});
}
describe(description) {
const This = this.constructor;
return new This({
...this._def,
description,
});
}
pipe(target) {
return ZodPipeline.create(this, target);
}
readonly() {
return ZodReadonly.create(this);
}
isOptional() {
return this.safeParse(undefined).success;
}
isNullable() {
return this.safeParse(null).success;
}
}
const cuidRegex = /^c[^\s-]{8,}$/i;
const cuid2Regex = /^[0-9a-z]+$/;
const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
const nanoidRegex = /^[a-z0-9_-]{21}$/i;
const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
let emojiRegex;
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
const ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
const ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
const dateRegex = new RegExp(`^${dateRegexSource}$`);
function timeRegexSource(args) {
let secondsRegexSource = `[0-5]\\d`;
if (args.precision) {
secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
}
else if (args.precision == null) {
secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
}
const secondsQuantifier = args.precision ? "+" : "?";
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
}
function timeRegex(args) {
return new RegExp(`^${timeRegexSource(args)}$`);
}
function datetimeRegex(args) {
let regex = `${dateRegexSource}T${timeRegexSource(args)}`;
const opts = [];
opts.push(args.local ? `Z?` : `Z`);
if (args.offset)
opts.push(`([+-]\\d{2}:?\\d{2})`);
regex = `${regex}(${opts.join("|")})`;
return new RegExp(`^${regex}$`);
}
function isValidIP(ip, version) {
if ((version === "v4" || !version) && ipv4Regex.test(ip)) {
return true;
}
if ((version === "v6" || !version) && ipv6Regex.test(ip)) {
return true;
}
return false;
}
function isValidJWT(jwt, alg) {
if (!jwtRegex.test(jwt))
return false;
try {
const [header] = jwt.split(".");
if (!header)
return false;
const base64 = header
.replace(/-/g, "+")
.replace(/_/g, "/")
.padEnd(header.length + ((4 - (header.length % 4)) % 4), "=");
const decoded = JSON.parse(atob(base64));
if (typeof decoded !== "object" || decoded === null)
return false;
if ("typ" in decoded && decoded?.typ !== "JWT")
return false;
if (!decoded.alg)
return false;
if (alg && decoded.alg !== alg)
return false;
return true;
}
catch {
return false;
}
}
function isValidCidr(ip, version) {
if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {
return true;
}
if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {
return true;
}
return false;
}
class ZodString extends ZodType {
_parse(input) {
if (this._def.coerce) {
input.data = String(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.string) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.string,
received: ctx.parsedType,
});
return INVALID;
}
const status = new ParseStatus();
let ctx = undefined;
for (const check of this._def.checks) {
if (check.kind === "min") {
if (input.data.length < check.value) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
minimum: check.value,
type: "string",
inclusive: true,
exact: false,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "max") {
if (input.data.length > check.value) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
maximum: check.value,
type: "string",
inclusive: true,
exact: false,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "length") {
const tooBig = input.data.length > check.value;
const tooSmall = input.data.length < check.value;
if (tooBig || tooSmall) {
ctx = this._getOrReturnCtx(input, ctx);
if (tooBig) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
maximum: check.value,
type: "string",
inclusive: true,
exact: true,
message: check.message,
});
}
else if (tooSmall) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
minimum: check.value,
type: "string",
inclusive: true,
exact: true,
message: check.message,
});
}
status.dirty();
}
}
else if (check.kind === "email") {
if (!emailRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "email",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "emoji") {
if (!emojiRegex) {
emojiRegex = new RegExp(_emojiRegex, "u");
}
if (!emojiRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "emoji",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "uuid") {
if (!uuidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "uuid",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "nanoid") {
if (!nanoidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "nanoid",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "cuid") {
if (!cuidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "cuid",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "cuid2") {
if (!cuid2Regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "cuid2",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "ulid") {
if (!ulidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "ulid",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "url") {
try {
new URL(input.data);
}
catch {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "url",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "regex") {
check.regex.lastIndex = 0;
const testResult = check.regex.test(input.data);
if (!testResult) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "regex",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "trim") {
input.data = input.data.trim();
}
else if (check.kind === "includes") {
if (!input.data.includes(check.value, check.position)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: { includes: check.value, position: check.position },
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "toLowerCase") {
input.data = input.data.toLowerCase();
}
else if (check.kind === "toUpperCase") {
input.data = input.data.toUpperCase();
}
else if (check.kind === "startsWith") {
if (!input.data.startsWith(check.value)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: { startsWith: check.value },
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "endsWith") {
if (!input.data.endsWith(check.value)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: { endsWith: check.value },
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "datetime") {
const regex = datetimeRegex(check);
if (!regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: "datetime",
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "date") {
const regex = dateRegex;
if (!regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: "date",
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "time") {
const regex = timeRegex(check);
if (!regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: "time",
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "duration") {
if (!durationRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "duration",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "ip") {
if (!isValidIP(input.data, check.version)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "ip",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "jwt") {
if (!isValidJWT(input.data, check.alg)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "jwt",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "cidr") {
if (!isValidCidr(input.data, check.version)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "cidr",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "base64") {
if (!base64Regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "base64",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "base64url") {
if (!base64urlRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "base64url",
code: ZodIssueCode.invalid_string,
message: check.message,
});
status.dirty();
}
}
else {
util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
_regex(regex, validation, message) {
return this.refinement((data) => regex.test(data), {
validation,
code: ZodIssueCode.invalid_string,
...errorUtil.errToObj(message),
});
}
_addCheck(check) {
return new ZodString({
...this._def,
checks: [...this._def.checks, check],
});
}
email(message) {
return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) });
}
url(message) {
return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) });
}
emoji(message) {
return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) });
}
uuid(message) {
return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) });
}
nanoid(message) {
return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) });
}
cuid(message) {
return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) });
}
cuid2(message) {
return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) });
}
ulid(message) {
return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) });
}
base64(message) {
return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });
}
base64url(message) {
return this._addCheck({
kind: "base64url",
...errorUtil.errToObj(message),
});
}
jwt(options) {
return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) });
}
ip(options) {
return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
}
cidr(options) {
return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });
}
datetime(options) {
if (typeof options === "string") {
return this._addCheck({
kind: "datetime",
precision: null,
offset: false,
local: false,
message: options,
});
}
return this._addCheck({
kind: "datetime",
precision: typeof options?.precision === "undefined" ? null : options?.precision,
offset: options?.offset ?? false,
local: options?.local ?? false,
...errorUtil.errToObj(options?.message),
});
}
date(message) {
return this._addCheck({ kind: "date", message });
}
time(options) {
if (typeof options === "string") {
return this._addCheck({
kind: "time",
precision: null,
message: options,
});
}
return this._addCheck({
kind: "time",
precision: typeof options?.precision === "undefined" ? null : options?.precision,
...errorUtil.errToObj(options?.message),
});
}
duration(message) {
return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) });
}
regex(regex, message) {
return this._addCheck({
kind: "regex",
regex: regex,
...errorUtil.errToObj(message),
});
}
includes(value, options) {
return this._addCheck({
kind: "includes",
value: value,
position: options?.position,
...errorUtil.errToObj(options?.message),
});
}
startsWith(value, message) {
return this._addCheck({
kind: "startsWith",
value: value,
...errorUtil.errToObj(message),
});
}
endsWith(value, message) {
return this._addCheck({
kind: "endsWith",
value: value,
...errorUtil.errToObj(message),
});
}
min(minLength, message) {
return this._addCheck({
kind: "min",
value: minLength,
...errorUtil.errToObj(message),
});
}
max(maxLength, message) {
return this._addCheck({
kind: "max",
value: maxLength,
...errorUtil.errToObj(message),
});
}
length(len, message) {
return this._addCheck({
kind: "length",
value: len,
...errorUtil.errToObj(message),
});
}
nonempty(message) {
return this.min(1, errorUtil.errToObj(message));
}
trim() {
return new ZodString({
...this._def,
checks: [...this._def.checks, { kind: "trim" }],
});
}
toLowerCase() {
return new ZodString({
...this._def,
checks: [...this._def.checks, { kind: "toLowerCase" }],
});
}
toUpperCase() {
return new ZodString({
...this._def,
checks: [...this._def.checks, { kind: "toUpperCase" }],
});
}
get isDatetime() {
return !!this._def.checks.find((ch) => ch.kind === "datetime");
}
get isDate() {
return !!this._def.checks.find((ch) => ch.kind === "date");
}
get isTime() {
return !!this._def.checks.find((ch) => ch.kind === "time");
}
get isDuration() {
return !!this._def.checks.find((ch) => ch.kind === "duration");
}
get isEmail() {
return !!this._def.checks.find((ch) => ch.kind === "email");
}
get isURL() {
return !!this._def.checks.find((ch) => ch.kind === "url");
}
get isEmoji() {
return !!this._def.checks.find((ch) => ch.kind === "emoji");
}
get isUUID() {
return !!this._def.checks.find((ch) => ch.kind === "uuid");
}
get isNANOID() {
return !!this._def.checks.find((ch) => ch.kind === "nanoid");
}
get isCUID() {
return !!this._def.checks.find((ch) => ch.kind === "cuid");
}
get isCUID2() {
return !!this._def.checks.find((ch) => ch.kind === "cuid2");
}
get isULID() {
return !!this._def.checks.find((ch) => ch.kind === "ulid");
}
get isIP() {
return !!this._def.checks.find((ch) => ch.kind === "ip");
}
get isCIDR() {
return !!this._def.checks.find((ch) => ch.kind === "cidr");
}
get isBase64() {
return !!this._def.checks.find((ch) => ch.kind === "base64");
}
get isBase64url() {
return !!this._def.checks.find((ch) => ch.kind === "base64url");
}
get minLength() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min;
}
get maxLength() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max;
}
}
ZodString.create = (params) => {
return new ZodString({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodString,
coerce: params?.coerce ?? false,
...processCreateParams(params),
});
};
function floatSafeRemainder(val, step) {
const valDecCount = (val.toString().split(".")[1] || "").length;
const stepDecCount = (step.toString().split(".")[1] || "").length;
const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
const valInt = Number.parseInt(val.toFixed(decCount).replace(".", ""));
const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
return (valInt % stepInt) / 10 ** decCount;
}
class ZodNumber extends ZodType {
constructor() {
super(...arguments);
this.min = this.gte;
this.max = this.lte;
this.step = this.multipleOf;
}
_parse(input) {
if (this._def.coerce) {
input.data = Number(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.number) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.number,
received: ctx.parsedType,
});
return INVALID;
}
let ctx = undefined;
const status = new ParseStatus();
for (const check of this._def.checks) {
if (check.kind === "int") {
if (!util.isInteger(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: "integer",
received: "float",
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "min") {
const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
if (tooSmall) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
minimum: check.value,
type: "number",
inclusive: check.inclusive,
exact: false,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "max") {
const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
if (tooBig) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
maximum: check.value,
type: "number",
inclusive: check.inclusive,
exact: false,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "multipleOf") {
if (floatSafeRemainder(input.data, check.value) !== 0) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.not_multiple_of,
multipleOf: check.value,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "finite") {
if (!Number.isFinite(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.not_finite,
message: check.message,
});
status.dirty();
}
}
else {
util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
gte(value, message) {
return this.setLimit("min", value, true, errorUtil.toString(message));
}
gt(value, message) {
return this.setLimit("min", value, false, errorUtil.toString(message));
}
lte(value, message) {
return this.setLimit("max", value, true, errorUtil.toString(message));
}
lt(value, message) {
return this.setLimit("max", value, false, errorUtil.toString(message));
}
setLimit(kind, value, inclusive, message) {
return new ZodNumber({
...this._def,
checks: [
...this._def.checks,
{
kind,
value,
inclusive,
message: errorUtil.toString(message),
},
],
});
}
_addCheck(check) {
return new ZodNumber({
...this._def,
checks: [...this._def.checks, check],
});
}
int(message) {
return this._addCheck({
kind: "int",
message: errorUtil.toString(message),
});
}
positive(message) {
return this._addCheck({
kind: "min",
value: 0,
inclusive: false,
message: errorUtil.toString(message),
});
}
negative(message) {
return this._addCheck({
kind: "max",
value: 0,
inclusive: false,
message: errorUtil.toString(message),
});
}
nonpositive(message) {
return this._addCheck({
kind: "max",
value: 0,
inclusive: true,
message: errorUtil.toString(message),
});
}
nonnegative(message) {
return this._addCheck({
kind: "min",
value: 0,
inclusive: true,
message: errorUtil.toString(message),
});
}
multipleOf(value, message) {
return this._addCheck({
kind: "multipleOf",
value: value,
message: errorUtil.toString(message),
});
}
finite(message) {
return this._addCheck({
kind: "finite",
message: errorUtil.toString(message),
});
}
safe(message) {
return this._addCheck({
kind: "min",
inclusive: true,
value: Number.MIN_SAFE_INTEGER,
message: errorUtil.toString(message),
})._addCheck({
kind: "max",
inclusive: true,
value: Number.MAX_SAFE_INTEGER,
message: errorUtil.toString(message),
});
}
get minValue() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min;
}
get maxValue() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max;
}
get isInt() {
return !!this._def.checks.find((ch) => ch.kind === "int" || (ch.kind === "multipleOf" && util.isInteger(ch.value)));
}
get isFinite() {
let max = null;
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {
return true;
}
else if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
else if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return Number.isFinite(min) && Number.isFinite(max);
}
}
ZodNumber.create = (params) => {
return new ZodNumber({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodNumber,
coerce: params?.coerce || false,
...processCreateParams(params),
});
};
class ZodBigInt extends ZodType {
constructor() {
super(...arguments);
this.min = this.gte;
this.max = this.lte;
}
_parse(input) {
if (this._def.coerce) {
try {
input.data = BigInt(input.data);
}
catch {
return this._getInvalidInput(input);
}
}
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.bigint) {
return this._getInvalidInput(input);
}
let ctx = undefined;
const status = new ParseStatus();
for (const check of this._def.checks) {
if (check.kind === "min") {
const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
if (tooSmall) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
type: "bigint",
minimum: check.value,
inclusive: check.inclusive,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "max") {
const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
if (tooBig) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
type: "bigint",
maximum: check.value,
inclusive: check.inclusive,
message: check.message,
});
status.dirty();
}
}
else if (check.kind === "multipleOf") {
if (input.data % check.value !== BigInt(0)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.not_multiple_of,
multipleOf: check.value,
message: check.message,
});
status.dirty();
}
}
else {
util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
_getInvalidInput(input) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.bigint,
received: ctx.parsedType,
});
return INVALID;
}
gte(value, message) {
return this.setLimit("min", value, true, errorUtil.toString(message));
}
gt(value, message) {
return this.setLimit("min", value, false, errorUtil.toString(message));
}
lte(value, message) {
return this.setLimit("max", value, true, errorUtil.toString(message));
}
lt(value, message) {
return this.setLimit("max", value, false, errorUtil.toString(message));
}
setLimit(kind, value, inclusive, message) {
return new ZodBigInt({
...this._def,
checks: [
...this._def.checks,
{
kind,
value,
inclusive,
message: errorUtil.toString(message),
},
],
});
}
_addCheck(check) {
return new ZodBigInt({
...this._def,
checks: [...this._def.checks, check],
});
}
positive(message) {
return this._addCheck({
kind: "min",
value: BigInt(0),
inclusive: false,
message: errorUtil.toString(message),
});
}
negative(message) {
return this._addCheck({
kind: "max",
value: BigInt(0),
inclusive: false,
message: errorUtil.toString(message),
});
}
nonpositive(message) {
return this._addCheck({
kind: "max",
value: BigInt(0),
inclusive: true,
message: errorUtil.toString(message),
});
}
nonnegative(message) {
return this._addCheck({
kind: "min",
value: BigInt(0),
inclusive: true,
message: errorUtil.toString(message),
});
}
multipleOf(value, message) {
return this._addCheck({
kind: "multipleOf",
value,
message: errorUtil.toString(message),
});
}
get minValue() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min;
}
get maxValue() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max;
}
}
ZodBigInt.create = (params) => {
return new ZodBigInt({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodBigInt,
coerce: params?.coerce ?? false,
...processCreateParams(params),
});
};
class ZodBoolean extends ZodType {
_parse(input) {
if (this._def.coerce) {
input.data = Boolean(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.boolean) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.boolean,
received: ctx.parsedType,
});
return INVALID;
}
return OK(input.data);
}
}
ZodBoolean.create = (params) => {
return new ZodBoolean({
typeName: ZodFirstPartyTypeKind.ZodBoolean,
coerce: params?.coerce || false,
...processCreateParams(params),
});
};
class ZodDate extends ZodType {
_parse(input) {
if (this._def.coerce) {
input.data = new Date(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.date) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.date,
received: ctx.parsedType,
});
return INVALID;
}
if (Number.isNaN(input.data.getTime())) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_date,
});
return INVALID;
}
const status = new ParseStatus();
let ctx = undefined;
for (const check of this._def.checks) {
if (check.kind === "min") {
if (input.data.getTime() < check.value) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
message: check.message,
inclusive: true,
exact: false,
minimum: check.value,
type: "date",
});
status.dirty();
}
}
else if (check.kind === "max") {
if (input.data.getTime() > check.value) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
message: check.message,
inclusive: true,
exact: false,
maximum: check.value,
type: "date",
});
status.dirty();
}
}
else {
util.assertNever(check);
}
}
return {
status: status.value,
value: new Date(input.data.getTime()),
};
}
_addCheck(check) {
return new ZodDate({
...this._def,
checks: [...this._def.checks, check],
});
}
min(minDate, message) {
return this._addCheck({
kind: "min",
value: minDate.getTime(),
message: errorUtil.toString(message),
});
}
max(maxDate, message) {
return this._addCheck({
kind: "max",
value: maxDate.getTime(),
message: errorUtil.toString(message),
});
}
get minDate() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min != null ? new Date(min) : null;
}
get maxDate() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max != null ? new Date(max) : null;
}
}
ZodDate.create = (params) => {
return new ZodDate({
checks: [],
coerce: params?.coerce || false,
typeName: ZodFirstPartyTypeKind.ZodDate,
...processCreateParams(params),
});
};
class ZodSymbol extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.symbol) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.symbol,
received: ctx.parsedType,
});
return INVALID;
}
return OK(input.data);
}
}
ZodSymbol.create = (params) => {
return new ZodSymbol({
typeName: ZodFirstPartyTypeKind.ZodSymbol,
...processCreateParams(params),
});
};
class ZodUndefined extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.undefined) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.undefined,
received: ctx.parsedType,
});
return INVALID;
}
return OK(input.data);
}
}
ZodUndefined.create = (params) => {
return new ZodUndefined({
typeName: ZodFirstPartyTypeKind.ZodUndefined,
...processCreateParams(params),
});
};
class ZodNull extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.null) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.null,
received: ctx.parsedType,
});
return INVALID;
}
return OK(input.data);
}
}
ZodNull.create = (params) => {
return new ZodNull({
typeName: ZodFirstPartyTypeKind.ZodNull,
...processCreateParams(params),
});
};
class ZodAny extends ZodType {
constructor() {
super(...arguments);
this._any = true;
}
_parse(input) {
return OK(input.data);
}
}
ZodAny.create = (params) => {
return new ZodAny({
typeName: ZodFirstPartyTypeKind.ZodAny,
...processCreateParams(params),
});
};
class ZodUnknown extends ZodType {
constructor() {
super(...arguments);
this._unknown = true;
}
_parse(input) {
return OK(input.data);
}
}
ZodUnknown.create = (params) => {
return new ZodUnknown({
typeName: ZodFirstPartyTypeKind.ZodUnknown,
...processCreateParams(params),
});
};
class ZodNever extends ZodType {
_parse(input) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.never,
received: ctx.parsedType,
});
return INVALID;
}
}
ZodNever.create = (params) => {
return new ZodNever({
typeName: ZodFirstPartyTypeKind.ZodNever,
...processCreateParams(params),
});
};
class ZodVoid extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.undefined) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.void,
received: ctx.parsedType,
});
return INVALID;
}
return OK(input.data);
}
}
ZodVoid.create = (params) => {
return new ZodVoid({
typeName: ZodFirstPartyTypeKind.ZodVoid,
...processCreateParams(params),
});
};
class ZodArray extends ZodType {
_parse(input) {
const { ctx, status } = this._processInputParams(input);
const def = this._def;
if (ctx.parsedType !== ZodParsedType.array) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.array,
received: ctx.parsedType,
});
return INVALID;
}
if (def.exactLength !== null) {
const tooBig = ctx.data.length > def.exactLength.value;
const tooSmall = ctx.data.length < def.exactLength.value;
if (tooBig || tooSmall) {
addIssueToContext(ctx, {
code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,
minimum: (tooSmall ? def.exactLength.value : undefined),
maximum: (tooBig ? def.exactLength.value : undefined),
type: "array",
inclusive: true,
exact: true,
message: def.exactLength.message,
});
status.dirty();
}
}
if (def.minLength !== null) {
if (ctx.data.length < def.minLength.value) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
minimum: def.minLength.value,
type: "array",
inclusive: true,
exact: false,
message: def.minLength.message,
});
status.dirty();
}
}
if (def.maxLength !== null) {
if (ctx.data.length > def.maxLength.value) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
maximum: def.maxLength.value,
type: "array",
inclusive: true,
exact: false,
message: def.maxLength.message,
});
status.dirty();
}
}
if (ctx.common.async) {
return Promise.all([...ctx.data].map((item, i) => {
return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
})).then((result) => {
return ParseStatus.mergeArray(status, result);
});
}
const result = [...ctx.data].map((item, i) => {
return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
});
return ParseStatus.mergeArray(status, result);
}
get element() {
return this._def.type;
}
min(minLength, message) {
return new ZodArray({
...this._def,
minLength: { value: minLength, message: errorUtil.toString(message) },
});
}
max(maxLength, message) {
return new ZodArray({
...this._def,
maxLength: { value: maxLength, message: errorUtil.toString(message) },
});
}
length(len, message) {
return new ZodArray({
...this._def,
exactLength: { value: len, message: errorUtil.toString(message) },
});
}
nonempty(message) {
return this.min(1, message);
}
}
ZodArray.create = (schema, params) => {
return new ZodArray({
type: schema,
minLength: null,
maxLength: null,
exactLength: null,
typeName: ZodFirstPartyTypeKind.ZodArray,
...processCreateParams(params),
});
};
function deepPartialify(schema) {
if (schema instanceof ZodObject) {
const newShape = {};
for (const key in schema.shape) {
const fieldSchema = schema.shape[key];
newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));
}
return new ZodObject({
...schema._def,
shape: () => newShape,
});
}
else if (schema instanceof ZodArray) {
return new ZodArray({
...schema._def,
type: deepPartialify(schema.element),
});
}
else if (schema instanceof ZodOptional) {
return ZodOptional.create(deepPartialify(schema.unwrap()));
}
else if (schema instanceof ZodNullable) {
return ZodNullable.create(deepPartialify(schema.unwrap()));
}
else if (schema instanceof ZodTuple) {
return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));
}
else {
return schema;
}
}
class ZodObject extends ZodType {
constructor() {
super(...arguments);
this._cached = null;
this.nonstrict = this.passthrough;
this.augment = this.extend;
}
_getCached() {
if (this._cached !== null)
return this._cached;
const shape = this._def.shape();
const keys = util.objectKeys(shape);
this._cached = { shape, keys };
return this._cached;
}
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.object) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.object,
received: ctx.parsedType,
});
return INVALID;
}
const { status, ctx } = this._processInputParams(input);
const { shape, keys: shapeKeys } = this._getCached();
const extraKeys = [];
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
for (const key in ctx.data) {
if (!shapeKeys.includes(key)) {
extraKeys.push(key);
}
}
}
const pairs = [];
for (const key of shapeKeys) {
const keyValidator = shape[key];
const value = ctx.data[key];
pairs.push({
key: { status: "valid", value: key },
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
alwaysSet: key in ctx.data,
});
}
if (this._def.catchall instanceof ZodNever) {
const unknownKeys = this._def.unknownKeys;
if (unknownKeys === "passthrough") {
for (const key of extraKeys) {
pairs.push({
key: { status: "valid", value: key },
value: { status: "valid", value: ctx.data[key] },
});
}
}
else if (unknownKeys === "strict") {
if (extraKeys.length > 0) {
addIssueToContext(ctx, {
code: ZodIssueCode.unrecognized_keys,
keys: extraKeys,
});
status.dirty();
}
}
else if (unknownKeys === "strip") ;
else {
throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);
}
}
else {
const catchall = this._def.catchall;
for (const key of extraKeys) {
const value = ctx.data[key];
pairs.push({
key: { status: "valid", value: key },
value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)
),
alwaysSet: key in ctx.data,
});
}
}
if (ctx.common.async) {
return Promise.resolve()
.then(async () => {
const syncPairs = [];
for (const pair of pairs) {
const key = await pair.key;
const value = await pair.value;
syncPairs.push({
key,
value,
alwaysSet: pair.alwaysSet,
});
}
return syncPairs;
})
.then((syncPairs) => {
return ParseStatus.mergeObjectSync(status, syncPairs);
});
}
else {
return ParseStatus.mergeObjectSync(status, pairs);
}
}
get shape() {
return this._def.shape();
}
strict(message) {
errorUtil.errToObj;
return new ZodObject({
...this._def,
unknownKeys: "strict",
...(message !== undefined
? {
errorMap: (issue, ctx) => {
const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
if (issue.code === "unrecognized_keys")
return {
message: errorUtil.errToObj(message).message ?? defaultError,
};
return {
message: defaultError,
};
},
}
: {}),
});
}
strip() {
return new ZodObject({
...this._def,
unknownKeys: "strip",
});
}
passthrough() {
return new ZodObject({
...this._def,
unknownKeys: "passthrough",
});
}
extend(augmentation) {
return new ZodObject({
...this._def,
shape: () => ({
...this._def.shape(),
...augmentation,
}),
});
}
merge(merging) {
const merged = new ZodObject({
unknownKeys: merging._def.unknownKeys,
catchall: merging._def.catchall,
shape: () => ({
...this._def.shape(),
...merging._def.shape(),
}),
typeName: ZodFirstPartyTypeKind.ZodObject,
});
return merged;
}
setKey(key, schema) {
return this.augment({ [key]: schema });
}
catchall(index) {
return new ZodObject({
...this._def,
catchall: index,
});
}
pick(mask) {
const shape = {};
for (const key of util.objectKeys(mask)) {
if (mask[key] && this.shape[key]) {
shape[key] = this.shape[key];
}
}
return new ZodObject({
...this._def,
shape: () => shape,
});
}
omit(mask) {
const shape = {};
for (const key of util.objectKeys(this.shape)) {
if (!mask[key]) {
shape[key] = this.shape[key];
}
}
return new ZodObject({
...this._def,
shape: () => shape,
});
}
deepPartial() {
return deepPartialify(this);
}
partial(mask) {
const newShape = {};
for (const key of util.objectKeys(this.shape)) {
const fieldSchema = this.shape[key];
if (mask && !mask[key]) {
newShape[key] = fieldSchema;
}
else {
newShape[key] = fieldSchema.optional();
}
}
return new ZodObject({
...this._def,
shape: () => newShape,
});
}
required(mask) {
const newShape = {};
for (const key of util.objectKeys(this.shape)) {
if (mask && !mask[key]) {
newShape[key] = this.shape[key];
}
else {
const fieldSchema = this.shape[key];
let newField = fieldSchema;
while (newField instanceof ZodOptional) {
newField = newField._def.innerType;
}
newShape[key] = newField;
}
}
return new ZodObject({
...this._def,
shape: () => newShape,
});
}
keyof() {
return createZodEnum(util.objectKeys(this.shape));
}
}
ZodObject.create = (shape, params) => {
return new ZodObject({
shape: () => shape,
unknownKeys: "strip",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params),
});
};
ZodObject.strictCreate = (shape, params) => {
return new ZodObject({
shape: () => shape,
unknownKeys: "strict",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params),
});
};
ZodObject.lazycreate = (shape, params) => {
return new ZodObject({
shape,
unknownKeys: "strip",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params),
});
};
class ZodUnion extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
const options = this._def.options;
function handleResults(results) {
for (const result of results) {
if (result.result.status === "valid") {
return result.result;
}
}
for (const result of results) {
if (result.result.status === "dirty") {
ctx.common.issues.push(...result.ctx.common.issues);
return result.result;
}
}
const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors,
});
return INVALID;
}
if (ctx.common.async) {
return Promise.all(options.map(async (option) => {
const childCtx = {
...ctx,
common: {
...ctx.common,
issues: [],
},
parent: null,
};
return {
result: await option._parseAsync({
data: ctx.data,
path: ctx.path,
parent: childCtx,
}),
ctx: childCtx,
};
})).then(handleResults);
}
else {
let dirty = undefined;
const issues = [];
for (const option of options) {
const childCtx = {
...ctx,
common: {
...ctx.common,
issues: [],
},
parent: null,
};
const result = option._parseSync({
data: ctx.data,
path: ctx.path,
parent: childCtx,
});
if (result.status === "valid") {
return result;
}
else if (result.status === "dirty" && !dirty) {
dirty = { result, ctx: childCtx };
}
if (childCtx.common.issues.length) {
issues.push(childCtx.common.issues);
}
}
if (dirty) {
ctx.common.issues.push(...dirty.ctx.common.issues);
return dirty.result;
}
const unionErrors = issues.map((issues) => new ZodError(issues));
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors,
});
return INVALID;
}
}
get options() {
return this._def.options;
}
}
ZodUnion.create = (types, params) => {
return new ZodUnion({
options: types,
typeName: ZodFirstPartyTypeKind.ZodUnion,
...processCreateParams(params),
});
};
const getDiscriminator = (type) => {
if (type instanceof ZodLazy) {
return getDiscriminator(type.schema);
}
else if (type instanceof ZodEffects) {
return getDiscriminator(type.innerType());
}
else if (type instanceof ZodLiteral) {
return [type.value];
}
else if (type instanceof ZodEnum) {
return type.options;
}
else if (type instanceof ZodNativeEnum) {
return util.objectValues(type.enum);
}
else if (type instanceof ZodDefault) {
return getDiscriminator(type._def.innerType);
}
else if (type instanceof ZodUndefined) {
return [undefined];
}
else if (type instanceof ZodNull) {
return [null];
}
else if (type instanceof ZodOptional) {
return [undefined, ...getDiscriminator(type.unwrap())];
}
else if (type instanceof ZodNullable) {
return [null, ...getDiscriminator(type.unwrap())];
}
else if (type instanceof ZodBranded) {
return getDiscriminator(type.unwrap());
}
else if (type instanceof ZodReadonly) {
return getDiscriminator(type.unwrap());
}
else if (type instanceof ZodCatch) {
return getDiscriminator(type._def.innerType);
}
else {
return [];
}
};
class ZodDiscriminatedUnion extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.object) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.object,
received: ctx.parsedType,
});
return INVALID;
}
const discriminator = this.discriminator;
const discriminatorValue = ctx.data[discriminator];
const option = this.optionsMap.get(discriminatorValue);
if (!option) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union_discriminator,
options: Array.from(this.optionsMap.keys()),
path: [discriminator],
});
return INVALID;
}
if (ctx.common.async) {
return option._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx,
});
}
else {
return option._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx,
});
}
}
get discriminator() {
return this._def.discriminator;
}
get options() {
return this._def.options;
}
get optionsMap() {
return this._def.optionsMap;
}
static create(discriminator, options, params) {
const optionsMap = new Map();
for (const type of options) {
const discriminatorValues = getDiscriminator(type.shape[discriminator]);
if (!discriminatorValues.length) {
throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
}
for (const value of discriminatorValues) {
if (optionsMap.has(value)) {
throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
}
optionsMap.set(value, type);
}
}
return new ZodDiscriminatedUnion({
typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
discriminator,
options,
optionsMap,
...processCreateParams(params),
});
}
}
function mergeValues(a, b) {
const aType = getParsedType(a);
const bType = getParsedType(b);
if (a === b) {
return { valid: true, data: a };
}
else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
const bKeys = util.objectKeys(b);
const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);
const newObj = { ...a, ...b };
for (const key of sharedKeys) {
const sharedValue = mergeValues(a[key], b[key]);
if (!sharedValue.valid) {
return { valid: false };
}
newObj[key] = sharedValue.data;
}
return { valid: true, data: newObj };
}
else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
if (a.length !== b.length) {
return { valid: false };
}
const newArray = [];
for (let index = 0; index < a.length; index++) {
const itemA = a[index];
const itemB = b[index];
const sharedValue = mergeValues(itemA, itemB);
if (!sharedValue.valid) {
return { valid: false };
}
newArray.push(sharedValue.data);
}
return { valid: true, data: newArray };
}
else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) {
return { valid: true, data: a };
}
else {
return { valid: false };
}
}
class ZodIntersection extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
const handleParsed = (parsedLeft, parsedRight) => {
if (isAborted(parsedLeft) || isAborted(parsedRight)) {
return INVALID;
}
const merged = mergeValues(parsedLeft.value, parsedRight.value);
if (!merged.valid) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_intersection_types,
});
return INVALID;
}
if (isDirty(parsedLeft) || isDirty(parsedRight)) {
status.dirty();
}
return { status: status.value, value: merged.data };
};
if (ctx.common.async) {
return Promise.all([
this._def.left._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx,
}),
this._def.right._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx,
}),
]).then(([left, right]) => handleParsed(left, right));
}
else {
return handleParsed(this._def.left._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx,
}), this._def.right._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx,
}));
}
}
}
ZodIntersection.create = (left, right, params) => {
return new ZodIntersection({
left: left,
right: right,
typeName: ZodFirstPartyTypeKind.ZodIntersection,
...processCreateParams(params),
});
};
class ZodTuple extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.array) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.array,
received: ctx.parsedType,
});
return INVALID;
}
if (ctx.data.length < this._def.items.length) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
minimum: this._def.items.length,
inclusive: true,
exact: false,
type: "array",
});
return INVALID;
}
const rest = this._def.rest;
if (!rest && ctx.data.length > this._def.items.length) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
maximum: this._def.items.length,
inclusive: true,
exact: false,
type: "array",
});
status.dirty();
}
const items = [...ctx.data]
.map((item, itemIndex) => {
const schema = this._def.items[itemIndex] || this._def.rest;
if (!schema)
return null;
return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));
})
.filter((x) => !!x);
if (ctx.common.async) {
return Promise.all(items).then((results) => {
return ParseStatus.mergeArray(status, results);
});
}
else {
return ParseStatus.mergeArray(status, items);
}
}
get items() {
return this._def.items;
}
rest(rest) {
return new ZodTuple({
...this._def,
rest,
});
}
}
ZodTuple.create = (schemas, params) => {
if (!Array.isArray(schemas)) {
throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
}
return new ZodTuple({
items: schemas,
typeName: ZodFirstPartyTypeKind.ZodTuple,
rest: null,
...processCreateParams(params),
});
};
class ZodRecord extends ZodType {
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.object) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.object,
received: ctx.parsedType,
});
return INVALID;
}
const pairs = [];
const keyType = this._def.keyType;
const valueType = this._def.valueType;
for (const key in ctx.data) {
pairs.push({
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
alwaysSet: key in ctx.data,
});
}
if (ctx.common.async) {
return ParseStatus.mergeObjectAsync(status, pairs);
}
else {
return ParseStatus.mergeObjectSync(status, pairs);
}
}
get element() {
return this._def.valueType;
}
static create(first, second, third) {
if (second instanceof ZodType) {
return new ZodRecord({
keyType: first,
valueType: second,
typeName: ZodFirstPartyTypeKind.ZodRecord,
...processCreateParams(third),
});
}
return new ZodRecord({
keyType: ZodString.create(),
valueType: first,
typeName: ZodFirstPartyTypeKind.ZodRecord,
...processCreateParams(second),
});
}
}
class ZodMap extends ZodType {
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.map) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.map,
received: ctx.parsedType,
});
return INVALID;
}
const keyType = this._def.keyType;
const valueType = this._def.valueType;
const pairs = [...ctx.data.entries()].map(([key, value], index) => {
return {
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"])),
};
});
if (ctx.common.async) {
const finalMap = new Map();
return Promise.resolve().then(async () => {
for (const pair of pairs) {
const key = await pair.key;
const value = await pair.value;
if (key.status === "aborted" || value.status === "aborted") {
return INVALID;
}
if (key.status === "dirty" || value.status === "dirty") {
status.dirty();
}
finalMap.set(key.value, value.value);
}
return { status: status.value, value: finalMap };
});
}
else {
const finalMap = new Map();
for (const pair of pairs) {
const key = pair.key;
const value = pair.value;
if (key.status === "aborted" || value.status === "aborted") {
return INVALID;
}
if (key.status === "dirty" || value.status === "dirty") {
status.dirty();
}
finalMap.set(key.value, value.value);
}
return { status: status.value, value: finalMap };
}
}
}
ZodMap.create = (keyType, valueType, params) => {
return new ZodMap({
valueType,
keyType,
typeName: ZodFirstPartyTypeKind.ZodMap,
...processCreateParams(params),
});
};
class ZodSet extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.set) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.set,
received: ctx.parsedType,
});
return INVALID;
}
const def = this._def;
if (def.minSize !== null) {
if (ctx.data.size < def.minSize.value) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_small,
minimum: def.minSize.value,
type: "set",
inclusive: true,
exact: false,
message: def.minSize.message,
});
status.dirty();
}
}
if (def.maxSize !== null) {
if (ctx.data.size > def.maxSize.value) {
addIssueToContext(ctx, {
code: ZodIssueCode.too_big,
maximum: def.maxSize.value,
type: "set",
inclusive: true,
exact: false,
message: def.maxSize.message,
});
status.dirty();
}
}
const valueType = this._def.valueType;
function finalizeSet(elements) {
const parsedSet = new Set();
for (const element of elements) {
if (element.status === "aborted")
return INVALID;
if (element.status === "dirty")
status.dirty();
parsedSet.add(element.value);
}
return { status: status.value, value: parsedSet };
}
const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
if (ctx.common.async) {
return Promise.all(elements).then((elements) => finalizeSet(elements));
}
else {
return finalizeSet(elements);
}
}
min(minSize, message) {
return new ZodSet({
...this._def,
minSize: { value: minSize, message: errorUtil.toString(message) },
});
}
max(maxSize, message) {
return new ZodSet({
...this._def,
maxSize: { value: maxSize, message: errorUtil.toString(message) },
});
}
size(size, message) {
return this.min(size, message).max(size, message);
}
nonempty(message) {
return this.min(1, message);
}
}
ZodSet.create = (valueType, params) => {
return new ZodSet({
valueType,
minSize: null,
maxSize: null,
typeName: ZodFirstPartyTypeKind.ZodSet,
...processCreateParams(params),
});
};
class ZodFunction extends ZodType {
constructor() {
super(...arguments);
this.validate = this.implement;
}
_parse(input) {
const { ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.function) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.function,
received: ctx.parsedType,
});
return INVALID;
}
function makeArgsIssue(args, error) {
return makeIssue({
data: args,
path: ctx.path,
errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), errorMap].filter((x) => !!x),
issueData: {
code: ZodIssueCode.invalid_arguments,
argumentsError: error,
},
});
}
function makeReturnsIssue(returns, error) {
return makeIssue({
data: returns,
path: ctx.path,
errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), errorMap].filter((x) => !!x),
issueData: {
code: ZodIssueCode.invalid_return_type,
returnTypeError: error,
},
});
}
const params = { errorMap: ctx.common.contextualErrorMap };
const fn = ctx.data;
if (this._def.returns instanceof ZodPromise) {
const me = this;
return OK(async function (...args) {
const error = new ZodError([]);
const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {
error.addIssue(makeArgsIssue(args, e));
throw error;
});
const result = await Reflect.apply(fn, this, parsedArgs);
const parsedReturns = await me._def.returns._def.type
.parseAsync(result, params)
.catch((e) => {
error.addIssue(makeReturnsIssue(result, e));
throw error;
});
return parsedReturns;
});
}
else {
const me = this;
return OK(function (...args) {
const parsedArgs = me._def.args.safeParse(args, params);
if (!parsedArgs.success) {
throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
}
const result = Reflect.apply(fn, this, parsedArgs.data);
const parsedReturns = me._def.returns.safeParse(result, params);
if (!parsedReturns.success) {
throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
}
return parsedReturns.data;
});
}
}
parameters() {
return this._def.args;
}
returnType() {
return this._def.returns;
}
args(...items) {
return new ZodFunction({
...this._def,
args: ZodTuple.create(items).rest(ZodUnknown.create()),
});
}
returns(returnType) {
return new ZodFunction({
...this._def,
returns: returnType,
});
}
implement(func) {
const validatedFunc = this.parse(func);
return validatedFunc;
}
strictImplement(func) {
const validatedFunc = this.parse(func);
return validatedFunc;
}
static create(args, returns, params) {
return new ZodFunction({
args: (args ? args : ZodTuple.create([]).rest(ZodUnknown.create())),
returns: returns || ZodUnknown.create(),
typeName: ZodFirstPartyTypeKind.ZodFunction,
...processCreateParams(params),
});
}
}
class ZodLazy extends ZodType {
get schema() {
return this._def.getter();
}
_parse(input) {
const { ctx } = this._processInputParams(input);
const lazySchema = this._def.getter();
return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
}
}
ZodLazy.create = (getter, params) => {
return new ZodLazy({
getter: getter,
typeName: ZodFirstPartyTypeKind.ZodLazy,
...processCreateParams(params),
});
};
class ZodLiteral extends ZodType {
_parse(input) {
if (input.data !== this._def.value) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
received: ctx.data,
code: ZodIssueCode.invalid_literal,
expected: this._def.value,
});
return INVALID;
}
return { status: "valid", value: input.data };
}
get value() {
return this._def.value;
}
}
ZodLiteral.create = (value, params) => {
return new ZodLiteral({
value: value,
typeName: ZodFirstPartyTypeKind.ZodLiteral,
...processCreateParams(params),
});
};
function createZodEnum(values, params) {
return new ZodEnum({
values,
typeName: ZodFirstPartyTypeKind.ZodEnum,
...processCreateParams(params),
});
}
class ZodEnum extends ZodType {
_parse(input) {
if (typeof input.data !== "string") {
const ctx = this._getOrReturnCtx(input);
const expectedValues = this._def.values;
addIssueToContext(ctx, {
expected: util.joinValues(expectedValues),
received: ctx.parsedType,
code: ZodIssueCode.invalid_type,
});
return INVALID;
}
if (!this._cache) {
this._cache = new Set(this._def.values);
}
if (!this._cache.has(input.data)) {
const ctx = this._getOrReturnCtx(input);
const expectedValues = this._def.values;
addIssueToContext(ctx, {
received: ctx.data,
code: ZodIssueCode.invalid_enum_value,
options: expectedValues,
});
return INVALID;
}
return OK(input.data);
}
get options() {
return this._def.values;
}
get enum() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
get Values() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
get Enum() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
extract(values, newDef = this._def) {
return ZodEnum.create(values, {
...this._def,
...newDef,
});
}
exclude(values, newDef = this._def) {
return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {
...this._def,
...newDef,
});
}
}
ZodEnum.create = createZodEnum;
class ZodNativeEnum extends ZodType {
_parse(input) {
const nativeEnumValues = util.getValidEnumValues(this._def.values);
const ctx = this._getOrReturnCtx(input);
if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {
const expectedValues = util.objectValues(nativeEnumValues);
addIssueToContext(ctx, {
expected: util.joinValues(expectedValues),
received: ctx.parsedType,
code: ZodIssueCode.invalid_type,
});
return INVALID;
}
if (!this._cache) {
this._cache = new Set(util.getValidEnumValues(this._def.values));
}
if (!this._cache.has(input.data)) {
const expectedValues = util.objectValues(nativeEnumValues);
addIssueToContext(ctx, {
received: ctx.data,
code: ZodIssueCode.invalid_enum_value,
options: expectedValues,
});
return INVALID;
}
return OK(input.data);
}
get enum() {
return this._def.values;
}
}
ZodNativeEnum.create = (values, params) => {
return new ZodNativeEnum({
values: values,
typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
...processCreateParams(params),
});
};
class ZodPromise extends ZodType {
unwrap() {
return this._def.type;
}
_parse(input) {
const { ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.promise,
received: ctx.parsedType,
});
return INVALID;
}
const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);
return OK(promisified.then((data) => {
return this._def.type.parseAsync(data, {
path: ctx.path,
errorMap: ctx.common.contextualErrorMap,
});
}));
}
}
ZodPromise.create = (schema, params) => {
return new ZodPromise({
type: schema,
typeName: ZodFirstPartyTypeKind.ZodPromise,
...processCreateParams(params),
});
};
class ZodEffects extends ZodType {
innerType() {
return this._def.schema;
}
sourceType() {
return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects
? this._def.schema.sourceType()
: this._def.schema;
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
const effect = this._def.effect || null;
const checkCtx = {
addIssue: (arg) => {
addIssueToContext(ctx, arg);
if (arg.fatal) {
status.abort();
}
else {
status.dirty();
}
},
get path() {
return ctx.path;
},
};
checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
if (effect.type === "preprocess") {
const processed = effect.transform(ctx.data, checkCtx);
if (ctx.common.async) {
return Promise.resolve(processed).then(async (processed) => {
if (status.value === "aborted")
return INVALID;
const result = await this._def.schema._parseAsync({
data: processed,
path: ctx.path,
parent: ctx,
});
if (result.status === "aborted")
return INVALID;
if (result.status === "dirty")
return DIRTY(result.value);
if (status.value === "dirty")
return DIRTY(result.value);
return result;
});
}
else {
if (status.value === "aborted")
return INVALID;
const result = this._def.schema._parseSync({
data: processed,
path: ctx.path,
parent: ctx,
});
if (result.status === "aborted")
return INVALID;
if (result.status === "dirty")
return DIRTY(result.value);
if (status.value === "dirty")
return DIRTY(result.value);
return result;
}
}
if (effect.type === "refinement") {
const executeRefinement = (acc) => {
const result = effect.refinement(acc, checkCtx);
if (ctx.common.async) {
return Promise.resolve(result);
}
if (result instanceof Promise) {
throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
}
return acc;
};
if (ctx.common.async === false) {
const inner = this._def.schema._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx,
});
if (inner.status === "aborted")
return INVALID;
if (inner.status === "dirty")
status.dirty();
executeRefinement(inner.value);
return { status: status.value, value: inner.value };
}
else {
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
if (inner.status === "aborted")
return INVALID;
if (inner.status === "dirty")
status.dirty();
return executeRefinement(inner.value).then(() => {
return { status: status.value, value: inner.value };
});
});
}
}
if (effect.type === "transform") {
if (ctx.common.async === false) {
const base = this._def.schema._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx,
});
if (!isValid(base))
return INVALID;
const result = effect.transform(base.value, checkCtx);
if (result instanceof Promise) {
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
}
return { status: status.value, value: result };
}
else {
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
if (!isValid(base))
return INVALID;
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
status: status.value,
value: result,
}));
});
}
}
util.assertNever(effect);
}
}
ZodEffects.create = (schema, effect, params) => {
return new ZodEffects({
schema,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect,
...processCreateParams(params),
});
};
ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
return new ZodEffects({
schema,
effect: { type: "preprocess", transform: preprocess },
typeName: ZodFirstPartyTypeKind.ZodEffects,
...processCreateParams(params),
});
};
class ZodOptional extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType === ZodParsedType.undefined) {
return OK(undefined);
}
return this._def.innerType._parse(input);
}
unwrap() {
return this._def.innerType;
}
}
ZodOptional.create = (type, params) => {
return new ZodOptional({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodOptional,
...processCreateParams(params),
});
};
class ZodNullable extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType === ZodParsedType.null) {
return OK(null);
}
return this._def.innerType._parse(input);
}
unwrap() {
return this._def.innerType;
}
}
ZodNullable.create = (type, params) => {
return new ZodNullable({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodNullable,
...processCreateParams(params),
});
};
class ZodDefault extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
let data = ctx.data;
if (ctx.parsedType === ZodParsedType.undefined) {
data = this._def.defaultValue();
}
return this._def.innerType._parse({
data,
path: ctx.path,
parent: ctx,
});
}
removeDefault() {
return this._def.innerType;
}
}
ZodDefault.create = (type, params) => {
return new ZodDefault({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodDefault,
defaultValue: typeof params.default === "function" ? params.default : () => params.default,
...processCreateParams(params),
});
};
class ZodCatch extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
const newCtx = {
...ctx,
common: {
...ctx.common,
issues: [],
},
};
const result = this._def.innerType._parse({
data: newCtx.data,
path: newCtx.path,
parent: {
...newCtx,
},
});
if (isAsync(result)) {
return result.then((result) => {
return {
status: "valid",
value: result.status === "valid"
? result.value
: this._def.catchValue({
get error() {
return new ZodError(newCtx.common.issues);
},
input: newCtx.data,
}),
};
});
}
else {
return {
status: "valid",
value: result.status === "valid"
? result.value
: this._def.catchValue({
get error() {
return new ZodError(newCtx.common.issues);
},
input: newCtx.data,
}),
};
}
}
removeCatch() {
return this._def.innerType;
}
}
ZodCatch.create = (type, params) => {
return new ZodCatch({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodCatch,
catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
...processCreateParams(params),
});
};
class ZodNaN extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.nan) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.nan,
received: ctx.parsedType,
});
return INVALID;
}
return { status: "valid", value: input.data };
}
}
ZodNaN.create = (params) => {
return new ZodNaN({
typeName: ZodFirstPartyTypeKind.ZodNaN,
...processCreateParams(params),
});
};
const BRAND = Symbol("zod_brand");
class ZodBranded extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
const data = ctx.data;
return this._def.type._parse({
data,
path: ctx.path,
parent: ctx,
});
}
unwrap() {
return this._def.type;
}
}
class ZodPipeline extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.common.async) {
const handleAsync = async () => {
const inResult = await this._def.in._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx,
});
if (inResult.status === "aborted")
return INVALID;
if (inResult.status === "dirty") {
status.dirty();
return DIRTY(inResult.value);
}
else {
return this._def.out._parseAsync({
data: inResult.value,
path: ctx.path,
parent: ctx,
});
}
};
return handleAsync();
}
else {
const inResult = this._def.in._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx,
});
if (inResult.status === "aborted")
return INVALID;
if (inResult.status === "dirty") {
status.dirty();
return {
status: "dirty",
value: inResult.value,
};
}
else {
return this._def.out._parseSync({
data: inResult.value,
path: ctx.path,
parent: ctx,
});
}
}
}
static create(a, b) {
return new ZodPipeline({
in: a,
out: b,
typeName: ZodFirstPartyTypeKind.ZodPipeline,
});
}
}
class ZodReadonly extends ZodType {
_parse(input) {
const result = this._def.innerType._parse(input);
const freeze = (data) => {
if (isValid(data)) {
data.value = Object.freeze(data.value);
}
return data;
};
return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
}
unwrap() {
return this._def.innerType;
}
}
ZodReadonly.create = (type, params) => {
return new ZodReadonly({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodReadonly,
...processCreateParams(params),
});
};
function cleanParams(params, data) {
const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;
const p2 = typeof p === "string" ? { message: p } : p;
return p2;
}
function custom(check, _params = {},
fatal) {
if (check)
return ZodAny.create().superRefine((data, ctx) => {
const r = check(data);
if (r instanceof Promise) {
return r.then((r) => {
if (!r) {
const params = cleanParams(_params, data);
const _fatal = params.fatal ?? fatal ?? true;
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
}
});
}
if (!r) {
const params = cleanParams(_params, data);
const _fatal = params.fatal ?? fatal ?? true;
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
}
return;
});
return ZodAny.create();
}
const late = {
object: ZodObject.lazycreate,
};
var ZodFirstPartyTypeKind;
(function (ZodFirstPartyTypeKind) {
ZodFirstPartyTypeKind["ZodString"] = "ZodString";
ZodFirstPartyTypeKind["ZodNumber"] = "ZodNumber";
ZodFirstPartyTypeKind["ZodNaN"] = "ZodNaN";
ZodFirstPartyTypeKind["ZodBigInt"] = "ZodBigInt";
ZodFirstPartyTypeKind["ZodBoolean"] = "ZodBoolean";
ZodFirstPartyTypeKind["ZodDate"] = "ZodDate";
ZodFirstPartyTypeKind["ZodSymbol"] = "ZodSymbol";
ZodFirstPartyTypeKind["ZodUndefined"] = "ZodUndefined";
ZodFirstPartyTypeKind["ZodNull"] = "ZodNull";
ZodFirstPartyTypeKind["ZodAny"] = "ZodAny";
ZodFirstPartyTypeKind["ZodUnknown"] = "ZodUnknown";
ZodFirstPartyTypeKind["ZodNever"] = "ZodNever";
ZodFirstPartyTypeKind["ZodVoid"] = "ZodVoid";
ZodFirstPartyTypeKind["ZodArray"] = "ZodArray";
ZodFirstPartyTypeKind["ZodObject"] = "ZodObject";
ZodFirstPartyTypeKind["ZodUnion"] = "ZodUnion";
ZodFirstPartyTypeKind["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
ZodFirstPartyTypeKind["ZodIntersection"] = "ZodIntersection";
ZodFirstPartyTypeKind["ZodTuple"] = "ZodTuple";
ZodFirstPartyTypeKind["ZodRecord"] = "ZodRecord";
ZodFirstPartyTypeKind["ZodMap"] = "ZodMap";
ZodFirstPartyTypeKind["ZodSet"] = "ZodSet";
ZodFirstPartyTypeKind["ZodFunction"] = "ZodFunction";
ZodFirstPartyTypeKind["ZodLazy"] = "ZodLazy";
ZodFirstPartyTypeKind["ZodLiteral"] = "ZodLiteral";
ZodFirstPartyTypeKind["ZodEnum"] = "ZodEnum";
ZodFirstPartyTypeKind["ZodEffects"] = "ZodEffects";
ZodFirstPartyTypeKind["ZodNativeEnum"] = "ZodNativeEnum";
ZodFirstPartyTypeKind["ZodOptional"] = "ZodOptional";
ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable";
ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault";
ZodFirstPartyTypeKind["ZodCatch"] = "ZodCatch";
ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise";
ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded";
ZodFirstPartyTypeKind["ZodPipeline"] = "ZodPipeline";
ZodFirstPartyTypeKind["ZodReadonly"] = "ZodReadonly";
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
const instanceOfType = (
cls, params = {
message: `Input not instance of ${cls.name}`,
}) => custom((data) => data instanceof cls, params);
const stringType = ZodString.create;
const numberType = ZodNumber.create;
const nanType = ZodNaN.create;
const bigIntType = ZodBigInt.create;
const booleanType = ZodBoolean.create;
const dateType = ZodDate.create;
const symbolType = ZodSymbol.create;
const undefinedType = ZodUndefined.create;
const nullType = ZodNull.create;
const anyType = ZodAny.create;
const unknownType = ZodUnknown.create;
const neverType = ZodNever.create;
const voidType = ZodVoid.create;
const arrayType = ZodArray.create;
const objectType = ZodObject.create;
const strictObjectType = ZodObject.strictCreate;
const unionType = ZodUnion.create;
const discriminatedUnionType = ZodDiscriminatedUnion.create;
const intersectionType = ZodIntersection.create;
const tupleType = ZodTuple.create;
const recordType = ZodRecord.create;
const mapType = ZodMap.create;
const setType = ZodSet.create;
const functionType = ZodFunction.create;
const lazyType = ZodLazy.create;
const literalType = ZodLiteral.create;
const enumType = ZodEnum.create;
const nativeEnumType = ZodNativeEnum.create;
const promiseType = ZodPromise.create;
const effectsType = ZodEffects.create;
const optionalType = ZodOptional.create;
const nullableType = ZodNullable.create;
const preprocessType = ZodEffects.createWithPreprocess;
const pipelineType = ZodPipeline.create;
const ostring = () => stringType().optional();
const onumber = () => numberType().optional();
const oboolean = () => booleanType().optional();
const coerce = {
string: ((arg) => ZodString.create({ ...arg, coerce: true })),
number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
boolean: ((arg) => ZodBoolean.create({
...arg,
coerce: true,
})),
bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
date: ((arg) => ZodDate.create({ ...arg, coerce: true })),
};
const NEVER = INVALID;
var z = /*#__PURE__*/Object.freeze({
__proto__: null,
BRAND: BRAND,
DIRTY: DIRTY,
EMPTY_PATH: EMPTY_PATH,
INVALID: INVALID,
NEVER: NEVER,
OK: OK,
ParseStatus: ParseStatus,
Schema: ZodType,
ZodAny: ZodAny,
ZodArray: ZodArray,
ZodBigInt: ZodBigInt,
ZodBoolean: ZodBoolean,
ZodBranded: ZodBranded,
ZodCatch: ZodCatch,
ZodDate: ZodDate,
ZodDefault: ZodDefault,
ZodDiscriminatedUnion: ZodDiscriminatedUnion,
ZodEffects: ZodEffects,
ZodEnum: ZodEnum,
ZodError: ZodError,
get ZodFirstPartyTypeKind () { return ZodFirstPartyTypeKind; },
ZodFunction: ZodFunction,
ZodIntersection: ZodIntersection,
ZodIssueCode: ZodIssueCode,
ZodLazy: ZodLazy,
ZodLiteral: ZodLiteral,
ZodMap: ZodMap,
ZodNaN: ZodNaN,
ZodNativeEnum: ZodNativeEnum,
ZodNever: ZodNever,
ZodNull: ZodNull,
ZodNullable: ZodNullable,
ZodNumber: ZodNumber,
ZodObject: ZodObject,
ZodOptional: ZodOptional,
ZodParsedType: ZodParsedType,
ZodPipeline: ZodPipeline,
ZodPromise: ZodPromise,
ZodReadonly: ZodReadonly,
ZodRecord: ZodRecord,
ZodSchema: ZodType,
ZodSet: ZodSet,
ZodString: ZodString,
ZodSymbol: ZodSymbol,
ZodTransformer: ZodEffects,
ZodTuple: ZodTuple,
ZodType: ZodType,
ZodUndefined: ZodUndefined,
ZodUnion: ZodUnion,
ZodUnknown: ZodUnknown,
ZodVoid: ZodVoid,
addIssueToContext: addIssueToContext,
any: anyType,
array: arrayType,
bigint: bigIntType,
boolean: booleanType,
coerce: coerce,
custom: custom,
date: dateType,
datetimeRegex: datetimeRegex,
defaultErrorMap: errorMap,
discriminatedUnion: discriminatedUnionType,
effect: effectsType,
enum: enumType,
function: functionType,
getErrorMap: getErrorMap,
getParsedType: getParsedType,
instanceof: instanceOfType,
intersection: intersectionType,
isAborted: isAborted,
isAsync: isAsync,
isDirty: isDirty,
isValid: isValid,
late: late,
lazy: lazyType,
literal: literalType,
makeIssue: makeIssue,
map: mapType,
nan: nanType,
nativeEnum: nativeEnumType,
never: neverType,
null: nullType,
nullable: nullableType,
number: numberType,
object: objectType,
get objectUtil () { return objectUtil; },
oboolean: oboolean,
onumber: onumber,
optional: optionalType,
ostring: ostring,
pipeline: pipelineType,
preprocess: preprocessType,
promise: promiseType,
quotelessJson: quotelessJson,
record: recordType,
set: setType,
setErrorMap: setErrorMap,
strictObject: strictObjectType,
string: stringType,
symbol: symbolType,
transformer: effectsType,
tuple: tupleType,
undefined: undefinedType,
union: unionType,
unknown: unknownType,
get util () { return util; },
void: voidType
});
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var Bluetooth$1;
(function (Bluetooth) {
Bluetooth.BluetoothUuidSchema = z.lazy(() => z.string());
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.BluetoothManufacturerDataSchema = z.lazy(() => z.object({
key: z.number().int().nonnegative(),
data: z.string(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.CharacteristicPropertiesSchema = z.lazy(() => z.object({
broadcast: z.boolean().optional(),
read: z.boolean().optional(),
writeWithoutResponse: z.boolean().optional(),
write: z.boolean().optional(),
notify: z.boolean().optional(),
indicate: z.boolean().optional(),
authenticatedSignedWrites: z.boolean().optional(),
extendedProperties: z.boolean().optional(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.RequestDeviceSchema = z.lazy(() => z.string());
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.RequestDeviceInfoSchema = z.lazy(() => z.object({
id: Bluetooth.RequestDeviceSchema,
name: z.union([z.string(), z.null()]),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.RequestDevicePromptSchema = z.lazy(() => z.string());
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.ScanRecordSchema = z.lazy(() => z.object({
name: z.string().optional(),
uuids: z.array(Bluetooth.BluetoothUuidSchema).optional(),
appearance: z.number().optional(),
manufacturerData: z
.array(Bluetooth.BluetoothManufacturerDataSchema)
.optional(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
z.lazy(() => z.union([
Bluetooth$1.HandleRequestDevicePromptSchema,
Bluetooth$1.SimulateAdapterSchema,
Bluetooth$1.DisableSimulationSchema,
Bluetooth$1.SimulatePreconnectedPeripheralSchema,
Bluetooth$1.SimulateAdvertisementSchema,
Bluetooth$1.SimulateGattConnectionResponseSchema,
Bluetooth$1.SimulateGattDisconnectionSchema,
Bluetooth$1.SimulateServiceSchema,
Bluetooth$1.SimulateCharacteristicSchema,
Bluetooth$1.SimulateCharacteristicResponseSchema,
Bluetooth$1.SimulateDescriptorSchema,
Bluetooth$1.SimulateDescriptorResponseSchema,
z.object({}),
]));
(function (Bluetooth) {
Bluetooth.HandleRequestDevicePromptSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.handleRequestDevicePrompt'),
params: Bluetooth.HandleRequestDevicePromptParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.HandleRequestDevicePromptParametersSchema = z.lazy(() => z
.object({
context: z.string(),
prompt: Bluetooth.RequestDevicePromptSchema,
})
.and(z.union([
Bluetooth.HandleRequestDevicePromptAcceptParametersSchema,
Bluetooth.HandleRequestDevicePromptCancelParametersSchema,
])));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.HandleRequestDevicePromptAcceptParametersSchema = z.lazy(() => z.object({
accept: z.literal(true),
device: Bluetooth.RequestDeviceSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.HandleRequestDevicePromptCancelParametersSchema = z.lazy(() => z.object({
accept: z.literal(false),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateAdapterSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateAdapter'),
params: Bluetooth.SimulateAdapterParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateAdapterParametersSchema = z.lazy(() => z.object({
context: z.string(),
leSupported: z.boolean().optional(),
state: z.enum(['absent', 'powered-off', 'powered-on']),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.DisableSimulationSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.disableSimulation'),
params: Bluetooth.DisableSimulationParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.DisableSimulationParametersSchema = z.lazy(() => z.object({
context: z.string(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulatePreconnectedPeripheralSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulatePreconnectedPeripheral'),
params: Bluetooth.SimulatePreconnectedPeripheralParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulatePreconnectedPeripheralParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
name: z.string(),
manufacturerData: z.array(Bluetooth.BluetoothManufacturerDataSchema),
knownServiceUuids: z.array(Bluetooth.BluetoothUuidSchema),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateAdvertisementSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateAdvertisement'),
params: Bluetooth.SimulateAdvertisementParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateAdvertisementParametersSchema = z.lazy(() => z.object({
context: z.string(),
scanEntry: Bluetooth.SimulateAdvertisementScanEntryParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateAdvertisementScanEntryParametersSchema = z.lazy(() => z.object({
deviceAddress: z.string(),
rssi: z.number(),
scanRecord: Bluetooth.ScanRecordSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateGattConnectionResponseSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateGattConnectionResponse'),
params: Bluetooth.SimulateGattConnectionResponseParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateGattConnectionResponseParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
code: z.number().int().nonnegative(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateGattDisconnectionSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateGattDisconnection'),
params: Bluetooth.SimulateGattDisconnectionParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateGattDisconnectionParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateServiceSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateService'),
params: Bluetooth.SimulateServiceParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateServiceParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
uuid: Bluetooth.BluetoothUuidSchema,
type: z.enum(['add', 'remove']),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateCharacteristicSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateCharacteristic'),
params: Bluetooth.SimulateCharacteristicParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateCharacteristicParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
serviceUuid: Bluetooth.BluetoothUuidSchema,
characteristicUuid: Bluetooth.BluetoothUuidSchema,
characteristicProperties: Bluetooth.CharacteristicPropertiesSchema.optional(),
type: z.enum(['add', 'remove']),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateCharacteristicResponseSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateCharacteristicResponse'),
params: Bluetooth.SimulateCharacteristicResponseParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateCharacteristicResponseParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
serviceUuid: Bluetooth.BluetoothUuidSchema,
characteristicUuid: Bluetooth.BluetoothUuidSchema,
type: z.enum([
'read',
'write',
'subscribe-to-notifications',
'unsubscribe-from-notifications',
]),
code: z.number().int().nonnegative(),
data: z.array(z.number().int().nonnegative()).optional(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateDescriptorSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateDescriptor'),
params: Bluetooth.SimulateDescriptorParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateDescriptorParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
serviceUuid: Bluetooth.BluetoothUuidSchema,
characteristicUuid: Bluetooth.BluetoothUuidSchema,
descriptorUuid: Bluetooth.BluetoothUuidSchema,
type: z.enum(['add', 'remove']),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateDescriptorResponseSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.simulateDescriptorResponse'),
params: Bluetooth.SimulateDescriptorResponseParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.SimulateDescriptorResponseParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
serviceUuid: Bluetooth.BluetoothUuidSchema,
characteristicUuid: Bluetooth.BluetoothUuidSchema,
descriptorUuid: Bluetooth.BluetoothUuidSchema,
type: z.enum(['read', 'write']),
code: z.number().int().nonnegative(),
data: z.array(z.number().int().nonnegative()).optional(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
z.lazy(() => z.union([
Bluetooth$1.RequestDevicePromptUpdatedSchema,
Bluetooth$1.GattConnectionAttemptedSchema,
]));
(function (Bluetooth) {
Bluetooth.RequestDevicePromptUpdatedSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.requestDevicePromptUpdated'),
params: Bluetooth.RequestDevicePromptUpdatedParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.RequestDevicePromptUpdatedParametersSchema = z.lazy(() => z.object({
context: z.string(),
prompt: Bluetooth.RequestDevicePromptSchema,
devices: z.array(Bluetooth.RequestDeviceInfoSchema),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.GattConnectionAttemptedSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.gattConnectionAttempted'),
params: Bluetooth.GattConnectionAttemptedParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.GattConnectionAttemptedParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.CharacteristicEventGeneratedSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.characteristicEventGenerated'),
params: Bluetooth.CharacteristicEventGeneratedParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.CharacteristicEventGeneratedParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
serviceUuid: Bluetooth.BluetoothUuidSchema,
characteristicUuid: Bluetooth.BluetoothUuidSchema,
type: z.enum([
'read',
'write-with-response',
'write-without-response',
'subscribe-to-notifications',
'unsubscribe-from-notifications',
]),
data: z.array(z.number().int().nonnegative()).optional(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.DescriptorEventGeneratedSchema = z.lazy(() => z.object({
method: z.literal('bluetooth.descriptorEventGenerated'),
params: Bluetooth.DescriptorEventGeneratedParametersSchema,
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
(function (Bluetooth) {
Bluetooth.DescriptorEventGeneratedParametersSchema = z.lazy(() => z.object({
context: z.string(),
address: z.string(),
serviceUuid: Bluetooth.BluetoothUuidSchema,
characteristicUuid: Bluetooth.BluetoothUuidSchema,
descriptorUuid: Bluetooth.BluetoothUuidSchema,
type: z.enum(['read', 'write']),
data: z.array(z.number().int().nonnegative()).optional(),
}));
})(Bluetooth$1 || (Bluetooth$1 = {}));
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
z.lazy(() => Permissions$1.SetPermissionSchema);
var Permissions$1;
(function (Permissions) {
Permissions.PermissionDescriptorSchema = z.lazy(() => z.object({
name: z.string(),
}));
})(Permissions$1 || (Permissions$1 = {}));
(function (Permissions) {
Permissions.PermissionStateSchema = z.lazy(() => z.enum(['granted', 'denied', 'prompt']));
})(Permissions$1 || (Permissions$1 = {}));
(function (Permissions) {
Permissions.SetPermissionSchema = z.lazy(() => z.object({
method: z.literal('permissions.setPermission'),
params: Permissions.SetPermissionParametersSchema,
}));
})(Permissions$1 || (Permissions$1 = {}));
(function (Permissions) {
Permissions.SetPermissionParametersSchema = z.lazy(() => z.object({
descriptor: Permissions.PermissionDescriptorSchema,
state: Permissions.PermissionStateSchema,
origin: z.string(),
userContext: z.string().optional(),
}));
})(Permissions$1 || (Permissions$1 = {}));
/**
* Copyright 2024 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const EventSchema = z.lazy(() => z
.object({
type: z.literal('event'),
})
.and(EventDataSchema)
.and(ExtensibleSchema));
z.lazy(() => z
.object({
id: JsUintSchema,
})
.and(CommandDataSchema)
.and(ExtensibleSchema));
const CommandResponseSchema = z.lazy(() => z
.object({
type: z.literal('success'),
id: JsUintSchema,
result: ResultDataSchema,
})
.and(ExtensibleSchema));
const EventDataSchema = z.lazy(() => z.union([
BrowsingContextEventSchema,
InputEventSchema,
LogEventSchema,
NetworkEventSchema,
ScriptEventSchema,
]));
const CommandDataSchema = z.lazy(() => z.union([
BrowserCommandSchema,
BrowsingContextCommandSchema,
EmulationCommandSchema,
InputCommandSchema,
NetworkCommandSchema,
ScriptCommandSchema,
SessionCommandSchema,
StorageCommandSchema,
WebExtensionCommandSchema,
]));
const ResultDataSchema = z.lazy(() => z.union([
BrowsingContextResultSchema,
EmptyResultSchema,
NetworkResultSchema,
ScriptResultSchema,
SessionResultSchema,
StorageResultSchema,
WebExtensionResultSchema,
]));
const EmptyParamsSchema = z.lazy(() => ExtensibleSchema);
z.lazy(() => z.union([CommandResponseSchema, ErrorResponseSchema, EventSchema]));
const ErrorResponseSchema = z.lazy(() => z
.object({
type: z.literal('error'),
id: z.union([JsUintSchema, z.null()]),
error: ErrorCodeSchema,
message: z.string(),
stacktrace: z.string().optional(),
})
.and(ExtensibleSchema));
const EmptyResultSchema = z.lazy(() => ExtensibleSchema);
const ExtensibleSchema = z.lazy(() => z.record(z.string(), z.any()));
const JsIntSchema = z
.number()
.int()
.gte(-9007199254740991)
.lte(9007199254740991);
const JsUintSchema = z
.number()
.int()
.nonnegative()
.gte(0)
.lte(9007199254740991);
const ErrorCodeSchema = z.lazy(() => z.enum([
'invalid argument',
'invalid selector',
'invalid session id',
'invalid web extension',
'move target out of bounds',
'no such alert',
'no such network collector',
'no such element',
'no such frame',
'no such handle',
'no such history entry',
'no such intercept',
'no such network data',
'no such node',
'no such request',
'no such script',
'no such storage partition',
'no such user context',
'no such web extension',
'session not created',
'unable to capture screen',
'unable to close browser',
'unable to set cookie',
'unable to set file input',
'unavailable network data',
'underspecified storage partition',
'unknown command',
'unknown error',
'unsupported operation',
]));
const SessionCommandSchema = z.lazy(() => z.union([
Session$1.EndSchema,
Session$1.NewSchema,
Session$1.StatusSchema,
Session$1.SubscribeSchema,
Session$1.UnsubscribeSchema,
]));
var Session$1;
(function (Session) {
Session.ProxyConfigurationSchema = z.lazy(() => z.union([
Session.AutodetectProxyConfigurationSchema,
Session.DirectProxyConfigurationSchema,
Session.ManualProxyConfigurationSchema,
Session.PacProxyConfigurationSchema,
Session.SystemProxyConfigurationSchema,
]));
})(Session$1 || (Session$1 = {}));
const SessionResultSchema = z.lazy(() => z.union([
Session$1.NewResultSchema,
Session$1.StatusResultSchema,
Session$1.SubscribeResultSchema,
]));
(function (Session) {
Session.CapabilitiesRequestSchema = z.lazy(() => z.object({
alwaysMatch: Session.CapabilityRequestSchema.optional(),
firstMatch: z.array(Session.CapabilityRequestSchema).optional(),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.CapabilityRequestSchema = z.lazy(() => z
.object({
acceptInsecureCerts: z.boolean().optional(),
browserName: z.string().optional(),
browserVersion: z.string().optional(),
platformName: z.string().optional(),
proxy: Session.ProxyConfigurationSchema.optional(),
unhandledPromptBehavior: Session.UserPromptHandlerSchema.optional(),
})
.and(ExtensibleSchema));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.AutodetectProxyConfigurationSchema = z.lazy(() => z
.object({
proxyType: z.literal('autodetect'),
})
.and(ExtensibleSchema));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.DirectProxyConfigurationSchema = z.lazy(() => z
.object({
proxyType: z.literal('direct'),
})
.and(ExtensibleSchema));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.ManualProxyConfigurationSchema = z.lazy(() => z
.object({
proxyType: z.literal('manual'),
httpProxy: z.string().optional(),
sslProxy: z.string().optional(),
})
.and(Session.SocksProxyConfigurationSchema.or(z.object({})))
.and(z.object({
noProxy: z.array(z.string()).optional(),
}))
.and(ExtensibleSchema));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.SocksProxyConfigurationSchema = z.lazy(() => z.object({
socksProxy: z.string(),
socksVersion: z.number().int().nonnegative().gte(0).lte(255),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.PacProxyConfigurationSchema = z.lazy(() => z
.object({
proxyType: z.literal('pac'),
proxyAutoconfigUrl: z.string(),
})
.and(ExtensibleSchema));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.SystemProxyConfigurationSchema = z.lazy(() => z
.object({
proxyType: z.literal('system'),
})
.and(ExtensibleSchema));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.UserPromptHandlerSchema = z.lazy(() => z.object({
alert: Session.UserPromptHandlerTypeSchema.optional(),
beforeUnload: Session.UserPromptHandlerTypeSchema.optional(),
confirm: Session.UserPromptHandlerTypeSchema.optional(),
default: Session.UserPromptHandlerTypeSchema.optional(),
file: Session.UserPromptHandlerTypeSchema.optional(),
prompt: Session.UserPromptHandlerTypeSchema.optional(),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.UserPromptHandlerTypeSchema = z.lazy(() => z.enum(['accept', 'dismiss', 'ignore']));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.SubscriptionSchema = z.lazy(() => z.string());
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.SubscriptionRequestSchema = z.lazy(() => z.object({
events: z.array(z.string()).min(1),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.UnsubscribeByIdRequestSchema = z.lazy(() => z.object({
subscriptions: z.array(Session.SubscriptionSchema).min(1),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.UnsubscribeByAttributesRequestSchema = z.lazy(() => z.object({
events: z.array(z.string()).min(1),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.StatusSchema = z.lazy(() => z.object({
method: z.literal('session.status'),
params: EmptyParamsSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.StatusResultSchema = z.lazy(() => z.object({
ready: z.boolean(),
message: z.string(),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.NewSchema = z.lazy(() => z.object({
method: z.literal('session.new'),
params: Session.NewParametersSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.NewParametersSchema = z.lazy(() => z.object({
capabilities: Session.CapabilitiesRequestSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.NewResultSchema = z.lazy(() => z.object({
sessionId: z.string(),
capabilities: z
.object({
acceptInsecureCerts: z.boolean(),
browserName: z.string(),
browserVersion: z.string(),
platformName: z.string(),
setWindowRect: z.boolean(),
userAgent: z.string(),
proxy: Session.ProxyConfigurationSchema.optional(),
unhandledPromptBehavior: Session.UserPromptHandlerSchema.optional(),
webSocketUrl: z.string().optional(),
})
.and(ExtensibleSchema),
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.EndSchema = z.lazy(() => z.object({
method: z.literal('session.end'),
params: EmptyParamsSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.SubscribeSchema = z.lazy(() => z.object({
method: z.literal('session.subscribe'),
params: Session.SubscriptionRequestSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.SubscribeResultSchema = z.lazy(() => z.object({
subscription: Session.SubscriptionSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.UnsubscribeSchema = z.lazy(() => z.object({
method: z.literal('session.unsubscribe'),
params: Session.UnsubscribeParametersSchema,
}));
})(Session$1 || (Session$1 = {}));
(function (Session) {
Session.UnsubscribeParametersSchema = z.lazy(() => z.union([
Session.UnsubscribeByAttributesRequestSchema,
Session.UnsubscribeByIdRequestSchema,
]));
})(Session$1 || (Session$1 = {}));
const BrowserCommandSchema = z.lazy(() => z.union([
Browser$1.CloseSchema,
Browser$1.CreateUserContextSchema,
Browser$1.GetClientWindowsSchema,
Browser$1.GetUserContextsSchema,
Browser$1.RemoveUserContextSchema,
Browser$1.SetClientWindowStateSchema,
]));
z.lazy(() => z.union([
Browser$1.CreateUserContextResultSchema,
Browser$1.GetUserContextsResultSchema,
]));
var Browser$1;
(function (Browser) {
Browser.ClientWindowSchema = z.lazy(() => z.string());
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.ClientWindowInfoSchema = z.lazy(() => z.object({
active: z.boolean(),
clientWindow: Browser.ClientWindowSchema,
height: JsUintSchema,
state: z.enum(['fullscreen', 'maximized', 'minimized', 'normal']),
width: JsUintSchema,
x: JsIntSchema,
y: JsIntSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.UserContextSchema = z.lazy(() => z.string());
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.UserContextInfoSchema = z.lazy(() => z.object({
userContext: Browser.UserContextSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.CloseSchema = z.lazy(() => z.object({
method: z.literal('browser.close'),
params: EmptyParamsSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.CreateUserContextSchema = z.lazy(() => z.object({
method: z.literal('browser.createUserContext'),
params: Browser.CreateUserContextParametersSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.CreateUserContextParametersSchema = z.lazy(() => z.object({
acceptInsecureCerts: z.boolean().optional(),
proxy: Session$1.ProxyConfigurationSchema.optional(),
unhandledPromptBehavior: Session$1.UserPromptHandlerSchema.optional(),
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.CreateUserContextResultSchema = z.lazy(() => Browser.UserContextInfoSchema);
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.GetClientWindowsSchema = z.lazy(() => z.object({
method: z.literal('browser.getClientWindows'),
params: EmptyParamsSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.GetClientWindowsResultSchema = z.lazy(() => z.object({
clientWindows: z.array(Browser.ClientWindowInfoSchema),
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.GetUserContextsSchema = z.lazy(() => z.object({
method: z.literal('browser.getUserContexts'),
params: EmptyParamsSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.GetUserContextsResultSchema = z.lazy(() => z.object({
userContexts: z.array(Browser.UserContextInfoSchema).min(1),
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.RemoveUserContextSchema = z.lazy(() => z.object({
method: z.literal('browser.removeUserContext'),
params: Browser.RemoveUserContextParametersSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.RemoveUserContextParametersSchema = z.lazy(() => z.object({
userContext: Browser.UserContextSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.SetClientWindowStateSchema = z.lazy(() => z.object({
method: z.literal('browser.setClientWindowState'),
params: Browser.SetClientWindowStateParametersSchema,
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.SetClientWindowStateParametersSchema = z.lazy(() => z
.object({
clientWindow: Browser.ClientWindowSchema,
})
.and(z.union([
Browser.ClientWindowNamedStateSchema,
Browser.ClientWindowRectStateSchema,
])));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.ClientWindowNamedStateSchema = z.lazy(() => z.object({
state: z.enum(['fullscreen', 'maximized', 'minimized']),
}));
})(Browser$1 || (Browser$1 = {}));
(function (Browser) {
Browser.ClientWindowRectStateSchema = z.lazy(() => z.object({
state: z.literal('normal'),
width: JsUintSchema.optional(),
height: JsUintSchema.optional(),
x: JsIntSchema.optional(),
y: JsIntSchema.optional(),
}));
})(Browser$1 || (Browser$1 = {}));
const BrowsingContextCommandSchema = z.lazy(() => z.union([
BrowsingContext$1.ActivateSchema,
BrowsingContext$1.CaptureScreenshotSchema,
BrowsingContext$1.CloseSchema,
BrowsingContext$1.CreateSchema,
BrowsingContext$1.GetTreeSchema,
BrowsingContext$1.HandleUserPromptSchema,
BrowsingContext$1.LocateNodesSchema,
BrowsingContext$1.NavigateSchema,
BrowsingContext$1.PrintSchema,
BrowsingContext$1.ReloadSchema,
BrowsingContext$1.SetViewportSchema,
BrowsingContext$1.TraverseHistorySchema,
]));
const BrowsingContextEventSchema = z.lazy(() => z.union([
BrowsingContext$1.ContextCreatedSchema,
BrowsingContext$1.ContextDestroyedSchema,
BrowsingContext$1.DomContentLoadedSchema,
BrowsingContext$1.DownloadEndSchema,
BrowsingContext$1.DownloadWillBeginSchema,
BrowsingContext$1.FragmentNavigatedSchema,
BrowsingContext$1.HistoryUpdatedSchema,
BrowsingContext$1.LoadSchema,
BrowsingContext$1.NavigationAbortedSchema,
BrowsingContext$1.NavigationCommittedSchema,
BrowsingContext$1.NavigationFailedSchema,
BrowsingContext$1.NavigationStartedSchema,
BrowsingContext$1.UserPromptClosedSchema,
BrowsingContext$1.UserPromptOpenedSchema,
]));
const BrowsingContextResultSchema = z.lazy(() => z.union([
BrowsingContext$1.CaptureScreenshotResultSchema,
BrowsingContext$1.CreateResultSchema,
BrowsingContext$1.GetTreeResultSchema,
BrowsingContext$1.LocateNodesResultSchema,
BrowsingContext$1.NavigateResultSchema,
BrowsingContext$1.PrintResultSchema,
BrowsingContext$1.TraverseHistoryResultSchema,
]));
var BrowsingContext$1;
(function (BrowsingContext) {
BrowsingContext.BrowsingContextSchema = z.lazy(() => z.string());
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.InfoListSchema = z.lazy(() => z.array(BrowsingContext.InfoSchema));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.InfoSchema = z.lazy(() => z.object({
children: z.union([BrowsingContext.InfoListSchema, z.null()]),
clientWindow: Browser$1.ClientWindowSchema,
context: BrowsingContext.BrowsingContextSchema,
originalOpener: z.union([
BrowsingContext.BrowsingContextSchema,
z.null(),
]),
url: z.string(),
userContext: Browser$1.UserContextSchema,
parent: z
.union([BrowsingContext.BrowsingContextSchema, z.null()])
.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.LocatorSchema = z.lazy(() => z.union([
BrowsingContext.AccessibilityLocatorSchema,
BrowsingContext.CssLocatorSchema,
BrowsingContext.ContextLocatorSchema,
BrowsingContext.InnerTextLocatorSchema,
BrowsingContext.XPathLocatorSchema,
]));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.AccessibilityLocatorSchema = z.lazy(() => z.object({
type: z.literal('accessibility'),
value: z.object({
name: z.string().optional(),
role: z.string().optional(),
}),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CssLocatorSchema = z.lazy(() => z.object({
type: z.literal('css'),
value: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ContextLocatorSchema = z.lazy(() => z.object({
type: z.literal('context'),
value: z.object({
context: BrowsingContext.BrowsingContextSchema,
}),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.InnerTextLocatorSchema = z.lazy(() => z.object({
type: z.literal('innerText'),
value: z.string(),
ignoreCase: z.boolean().optional(),
matchType: z.enum(['full', 'partial']).optional(),
maxDepth: JsUintSchema.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.XPathLocatorSchema = z.lazy(() => z.object({
type: z.literal('xpath'),
value: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigationSchema = z.lazy(() => z.string());
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.BaseNavigationInfoSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
navigation: z.union([BrowsingContext.NavigationSchema, z.null()]),
timestamp: JsUintSchema,
url: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigationInfoSchema = z.lazy(() => BrowsingContext.BaseNavigationInfoSchema);
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ReadinessStateSchema = z.lazy(() => z.enum(['none', 'interactive', 'complete']));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.UserPromptTypeSchema = z.lazy(() => z.enum(['alert', 'beforeunload', 'confirm', 'prompt']));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ActivateSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.activate'),
params: BrowsingContext.ActivateParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ActivateParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CaptureScreenshotParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
origin: z.enum(['viewport', 'document']).default('viewport').optional(),
format: BrowsingContext.ImageFormatSchema.optional(),
clip: BrowsingContext.ClipRectangleSchema.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CaptureScreenshotSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.captureScreenshot'),
params: BrowsingContext.CaptureScreenshotParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ImageFormatSchema = z.lazy(() => z.object({
type: z.string(),
quality: z.number().gte(0).lte(1).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ClipRectangleSchema = z.lazy(() => z.union([
BrowsingContext.BoxClipRectangleSchema,
BrowsingContext.ElementClipRectangleSchema,
]));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ElementClipRectangleSchema = z.lazy(() => z.object({
type: z.literal('element'),
element: Script$1.SharedReferenceSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.BoxClipRectangleSchema = z.lazy(() => z.object({
type: z.literal('box'),
x: z.number(),
y: z.number(),
width: z.number(),
height: z.number(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CaptureScreenshotResultSchema = z.lazy(() => z.object({
data: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CloseSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.close'),
params: BrowsingContext.CloseParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CloseParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
promptUnload: z.boolean().default(false).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CreateSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.create'),
params: BrowsingContext.CreateParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CreateTypeSchema = z.lazy(() => z.enum(['tab', 'window']));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CreateParametersSchema = z.lazy(() => z.object({
type: BrowsingContext.CreateTypeSchema,
referenceContext: BrowsingContext.BrowsingContextSchema.optional(),
background: z.boolean().default(false).optional(),
userContext: Browser$1.UserContextSchema.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.CreateResultSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.GetTreeSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.getTree'),
params: BrowsingContext.GetTreeParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.GetTreeParametersSchema = z.lazy(() => z.object({
maxDepth: JsUintSchema.optional(),
root: BrowsingContext.BrowsingContextSchema.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.GetTreeResultSchema = z.lazy(() => z.object({
contexts: BrowsingContext.InfoListSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.HandleUserPromptSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.handleUserPrompt'),
params: BrowsingContext.HandleUserPromptParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.HandleUserPromptParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
accept: z.boolean().optional(),
userText: z.string().optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.LocateNodesParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
locator: BrowsingContext.LocatorSchema,
maxNodeCount: JsUintSchema.gte(1).optional(),
serializationOptions: Script$1.SerializationOptionsSchema.optional(),
startNodes: z.array(Script$1.SharedReferenceSchema).min(1).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.LocateNodesSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.locateNodes'),
params: BrowsingContext.LocateNodesParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.LocateNodesResultSchema = z.lazy(() => z.object({
nodes: z.array(Script$1.NodeRemoteValueSchema),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigateSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.navigate'),
params: BrowsingContext.NavigateParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigateParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
url: z.string(),
wait: BrowsingContext.ReadinessStateSchema.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigateResultSchema = z.lazy(() => z.object({
navigation: z.union([BrowsingContext.NavigationSchema, z.null()]),
url: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.PrintSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.print'),
params: BrowsingContext.PrintParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.PrintParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
background: z.boolean().default(false).optional(),
margin: BrowsingContext.PrintMarginParametersSchema.optional(),
orientation: z
.enum(['portrait', 'landscape'])
.default('portrait')
.optional(),
page: BrowsingContext.PrintPageParametersSchema.optional(),
pageRanges: z.array(z.union([JsUintSchema, z.string()])).optional(),
scale: z.number().gte(0.1).lte(2).default(1).optional(),
shrinkToFit: z.boolean().default(true).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.PrintMarginParametersSchema = z.lazy(() => z.object({
bottom: z.number().gte(0).default(1).optional(),
left: z.number().gte(0).default(1).optional(),
right: z.number().gte(0).default(1).optional(),
top: z.number().gte(0).default(1).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.PrintPageParametersSchema = z.lazy(() => z.object({
height: z.number().gte(0.0352).default(27.94).optional(),
width: z.number().gte(0.0352).default(21.59).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.PrintResultSchema = z.lazy(() => z.object({
data: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ReloadSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.reload'),
params: BrowsingContext.ReloadParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ReloadParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
ignoreCache: z.boolean().optional(),
wait: BrowsingContext.ReadinessStateSchema.optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.SetViewportSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.setViewport'),
params: BrowsingContext.SetViewportParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.SetViewportParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema.optional(),
viewport: z.union([BrowsingContext.ViewportSchema, z.null()]).optional(),
devicePixelRatio: z.union([z.number().gt(0), z.null()]).optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ViewportSchema = z.lazy(() => z.object({
width: JsUintSchema,
height: JsUintSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.TraverseHistorySchema = z.lazy(() => z.object({
method: z.literal('browsingContext.traverseHistory'),
params: BrowsingContext.TraverseHistoryParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.TraverseHistoryParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
delta: JsIntSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.TraverseHistoryResultSchema = z.lazy(() => z.object({}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ContextCreatedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.contextCreated'),
params: BrowsingContext.InfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.ContextDestroyedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.contextDestroyed'),
params: BrowsingContext.InfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigationStartedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.navigationStarted'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.FragmentNavigatedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.fragmentNavigated'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.HistoryUpdatedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.historyUpdated'),
params: BrowsingContext.HistoryUpdatedParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.HistoryUpdatedParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
timestamp: JsUintSchema,
url: z.string(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DomContentLoadedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.domContentLoaded'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.LoadSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.load'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DownloadWillBeginSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.downloadWillBegin'),
params: BrowsingContext.DownloadWillBeginParamsSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DownloadWillBeginParamsSchema = z.lazy(() => z
.object({
suggestedFilename: z.string(),
})
.and(BrowsingContext.BaseNavigationInfoSchema));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DownloadEndSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.downloadEnd'),
params: BrowsingContext.DownloadEndParamsSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DownloadEndParamsSchema = z.lazy(() => z.union([
BrowsingContext.DownloadCanceledParamsSchema,
BrowsingContext.DownloadCompleteParamsSchema,
]));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DownloadCanceledParamsSchema = z.lazy(() => z
.object({
status: z.literal('canceled'),
})
.and(BrowsingContext.BaseNavigationInfoSchema));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.DownloadCompleteParamsSchema = z.lazy(() => z
.object({
status: z.literal('complete'),
filepath: z.union([z.string(), z.null()]),
})
.and(BrowsingContext.BaseNavigationInfoSchema));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigationAbortedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.navigationAborted'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigationCommittedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.navigationCommitted'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.NavigationFailedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.navigationFailed'),
params: BrowsingContext.NavigationInfoSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.UserPromptClosedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.userPromptClosed'),
params: BrowsingContext.UserPromptClosedParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.UserPromptClosedParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
accepted: z.boolean(),
type: BrowsingContext.UserPromptTypeSchema,
userText: z.string().optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.UserPromptOpenedSchema = z.lazy(() => z.object({
method: z.literal('browsingContext.userPromptOpened'),
params: BrowsingContext.UserPromptOpenedParametersSchema,
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
(function (BrowsingContext) {
BrowsingContext.UserPromptOpenedParametersSchema = z.lazy(() => z.object({
context: BrowsingContext.BrowsingContextSchema,
handler: Session$1.UserPromptHandlerTypeSchema,
message: z.string(),
type: BrowsingContext.UserPromptTypeSchema,
defaultValue: z.string().optional(),
}));
})(BrowsingContext$1 || (BrowsingContext$1 = {}));
const EmulationCommandSchema = z.lazy(() => z.union([
Emulation$1.SetForcedColorsModeThemeOverrideSchema,
Emulation$1.SetGeolocationOverrideSchema,
Emulation$1.SetLocaleOverrideSchema,
Emulation$1.SetScreenOrientationOverrideSchema,
Emulation$1.SetScriptingEnabledSchema,
Emulation$1.SetTimezoneOverrideSchema,
]));
var Emulation$1;
(function (Emulation) {
Emulation.SetForcedColorsModeThemeOverrideSchema = z.lazy(() => z.object({
method: z.literal('emulation.setForcedColorsModeThemeOverride'),
params: Emulation.SetForcedColorsModeThemeOverrideParametersSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetForcedColorsModeThemeOverrideParametersSchema = z.lazy(() => z.object({
theme: z.union([Emulation.ForcedColorsModeThemeSchema, z.null()]),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.ForcedColorsModeThemeSchema = z.lazy(() => z.enum(['light', 'dark']));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetGeolocationOverrideSchema = z.lazy(() => z.object({
method: z.literal('emulation.setGeolocationOverride'),
params: Emulation.SetGeolocationOverrideParametersSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetGeolocationOverrideParametersSchema = z.lazy(() => z
.union([
z.object({
coordinates: z.union([
Emulation.GeolocationCoordinatesSchema,
z.null(),
]),
}),
z.object({
error: Emulation.GeolocationPositionErrorSchema,
}),
])
.and(z.object({
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
})));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.GeolocationCoordinatesSchema = z.lazy(() => z.object({
latitude: z.number().gte(-90).lte(90),
longitude: z.number().gte(-180).lte(180),
accuracy: z.number().gte(0).default(1).optional(),
altitude: z.union([z.number(), z.null().default(null)]).optional(),
altitudeAccuracy: z
.union([z.number().gte(0), z.null().default(null)])
.optional(),
heading: z
.union([z.number().gt(0).lt(360), z.null().default(null)])
.optional(),
speed: z.union([z.number().gte(0), z.null().default(null)]).optional(),
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.GeolocationPositionErrorSchema = z.lazy(() => z.object({
type: z.literal('positionUnavailable'),
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetLocaleOverrideSchema = z.lazy(() => z.object({
method: z.literal('emulation.setLocaleOverride'),
params: Emulation.SetLocaleOverrideParametersSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetLocaleOverrideParametersSchema = z.lazy(() => z.object({
locale: z.union([z.string(), z.null()]),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetScreenOrientationOverrideSchema = z.lazy(() => z.object({
method: z.literal('emulation.setScreenOrientationOverride'),
params: Emulation.SetScreenOrientationOverrideParametersSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.ScreenOrientationNaturalSchema = z.lazy(() => z.enum(['portrait', 'landscape']));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.ScreenOrientationTypeSchema = z.lazy(() => z.enum([
'portrait-primary',
'portrait-secondary',
'landscape-primary',
'landscape-secondary',
]));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.ScreenOrientationSchema = z.lazy(() => z.object({
natural: Emulation.ScreenOrientationNaturalSchema,
type: Emulation.ScreenOrientationTypeSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetScreenOrientationOverrideParametersSchema = z.lazy(() => z.object({
screenOrientation: z.union([Emulation.ScreenOrientationSchema, z.null()]),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetScriptingEnabledSchema = z.lazy(() => z.object({
method: z.literal('emulation.setScriptingEnabled'),
params: Emulation.SetScriptingEnabledParametersSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetScriptingEnabledParametersSchema = z.lazy(() => z.object({
enabled: z.union([z.literal(false), z.null()]),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetTimezoneOverrideSchema = z.lazy(() => z.object({
method: z.literal('emulation.setTimezoneOverride'),
params: Emulation.SetTimezoneOverrideParametersSchema,
}));
})(Emulation$1 || (Emulation$1 = {}));
(function (Emulation) {
Emulation.SetTimezoneOverrideParametersSchema = z.lazy(() => z.object({
timezone: z.union([z.string(), z.null()]),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Emulation$1 || (Emulation$1 = {}));
const NetworkCommandSchema = z.lazy(() => z.union([
Network$1.AddDataCollectorSchema,
Network$1.AddInterceptSchema,
Network$1.ContinueRequestSchema,
Network$1.ContinueResponseSchema,
Network$1.ContinueWithAuthSchema,
Network$1.DisownDataSchema,
Network$1.FailRequestSchema,
Network$1.GetDataSchema,
Network$1.ProvideResponseSchema,
Network$1.RemoveDataCollectorSchema,
Network$1.RemoveInterceptSchema,
Network$1.SetCacheBehaviorSchema,
Network$1.SetExtraHeadersSchema,
]));
const NetworkEventSchema = z.lazy(() => z.union([
Network$1.AuthRequiredSchema,
Network$1.BeforeRequestSentSchema,
Network$1.FetchErrorSchema,
Network$1.ResponseCompletedSchema,
Network$1.ResponseStartedSchema,
]));
const NetworkResultSchema = z.lazy(() => Network$1.AddInterceptResultSchema);
var Network$1;
(function (Network) {
Network.AuthChallengeSchema = z.lazy(() => z.object({
scheme: z.string(),
realm: z.string(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AuthCredentialsSchema = z.lazy(() => z.object({
type: z.literal('password'),
username: z.string(),
password: z.string(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.BaseParametersSchema = z.lazy(() => z.object({
context: z.union([BrowsingContext$1.BrowsingContextSchema, z.null()]),
isBlocked: z.boolean(),
navigation: z.union([BrowsingContext$1.NavigationSchema, z.null()]),
redirectCount: JsUintSchema,
request: Network.RequestDataSchema,
timestamp: JsUintSchema,
intercepts: z.array(Network.InterceptSchema).min(1).optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.BytesValueSchema = z.lazy(() => z.union([Network.StringValueSchema, Network.Base64ValueSchema]));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.StringValueSchema = z.lazy(() => z.object({
type: z.literal('string'),
value: z.string(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.Base64ValueSchema = z.lazy(() => z.object({
type: z.literal('base64'),
value: z.string(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.CollectorSchema = z.lazy(() => z.string());
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.CollectorTypeSchema = z.literal('blob');
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.SameSiteSchema = z.lazy(() => z.enum(['strict', 'lax', 'none', 'default']));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.CookieSchema = z.lazy(() => z
.object({
name: z.string(),
value: Network.BytesValueSchema,
domain: z.string(),
path: z.string(),
size: JsUintSchema,
httpOnly: z.boolean(),
secure: z.boolean(),
sameSite: Network.SameSiteSchema,
expiry: JsUintSchema.optional(),
})
.and(ExtensibleSchema));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.CookieHeaderSchema = z.lazy(() => z.object({
name: z.string(),
value: Network.BytesValueSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.DataTypeSchema = z.literal('response');
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.FetchTimingInfoSchema = z.lazy(() => z.object({
timeOrigin: z.number(),
requestTime: z.number(),
redirectStart: z.number(),
redirectEnd: z.number(),
fetchStart: z.number(),
dnsStart: z.number(),
dnsEnd: z.number(),
connectStart: z.number(),
connectEnd: z.number(),
tlsStart: z.number(),
requestStart: z.number(),
responseStart: z.number(),
responseEnd: z.number(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.HeaderSchema = z.lazy(() => z.object({
name: z.string(),
value: Network.BytesValueSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.InitiatorSchema = z.lazy(() => z.object({
columnNumber: JsUintSchema.optional(),
lineNumber: JsUintSchema.optional(),
request: Network.RequestSchema.optional(),
stackTrace: Script$1.StackTraceSchema.optional(),
type: z.enum(['parser', 'script', 'preflight', 'other']).optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.InterceptSchema = z.lazy(() => z.string());
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.RequestSchema = z.lazy(() => z.string());
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.RequestDataSchema = z.lazy(() => z.object({
request: Network.RequestSchema,
url: z.string(),
method: z.string(),
headers: z.array(Network.HeaderSchema),
cookies: z.array(Network.CookieSchema),
headersSize: JsUintSchema,
bodySize: z.union([JsUintSchema, z.null()]),
destination: z.string(),
initiatorType: z.union([z.string(), z.null()]),
timings: Network.FetchTimingInfoSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ResponseContentSchema = z.lazy(() => z.object({
size: JsUintSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ResponseDataSchema = z.lazy(() => z.object({
url: z.string(),
protocol: z.string(),
status: JsUintSchema,
statusText: z.string(),
fromCache: z.boolean(),
headers: z.array(Network.HeaderSchema),
mimeType: z.string(),
bytesReceived: JsUintSchema,
headersSize: z.union([JsUintSchema, z.null()]),
bodySize: z.union([JsUintSchema, z.null()]),
content: Network.ResponseContentSchema,
authChallenges: z.array(Network.AuthChallengeSchema).optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.SetCookieHeaderSchema = z.lazy(() => z.object({
name: z.string(),
value: Network.BytesValueSchema,
domain: z.string().optional(),
httpOnly: z.boolean().optional(),
expiry: z.string().optional(),
maxAge: JsIntSchema.optional(),
path: z.string().optional(),
sameSite: Network.SameSiteSchema.optional(),
secure: z.boolean().optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.UrlPatternSchema = z.lazy(() => z.union([Network.UrlPatternPatternSchema, Network.UrlPatternStringSchema]));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.UrlPatternPatternSchema = z.lazy(() => z.object({
type: z.literal('pattern'),
protocol: z.string().optional(),
hostname: z.string().optional(),
port: z.string().optional(),
pathname: z.string().optional(),
search: z.string().optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.UrlPatternStringSchema = z.lazy(() => z.object({
type: z.literal('string'),
pattern: z.string(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AddDataCollectorSchema = z.lazy(() => z.object({
method: z.literal('network.addDataCollector'),
params: Network.AddDataCollectorParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AddDataCollectorParametersSchema = z.lazy(() => z.object({
dataTypes: z.array(Network.DataTypeSchema).min(1),
maxEncodedDataSize: JsUintSchema,
collectorType: Network.CollectorTypeSchema.default('blob').optional(),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AddDataCollectorResultSchema = z.lazy(() => z.object({
collector: Network.CollectorSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AddInterceptParametersSchema = z.lazy(() => z.object({
phases: z.array(Network.InterceptPhaseSchema).min(1),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
urlPatterns: z.array(Network.UrlPatternSchema).optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AddInterceptSchema = z.lazy(() => z.object({
method: z.literal('network.addIntercept'),
params: Network.AddInterceptParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.InterceptPhaseSchema = z.lazy(() => z.enum(['beforeRequestSent', 'responseStarted', 'authRequired']));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.AddInterceptResultSchema = z.lazy(() => z.object({
intercept: Network.InterceptSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueRequestSchema = z.lazy(() => z.object({
method: z.literal('network.continueRequest'),
params: Network.ContinueRequestParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueRequestParametersSchema = z.lazy(() => z.object({
request: Network.RequestSchema,
body: Network.BytesValueSchema.optional(),
cookies: z.array(Network.CookieHeaderSchema).optional(),
headers: z.array(Network.HeaderSchema).optional(),
method: z.string().optional(),
url: z.string().optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueResponseSchema = z.lazy(() => z.object({
method: z.literal('network.continueResponse'),
params: Network.ContinueResponseParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueResponseParametersSchema = z.lazy(() => z.object({
request: Network.RequestSchema,
cookies: z.array(Network.SetCookieHeaderSchema).optional(),
credentials: Network.AuthCredentialsSchema.optional(),
headers: z.array(Network.HeaderSchema).optional(),
reasonPhrase: z.string().optional(),
statusCode: JsUintSchema.optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueWithAuthSchema = z.lazy(() => z.object({
method: z.literal('network.continueWithAuth'),
params: Network.ContinueWithAuthParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueWithAuthParametersSchema = z.lazy(() => z
.object({
request: Network.RequestSchema,
})
.and(z.union([
Network.ContinueWithAuthCredentialsSchema,
Network.ContinueWithAuthNoCredentialsSchema,
])));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueWithAuthCredentialsSchema = z.lazy(() => z.object({
action: z.literal('provideCredentials'),
credentials: Network.AuthCredentialsSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ContinueWithAuthNoCredentialsSchema = z.lazy(() => z.object({
action: z.enum(['default', 'cancel']),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.DisownDataSchema = z.lazy(() => z.object({
method: z.literal('network.disownData'),
params: Network.DisownDataParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.DisownDataParametersSchema = z.lazy(() => z.object({
dataType: Network.DataTypeSchema,
collector: Network.CollectorSchema,
request: Network.RequestSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.FailRequestSchema = z.lazy(() => z.object({
method: z.literal('network.failRequest'),
params: Network.FailRequestParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.FailRequestParametersSchema = z.lazy(() => z.object({
request: Network.RequestSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.GetDataSchema = z.lazy(() => z.object({
method: z.literal('network.getData'),
params: Network.GetDataParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.GetDataParametersSchema = z.lazy(() => z.object({
dataType: Network.DataTypeSchema,
collector: Network.CollectorSchema.optional(),
disown: z.boolean().default(false).optional(),
request: Network.RequestSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.GetDataResultSchema = z.lazy(() => z.object({
bytes: Network.BytesValueSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ProvideResponseSchema = z.lazy(() => z.object({
method: z.literal('network.provideResponse'),
params: Network.ProvideResponseParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ProvideResponseParametersSchema = z.lazy(() => z.object({
request: Network.RequestSchema,
body: Network.BytesValueSchema.optional(),
cookies: z.array(Network.SetCookieHeaderSchema).optional(),
headers: z.array(Network.HeaderSchema).optional(),
reasonPhrase: z.string().optional(),
statusCode: JsUintSchema.optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.RemoveDataCollectorSchema = z.lazy(() => z.object({
method: z.literal('network.removeDataCollector'),
params: Network.RemoveDataCollectorParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.RemoveDataCollectorParametersSchema = z.lazy(() => z.object({
collector: Network.CollectorSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.RemoveInterceptSchema = z.lazy(() => z.object({
method: z.literal('network.removeIntercept'),
params: Network.RemoveInterceptParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.RemoveInterceptParametersSchema = z.lazy(() => z.object({
intercept: Network.InterceptSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.SetCacheBehaviorSchema = z.lazy(() => z.object({
method: z.literal('network.setCacheBehavior'),
params: Network.SetCacheBehaviorParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.SetCacheBehaviorParametersSchema = z.lazy(() => z.object({
cacheBehavior: z.enum(['default', 'bypass']),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.SetExtraHeadersSchema = z.lazy(() => z.object({
method: z.literal('network.setExtraHeaders'),
params: Network.SetExtraHeadersParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.SetExtraHeadersParametersSchema = z.lazy(() => z.object({
headers: z.array(Network.HeaderSchema),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
}));
})(Network$1 || (Network$1 = {}));
const ScriptEventSchema = z.lazy(() => z.union([
Script$1.MessageSchema,
Script$1.RealmCreatedSchema,
Script$1.RealmDestroyedSchema,
]));
(function (Network) {
Network.AuthRequiredParametersSchema = z.lazy(() => Network.BaseParametersSchema.and(z.object({
response: Network.ResponseDataSchema,
})));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.BeforeRequestSentParametersSchema = z.lazy(() => Network.BaseParametersSchema.and(z.object({
initiator: Network.InitiatorSchema.optional(),
})));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.FetchErrorParametersSchema = z.lazy(() => Network.BaseParametersSchema.and(z.object({
errorText: z.string(),
})));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ResponseCompletedParametersSchema = z.lazy(() => Network.BaseParametersSchema.and(z.object({
response: Network.ResponseDataSchema,
})));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ResponseStartedParametersSchema = z.lazy(() => Network.BaseParametersSchema.and(z.object({
response: Network.ResponseDataSchema,
})));
})(Network$1 || (Network$1 = {}));
const ScriptCommandSchema = z.lazy(() => z.union([
Script$1.AddPreloadScriptSchema,
Script$1.CallFunctionSchema,
Script$1.DisownSchema,
Script$1.EvaluateSchema,
Script$1.GetRealmsSchema,
Script$1.RemovePreloadScriptSchema,
]));
const ScriptResultSchema = z.lazy(() => z.union([
Script$1.AddPreloadScriptResultSchema,
Script$1.EvaluateResultSchema,
Script$1.GetRealmsResultSchema,
]));
(function (Network) {
Network.AuthRequiredSchema = z.lazy(() => z.object({
method: z.literal('network.authRequired'),
params: Network.AuthRequiredParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.BeforeRequestSentSchema = z.lazy(() => z.object({
method: z.literal('network.beforeRequestSent'),
params: Network.BeforeRequestSentParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.FetchErrorSchema = z.lazy(() => z.object({
method: z.literal('network.fetchError'),
params: Network.FetchErrorParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ResponseCompletedSchema = z.lazy(() => z.object({
method: z.literal('network.responseCompleted'),
params: Network.ResponseCompletedParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
(function (Network) {
Network.ResponseStartedSchema = z.lazy(() => z.object({
method: z.literal('network.responseStarted'),
params: Network.ResponseStartedParametersSchema,
}));
})(Network$1 || (Network$1 = {}));
var Script$1;
(function (Script) {
Script.ChannelSchema = z.lazy(() => z.string());
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.EvaluateResultSuccessSchema = z.lazy(() => z.object({
type: z.literal('success'),
result: Script.RemoteValueSchema,
realm: Script.RealmSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ExceptionDetailsSchema = z.lazy(() => z.object({
columnNumber: JsUintSchema,
exception: Script.RemoteValueSchema,
lineNumber: JsUintSchema,
stackTrace: Script.StackTraceSchema,
text: z.string(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ChannelValueSchema = z.lazy(() => z.object({
type: z.literal('channel'),
value: Script.ChannelPropertiesSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ChannelPropertiesSchema = z.lazy(() => z.object({
channel: Script.ChannelSchema,
serializationOptions: Script.SerializationOptionsSchema.optional(),
ownership: Script.ResultOwnershipSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.EvaluateResultSchema = z.lazy(() => z.union([
Script.EvaluateResultSuccessSchema,
Script.EvaluateResultExceptionSchema,
]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.EvaluateResultExceptionSchema = z.lazy(() => z.object({
type: z.literal('exception'),
exceptionDetails: Script.ExceptionDetailsSchema,
realm: Script.RealmSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.HandleSchema = z.lazy(() => z.string());
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.InternalIdSchema = z.lazy(() => z.string());
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ListLocalValueSchema = z.lazy(() => z.array(Script.LocalValueSchema));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.LocalValueSchema = z.lazy(() => z.union([
Script.RemoteReferenceSchema,
Script.PrimitiveProtocolValueSchema,
Script.ChannelValueSchema,
Script.ArrayLocalValueSchema,
Script.DateLocalValueSchema,
Script.MapLocalValueSchema,
Script.ObjectLocalValueSchema,
Script.RegExpLocalValueSchema,
Script.SetLocalValueSchema,
]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ArrayLocalValueSchema = z.lazy(() => z.object({
type: z.literal('array'),
value: Script.ListLocalValueSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.DateLocalValueSchema = z.lazy(() => z.object({
type: z.literal('date'),
value: z.string(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.MappingLocalValueSchema = z.lazy(() => z.array(z.tuple([
z.union([Script.LocalValueSchema, z.string()]),
Script.LocalValueSchema,
])));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.MapLocalValueSchema = z.lazy(() => z.object({
type: z.literal('map'),
value: Script.MappingLocalValueSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ObjectLocalValueSchema = z.lazy(() => z.object({
type: z.literal('object'),
value: Script.MappingLocalValueSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RegExpValueSchema = z.lazy(() => z.object({
pattern: z.string(),
flags: z.string().optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RegExpLocalValueSchema = z.lazy(() => z.object({
type: z.literal('regexp'),
value: Script.RegExpValueSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SetLocalValueSchema = z.lazy(() => z.object({
type: z.literal('set'),
value: Script.ListLocalValueSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.PreloadScriptSchema = z.lazy(() => z.string());
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmSchema = z.lazy(() => z.string());
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.PrimitiveProtocolValueSchema = z.lazy(() => z.union([
Script.UndefinedValueSchema,
Script.NullValueSchema,
Script.StringValueSchema,
Script.NumberValueSchema,
Script.BooleanValueSchema,
Script.BigIntValueSchema,
]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.UndefinedValueSchema = z.lazy(() => z.object({
type: z.literal('undefined'),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.NullValueSchema = z.lazy(() => z.object({
type: z.literal('null'),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.StringValueSchema = z.lazy(() => z.object({
type: z.literal('string'),
value: z.string(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SpecialNumberSchema = z.lazy(() => z.enum(['NaN', '-0', 'Infinity', '-Infinity']));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.NumberValueSchema = z.lazy(() => z.object({
type: z.literal('number'),
value: z.union([z.number(), Script.SpecialNumberSchema]),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.BooleanValueSchema = z.lazy(() => z.object({
type: z.literal('boolean'),
value: z.boolean(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.BigIntValueSchema = z.lazy(() => z.object({
type: z.literal('bigint'),
value: z.string(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmInfoSchema = z.lazy(() => z.union([
Script.WindowRealmInfoSchema,
Script.DedicatedWorkerRealmInfoSchema,
Script.SharedWorkerRealmInfoSchema,
Script.ServiceWorkerRealmInfoSchema,
Script.WorkerRealmInfoSchema,
Script.PaintWorkletRealmInfoSchema,
Script.AudioWorkletRealmInfoSchema,
Script.WorkletRealmInfoSchema,
]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.BaseRealmInfoSchema = z.lazy(() => z.object({
realm: Script.RealmSchema,
origin: z.string(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WindowRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('window'),
context: BrowsingContext$1.BrowsingContextSchema,
sandbox: z.string().optional(),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.DedicatedWorkerRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('dedicated-worker'),
owners: z.tuple([Script.RealmSchema]),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SharedWorkerRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('shared-worker'),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ServiceWorkerRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('service-worker'),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WorkerRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('worker'),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.PaintWorkletRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('paint-worklet'),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.AudioWorkletRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('audio-worklet'),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WorkletRealmInfoSchema = z.lazy(() => Script.BaseRealmInfoSchema.and(z.object({
type: z.literal('worklet'),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmTypeSchema = z.lazy(() => z.enum([
'window',
'dedicated-worker',
'shared-worker',
'service-worker',
'worker',
'paint-worklet',
'audio-worklet',
'worklet',
]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ListRemoteValueSchema = z.lazy(() => z.array(Script.RemoteValueSchema));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.MappingRemoteValueSchema = z.lazy(() => z.array(z.tuple([
z.union([Script.RemoteValueSchema, z.string()]),
Script.RemoteValueSchema,
])));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RemoteValueSchema = z.lazy(() => z.union([
Script.PrimitiveProtocolValueSchema,
Script.SymbolRemoteValueSchema,
Script.ArrayRemoteValueSchema,
Script.ObjectRemoteValueSchema,
Script.FunctionRemoteValueSchema,
Script.RegExpRemoteValueSchema,
Script.DateRemoteValueSchema,
Script.MapRemoteValueSchema,
Script.SetRemoteValueSchema,
Script.WeakMapRemoteValueSchema,
Script.WeakSetRemoteValueSchema,
Script.GeneratorRemoteValueSchema,
Script.ErrorRemoteValueSchema,
Script.ProxyRemoteValueSchema,
Script.PromiseRemoteValueSchema,
Script.TypedArrayRemoteValueSchema,
Script.ArrayBufferRemoteValueSchema,
Script.NodeListRemoteValueSchema,
Script.HtmlCollectionRemoteValueSchema,
Script.NodeRemoteValueSchema,
Script.WindowProxyRemoteValueSchema,
]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RemoteReferenceSchema = z.lazy(() => z.union([Script.SharedReferenceSchema, Script.RemoteObjectReferenceSchema]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SharedReferenceSchema = z.lazy(() => z
.object({
sharedId: Script.SharedIdSchema,
handle: Script.HandleSchema.optional(),
})
.and(ExtensibleSchema));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RemoteObjectReferenceSchema = z.lazy(() => z
.object({
handle: Script.HandleSchema,
sharedId: Script.SharedIdSchema.optional(),
})
.and(ExtensibleSchema));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SymbolRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('symbol'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ArrayRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('array'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.ListRemoteValueSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ObjectRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('object'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.MappingRemoteValueSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.FunctionRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('function'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RegExpRemoteValueSchema = z.lazy(() => Script.RegExpLocalValueSchema.and(z.object({
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.DateRemoteValueSchema = z.lazy(() => Script.DateLocalValueSchema.and(z.object({
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
})));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.MapRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('map'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.MappingRemoteValueSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SetRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('set'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.ListRemoteValueSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WeakMapRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('weakmap'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WeakSetRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('weakset'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.GeneratorRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('generator'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ErrorRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('error'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ProxyRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('proxy'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.PromiseRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('promise'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.TypedArrayRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('typedarray'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ArrayBufferRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('arraybuffer'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.NodeListRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('nodelist'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.ListRemoteValueSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.HtmlCollectionRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('htmlcollection'),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.ListRemoteValueSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.NodeRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('node'),
sharedId: Script.SharedIdSchema.optional(),
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
value: Script.NodePropertiesSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.NodePropertiesSchema = z.lazy(() => z.object({
nodeType: JsUintSchema,
childNodeCount: JsUintSchema,
attributes: z.record(z.string(), z.string()).optional(),
children: z.array(Script.NodeRemoteValueSchema).optional(),
localName: z.string().optional(),
mode: z.enum(['open', 'closed']).optional(),
namespaceURI: z.string().optional(),
nodeValue: z.string().optional(),
shadowRoot: z.union([Script.NodeRemoteValueSchema, z.null()]).optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WindowProxyRemoteValueSchema = z.lazy(() => z.object({
type: z.literal('window'),
value: Script.WindowProxyPropertiesSchema,
handle: Script.HandleSchema.optional(),
internalId: Script.InternalIdSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.WindowProxyPropertiesSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ResultOwnershipSchema = z.lazy(() => z.enum(['root', 'none']));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SerializationOptionsSchema = z.lazy(() => z.object({
maxDomDepth: z.union([JsUintSchema, z.null()]).default(0).optional(),
maxObjectDepth: z
.union([JsUintSchema, z.null()])
.default(null)
.optional(),
includeShadowTree: z
.enum(['none', 'open', 'all'])
.default('none')
.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SharedIdSchema = z.lazy(() => z.string());
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.StackFrameSchema = z.lazy(() => z.object({
columnNumber: JsUintSchema,
functionName: z.string(),
lineNumber: JsUintSchema,
url: z.string(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.StackTraceSchema = z.lazy(() => z.object({
callFrames: z.array(Script.StackFrameSchema),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.SourceSchema = z.lazy(() => z.object({
realm: Script.RealmSchema,
context: BrowsingContext$1.BrowsingContextSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmTargetSchema = z.lazy(() => z.object({
realm: Script.RealmSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.ContextTargetSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema,
sandbox: z.string().optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.TargetSchema = z.lazy(() => z.union([Script.ContextTargetSchema, Script.RealmTargetSchema]));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.AddPreloadScriptSchema = z.lazy(() => z.object({
method: z.literal('script.addPreloadScript'),
params: Script.AddPreloadScriptParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.AddPreloadScriptParametersSchema = z.lazy(() => z.object({
functionDeclaration: z.string(),
arguments: z.array(Script.ChannelValueSchema).optional(),
contexts: z
.array(BrowsingContext$1.BrowsingContextSchema)
.min(1)
.optional(),
userContexts: z.array(Browser$1.UserContextSchema).min(1).optional(),
sandbox: z.string().optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.AddPreloadScriptResultSchema = z.lazy(() => z.object({
script: Script.PreloadScriptSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.DisownSchema = z.lazy(() => z.object({
method: z.literal('script.disown'),
params: Script.DisownParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.DisownParametersSchema = z.lazy(() => z.object({
handles: z.array(Script.HandleSchema),
target: Script.TargetSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.CallFunctionParametersSchema = z.lazy(() => z.object({
functionDeclaration: z.string(),
awaitPromise: z.boolean(),
target: Script.TargetSchema,
arguments: z.array(Script.LocalValueSchema).optional(),
resultOwnership: Script.ResultOwnershipSchema.optional(),
serializationOptions: Script.SerializationOptionsSchema.optional(),
this: Script.LocalValueSchema.optional(),
userActivation: z.boolean().default(false).optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.CallFunctionSchema = z.lazy(() => z.object({
method: z.literal('script.callFunction'),
params: Script.CallFunctionParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.EvaluateSchema = z.lazy(() => z.object({
method: z.literal('script.evaluate'),
params: Script.EvaluateParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.EvaluateParametersSchema = z.lazy(() => z.object({
expression: z.string(),
target: Script.TargetSchema,
awaitPromise: z.boolean(),
resultOwnership: Script.ResultOwnershipSchema.optional(),
serializationOptions: Script.SerializationOptionsSchema.optional(),
userActivation: z.boolean().default(false).optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.GetRealmsSchema = z.lazy(() => z.object({
method: z.literal('script.getRealms'),
params: Script.GetRealmsParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.GetRealmsParametersSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema.optional(),
type: Script.RealmTypeSchema.optional(),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.GetRealmsResultSchema = z.lazy(() => z.object({
realms: z.array(Script.RealmInfoSchema),
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RemovePreloadScriptSchema = z.lazy(() => z.object({
method: z.literal('script.removePreloadScript'),
params: Script.RemovePreloadScriptParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RemovePreloadScriptParametersSchema = z.lazy(() => z.object({
script: Script.PreloadScriptSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.MessageParametersSchema = z.lazy(() => z.object({
channel: Script.ChannelSchema,
data: Script.RemoteValueSchema,
source: Script.SourceSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmCreatedSchema = z.lazy(() => z.object({
method: z.literal('script.realmCreated'),
params: Script.RealmInfoSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.MessageSchema = z.lazy(() => z.object({
method: z.literal('script.message'),
params: Script.MessageParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmDestroyedSchema = z.lazy(() => z.object({
method: z.literal('script.realmDestroyed'),
params: Script.RealmDestroyedParametersSchema,
}));
})(Script$1 || (Script$1 = {}));
(function (Script) {
Script.RealmDestroyedParametersSchema = z.lazy(() => z.object({
realm: Script.RealmSchema,
}));
})(Script$1 || (Script$1 = {}));
const StorageCommandSchema = z.lazy(() => z.union([
Storage$1.DeleteCookiesSchema,
Storage$1.GetCookiesSchema,
Storage$1.SetCookieSchema,
]));
const StorageResultSchema = z.lazy(() => z.union([
Storage$1.DeleteCookiesResultSchema,
Storage$1.GetCookiesResultSchema,
Storage$1.SetCookieResultSchema,
]));
var Storage$1;
(function (Storage) {
Storage.PartitionKeySchema = z.lazy(() => z
.object({
userContext: z.string().optional(),
sourceOrigin: z.string().optional(),
})
.and(ExtensibleSchema));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.GetCookiesSchema = z.lazy(() => z.object({
method: z.literal('storage.getCookies'),
params: Storage.GetCookiesParametersSchema,
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.CookieFilterSchema = z.lazy(() => z
.object({
name: z.string().optional(),
value: Network$1.BytesValueSchema.optional(),
domain: z.string().optional(),
path: z.string().optional(),
size: JsUintSchema.optional(),
httpOnly: z.boolean().optional(),
secure: z.boolean().optional(),
sameSite: Network$1.SameSiteSchema.optional(),
expiry: JsUintSchema.optional(),
})
.and(ExtensibleSchema));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.BrowsingContextPartitionDescriptorSchema = z.lazy(() => z.object({
type: z.literal('context'),
context: BrowsingContext$1.BrowsingContextSchema,
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.StorageKeyPartitionDescriptorSchema = z.lazy(() => z
.object({
type: z.literal('storageKey'),
userContext: z.string().optional(),
sourceOrigin: z.string().optional(),
})
.and(ExtensibleSchema));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.PartitionDescriptorSchema = z.lazy(() => z.union([
Storage.BrowsingContextPartitionDescriptorSchema,
Storage.StorageKeyPartitionDescriptorSchema,
]));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.GetCookiesParametersSchema = z.lazy(() => z.object({
filter: Storage.CookieFilterSchema.optional(),
partition: Storage.PartitionDescriptorSchema.optional(),
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.GetCookiesResultSchema = z.lazy(() => z.object({
cookies: z.array(Network$1.CookieSchema),
partitionKey: Storage.PartitionKeySchema,
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.SetCookieSchema = z.lazy(() => z.object({
method: z.literal('storage.setCookie'),
params: Storage.SetCookieParametersSchema,
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.PartialCookieSchema = z.lazy(() => z
.object({
name: z.string(),
value: Network$1.BytesValueSchema,
domain: z.string(),
path: z.string().optional(),
httpOnly: z.boolean().optional(),
secure: z.boolean().optional(),
sameSite: Network$1.SameSiteSchema.optional(),
expiry: JsUintSchema.optional(),
})
.and(ExtensibleSchema));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.SetCookieParametersSchema = z.lazy(() => z.object({
cookie: Storage.PartialCookieSchema,
partition: Storage.PartitionDescriptorSchema.optional(),
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.SetCookieResultSchema = z.lazy(() => z.object({
partitionKey: Storage.PartitionKeySchema,
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.DeleteCookiesSchema = z.lazy(() => z.object({
method: z.literal('storage.deleteCookies'),
params: Storage.DeleteCookiesParametersSchema,
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.DeleteCookiesParametersSchema = z.lazy(() => z.object({
filter: Storage.CookieFilterSchema.optional(),
partition: Storage.PartitionDescriptorSchema.optional(),
}));
})(Storage$1 || (Storage$1 = {}));
(function (Storage) {
Storage.DeleteCookiesResultSchema = z.lazy(() => z.object({
partitionKey: Storage.PartitionKeySchema,
}));
})(Storage$1 || (Storage$1 = {}));
const LogEventSchema = z.lazy(() => Log.EntryAddedSchema);
var Log;
(function (Log) {
Log.LevelSchema = z.lazy(() => z.enum(['debug', 'info', 'warn', 'error']));
})(Log || (Log = {}));
(function (Log) {
Log.EntrySchema = z.lazy(() => z.union([
Log.GenericLogEntrySchema,
Log.ConsoleLogEntrySchema,
Log.JavascriptLogEntrySchema,
]));
})(Log || (Log = {}));
(function (Log) {
Log.BaseLogEntrySchema = z.lazy(() => z.object({
level: Log.LevelSchema,
source: Script$1.SourceSchema,
text: z.union([z.string(), z.null()]),
timestamp: JsUintSchema,
stackTrace: Script$1.StackTraceSchema.optional(),
}));
})(Log || (Log = {}));
(function (Log) {
Log.GenericLogEntrySchema = z.lazy(() => Log.BaseLogEntrySchema.and(z.object({
type: z.string(),
})));
})(Log || (Log = {}));
(function (Log) {
Log.ConsoleLogEntrySchema = z.lazy(() => Log.BaseLogEntrySchema.and(z.object({
type: z.literal('console'),
method: z.string(),
args: z.array(Script$1.RemoteValueSchema),
})));
})(Log || (Log = {}));
(function (Log) {
Log.JavascriptLogEntrySchema = z.lazy(() => Log.BaseLogEntrySchema.and(z.object({
type: z.literal('javascript'),
})));
})(Log || (Log = {}));
(function (Log) {
Log.EntryAddedSchema = z.lazy(() => z.object({
method: z.literal('log.entryAdded'),
params: Log.EntrySchema,
}));
})(Log || (Log = {}));
const InputCommandSchema = z.lazy(() => z.union([
Input$1.PerformActionsSchema,
Input$1.ReleaseActionsSchema,
Input$1.SetFilesSchema,
]));
const InputEventSchema = z.lazy(() => Input$1.FileDialogOpenedSchema);
var Input$1;
(function (Input) {
Input.ElementOriginSchema = z.lazy(() => z.object({
type: z.literal('element'),
element: Script$1.SharedReferenceSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PerformActionsParametersSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema,
actions: z.array(Input.SourceActionsSchema),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.NoneSourceActionsSchema = z.lazy(() => z.object({
type: z.literal('none'),
id: z.string(),
actions: z.array(Input.NoneSourceActionSchema),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.KeySourceActionsSchema = z.lazy(() => z.object({
type: z.literal('key'),
id: z.string(),
actions: z.array(Input.KeySourceActionSchema),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerSourceActionsSchema = z.lazy(() => z.object({
type: z.literal('pointer'),
id: z.string(),
parameters: Input.PointerParametersSchema.optional(),
actions: z.array(Input.PointerSourceActionSchema),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PerformActionsSchema = z.lazy(() => z.object({
method: z.literal('input.performActions'),
params: Input.PerformActionsParametersSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.SourceActionsSchema = z.lazy(() => z.union([
Input.NoneSourceActionsSchema,
Input.KeySourceActionsSchema,
Input.PointerSourceActionsSchema,
Input.WheelSourceActionsSchema,
]));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.NoneSourceActionSchema = z.lazy(() => Input.PauseActionSchema);
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.KeySourceActionSchema = z.lazy(() => z.union([
Input.PauseActionSchema,
Input.KeyDownActionSchema,
Input.KeyUpActionSchema,
]));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerTypeSchema = z.lazy(() => z.enum(['mouse', 'pen', 'touch']));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerParametersSchema = z.lazy(() => z.object({
pointerType: Input.PointerTypeSchema.default('mouse').optional(),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.WheelSourceActionsSchema = z.lazy(() => z.object({
type: z.literal('wheel'),
id: z.string(),
actions: z.array(Input.WheelSourceActionSchema),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerSourceActionSchema = z.lazy(() => z.union([
Input.PauseActionSchema,
Input.PointerDownActionSchema,
Input.PointerUpActionSchema,
Input.PointerMoveActionSchema,
]));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.WheelSourceActionSchema = z.lazy(() => z.union([Input.PauseActionSchema, Input.WheelScrollActionSchema]));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PauseActionSchema = z.lazy(() => z.object({
type: z.literal('pause'),
duration: JsUintSchema.optional(),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.KeyDownActionSchema = z.lazy(() => z.object({
type: z.literal('keyDown'),
value: z.string(),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.KeyUpActionSchema = z.lazy(() => z.object({
type: z.literal('keyUp'),
value: z.string(),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerUpActionSchema = z.lazy(() => z.object({
type: z.literal('pointerUp'),
button: JsUintSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerDownActionSchema = z.lazy(() => z
.object({
type: z.literal('pointerDown'),
button: JsUintSchema,
})
.and(Input.PointerCommonPropertiesSchema));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerMoveActionSchema = z.lazy(() => z
.object({
type: z.literal('pointerMove'),
x: z.number(),
y: z.number(),
duration: JsUintSchema.optional(),
origin: Input.OriginSchema.optional(),
})
.and(Input.PointerCommonPropertiesSchema));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.WheelScrollActionSchema = z.lazy(() => z.object({
type: z.literal('scroll'),
x: JsIntSchema,
y: JsIntSchema,
deltaX: JsIntSchema,
deltaY: JsIntSchema,
duration: JsUintSchema.optional(),
origin: Input.OriginSchema.default('viewport').optional(),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.PointerCommonPropertiesSchema = z.lazy(() => z.object({
width: JsUintSchema.default(1).optional(),
height: JsUintSchema.default(1).optional(),
pressure: z.number().default(0).optional(),
tangentialPressure: z.number().default(0).optional(),
twist: z
.number()
.int()
.nonnegative()
.gte(0)
.lte(359)
.default(0)
.optional(),
altitudeAngle: z
.number()
.gte(0)
.lte(1.5707963267948966)
.default(0)
.optional(),
azimuthAngle: z
.number()
.gte(0)
.lte(6.283185307179586)
.default(0)
.optional(),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.OriginSchema = z.lazy(() => z.union([
z.literal('viewport'),
z.literal('pointer'),
Input.ElementOriginSchema,
]));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.ReleaseActionsSchema = z.lazy(() => z.object({
method: z.literal('input.releaseActions'),
params: Input.ReleaseActionsParametersSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.ReleaseActionsParametersSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.SetFilesSchema = z.lazy(() => z.object({
method: z.literal('input.setFiles'),
params: Input.SetFilesParametersSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.SetFilesParametersSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema,
element: Script$1.SharedReferenceSchema,
files: z.array(z.string()),
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.FileDialogOpenedSchema = z.lazy(() => z.object({
method: z.literal('input.fileDialogOpened'),
params: Input.FileDialogInfoSchema,
}));
})(Input$1 || (Input$1 = {}));
(function (Input) {
Input.FileDialogInfoSchema = z.lazy(() => z.object({
context: BrowsingContext$1.BrowsingContextSchema,
element: Script$1.SharedReferenceSchema.optional(),
multiple: z.boolean(),
}));
})(Input$1 || (Input$1 = {}));
const WebExtensionCommandSchema = z.lazy(() => z.union([WebExtension.InstallSchema, WebExtension.UninstallSchema]));
const WebExtensionResultSchema = z.lazy(() => WebExtension.InstallResultSchema);
var WebExtension;
(function (WebExtension) {
WebExtension.ExtensionSchema = z.lazy(() => z.string());
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.InstallParametersSchema = z.lazy(() => z.object({
extensionData: WebExtension.ExtensionDataSchema,
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.InstallSchema = z.lazy(() => z.object({
method: z.literal('webExtension.install'),
params: WebExtension.InstallParametersSchema,
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.ExtensionDataSchema = z.lazy(() => z.union([
WebExtension.ExtensionArchivePathSchema,
WebExtension.ExtensionBase64EncodedSchema,
WebExtension.ExtensionPathSchema,
]));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.ExtensionPathSchema = z.lazy(() => z.object({
type: z.literal('path'),
path: z.string(),
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.ExtensionArchivePathSchema = z.lazy(() => z.object({
type: z.literal('archivePath'),
path: z.string(),
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.ExtensionBase64EncodedSchema = z.lazy(() => z.object({
type: z.literal('base64'),
value: z.string(),
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.InstallResultSchema = z.lazy(() => z.object({
extension: WebExtension.ExtensionSchema,
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.UninstallSchema = z.lazy(() => z.object({
method: z.literal('webExtension.uninstall'),
params: WebExtension.UninstallParametersSchema,
}));
})(WebExtension || (WebExtension = {}));
(function (WebExtension) {
WebExtension.UninstallParametersSchema = z.lazy(() => z.object({
extension: WebExtension.ExtensionSchema,
}));
})(WebExtension || (WebExtension = {}));
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function parseObject(obj, schema) {
const parseResult = schema.safeParse(obj);
if (parseResult.success) {
return parseResult.data;
}
const errorMessage = parseResult.error.errors
.map((e) => `${e.message} in ` +
`${e.path.map((p) => JSON.stringify(p)).join('/')}.`)
.join(' ');
throw new InvalidArgumentException(errorMessage);
}
var Browser;
(function (Browser) {
function parseCreateUserContextParameters(params) {
return parseObject(params, Browser$1.CreateUserContextParametersSchema);
}
Browser.parseCreateUserContextParameters = parseCreateUserContextParameters;
function parseRemoveUserContextParameters(params) {
return parseObject(params, Browser$1.RemoveUserContextParametersSchema);
}
Browser.parseRemoveUserContextParameters = parseRemoveUserContextParameters;
function parseSetClientWindowStateParameters(params) {
return parseObject(params, Browser$1.SetClientWindowStateParametersSchema);
}
Browser.parseSetClientWindowStateParameters = parseSetClientWindowStateParameters;
})(Browser || (Browser = {}));
var Network;
(function (Network) {
function parseAddDataCollectorParameters(params) {
return parseObject(params, Network$1.AddDataCollectorParametersSchema);
}
Network.parseAddDataCollectorParameters = parseAddDataCollectorParameters;
function parseAddInterceptParameters(params) {
return parseObject(params, Network$1.AddInterceptParametersSchema);
}
Network.parseAddInterceptParameters = parseAddInterceptParameters;
function parseContinueRequestParameters(params) {
return parseObject(params, Network$1.ContinueRequestParametersSchema);
}
Network.parseContinueRequestParameters = parseContinueRequestParameters;
function parseContinueResponseParameters(params) {
return parseObject(params, Network$1.ContinueResponseParametersSchema);
}
Network.parseContinueResponseParameters = parseContinueResponseParameters;
function parseContinueWithAuthParameters(params) {
return parseObject(params, Network$1.ContinueWithAuthParametersSchema);
}
Network.parseContinueWithAuthParameters = parseContinueWithAuthParameters;
function parseDisownDataParameters(params) {
return parseObject(params, Network$1.DisownDataParametersSchema);
}
Network.parseDisownDataParameters = parseDisownDataParameters;
function parseFailRequestParameters(params) {
return parseObject(params, Network$1.FailRequestParametersSchema);
}
Network.parseFailRequestParameters = parseFailRequestParameters;
function parseGetDataParameters(params) {
return parseObject(params, Network$1.GetDataParametersSchema);
}
Network.parseGetDataParameters = parseGetDataParameters;
function parseProvideResponseParameters(params) {
return parseObject(params, Network$1.ProvideResponseParametersSchema);
}
Network.parseProvideResponseParameters = parseProvideResponseParameters;
function parseRemoveDataCollectorParameters(params) {
return parseObject(params, Network$1.RemoveDataCollectorParametersSchema);
}
Network.parseRemoveDataCollectorParameters = parseRemoveDataCollectorParameters;
function parseRemoveInterceptParameters(params) {
return parseObject(params, Network$1.RemoveInterceptParametersSchema);
}
Network.parseRemoveInterceptParameters = parseRemoveInterceptParameters;
function parseSetCacheBehaviorParameters(params) {
return parseObject(params, Network$1.SetCacheBehaviorParametersSchema);
}
Network.parseSetCacheBehaviorParameters = parseSetCacheBehaviorParameters;
function parseSetExtraHeadersParameters(params) {
return parseObject(params, Network$1.SetExtraHeadersParametersSchema);
}
Network.parseSetExtraHeadersParameters = parseSetExtraHeadersParameters;
})(Network || (Network = {}));
var Script;
(function (Script) {
function parseAddPreloadScriptParams(params) {
return parseObject(params, Script$1.AddPreloadScriptParametersSchema);
}
Script.parseAddPreloadScriptParams = parseAddPreloadScriptParams;
function parseCallFunctionParams(params) {
return parseObject(params, Script$1.CallFunctionParametersSchema);
}
Script.parseCallFunctionParams = parseCallFunctionParams;
function parseDisownParams(params) {
return parseObject(params, Script$1.DisownParametersSchema);
}
Script.parseDisownParams = parseDisownParams;
function parseEvaluateParams(params) {
return parseObject(params, Script$1.EvaluateParametersSchema);
}
Script.parseEvaluateParams = parseEvaluateParams;
function parseGetRealmsParams(params) {
return parseObject(params, Script$1.GetRealmsParametersSchema);
}
Script.parseGetRealmsParams = parseGetRealmsParams;
function parseRemovePreloadScriptParams(params) {
return parseObject(params, Script$1.RemovePreloadScriptParametersSchema);
}
Script.parseRemovePreloadScriptParams = parseRemovePreloadScriptParams;
})(Script || (Script = {}));
var BrowsingContext;
(function (BrowsingContext) {
function parseActivateParams(params) {
return parseObject(params, BrowsingContext$1.ActivateParametersSchema);
}
BrowsingContext.parseActivateParams = parseActivateParams;
function parseCaptureScreenshotParams(params) {
return parseObject(params, BrowsingContext$1.CaptureScreenshotParametersSchema);
}
BrowsingContext.parseCaptureScreenshotParams = parseCaptureScreenshotParams;
function parseCloseParams(params) {
return parseObject(params, BrowsingContext$1.CloseParametersSchema);
}
BrowsingContext.parseCloseParams = parseCloseParams;
function parseCreateParams(params) {
return parseObject(params, BrowsingContext$1.CreateParametersSchema);
}
BrowsingContext.parseCreateParams = parseCreateParams;
function parseGetTreeParams(params) {
return parseObject(params, BrowsingContext$1.GetTreeParametersSchema);
}
BrowsingContext.parseGetTreeParams = parseGetTreeParams;
function parseHandleUserPromptParameters(params) {
return parseObject(params, BrowsingContext$1.HandleUserPromptParametersSchema);
}
BrowsingContext.parseHandleUserPromptParameters = parseHandleUserPromptParameters;
function parseLocateNodesParams(params) {
return parseObject(params, BrowsingContext$1.LocateNodesParametersSchema);
}
BrowsingContext.parseLocateNodesParams = parseLocateNodesParams;
function parseNavigateParams(params) {
return parseObject(params, BrowsingContext$1.NavigateParametersSchema);
}
BrowsingContext.parseNavigateParams = parseNavigateParams;
function parsePrintParams(params) {
return parseObject(params, BrowsingContext$1.PrintParametersSchema);
}
BrowsingContext.parsePrintParams = parsePrintParams;
function parseReloadParams(params) {
return parseObject(params, BrowsingContext$1.ReloadParametersSchema);
}
BrowsingContext.parseReloadParams = parseReloadParams;
function parseSetViewportParams(params) {
return parseObject(params, BrowsingContext$1.SetViewportParametersSchema);
}
BrowsingContext.parseSetViewportParams = parseSetViewportParams;
function parseTraverseHistoryParams(params) {
return parseObject(params, BrowsingContext$1.TraverseHistoryParametersSchema);
}
BrowsingContext.parseTraverseHistoryParams = parseTraverseHistoryParams;
})(BrowsingContext || (BrowsingContext = {}));
var Session;
(function (Session) {
function parseSubscribeParams(params) {
return parseObject(params, Session$1.SubscriptionRequestSchema);
}
Session.parseSubscribeParams = parseSubscribeParams;
function parseUnsubscribeParams(params) {
if (params && typeof params === 'object' && 'subscriptions' in params) {
return parseObject(params, Session$1.UnsubscribeByIdRequestSchema);
}
return parseObject(params, Session$1.UnsubscribeParametersSchema);
}
Session.parseUnsubscribeParams = parseUnsubscribeParams;
})(Session || (Session = {}));
var Emulation;
(function (Emulation) {
function parseSetForcedColorsModeThemeOverrideParams(params) {
return parseObject(params, Emulation$1.SetForcedColorsModeThemeOverrideParametersSchema);
}
Emulation.parseSetForcedColorsModeThemeOverrideParams = parseSetForcedColorsModeThemeOverrideParams;
function parseSetGeolocationOverrideParams(params) {
if ('coordinates' in params && 'error' in params) {
throw new InvalidArgumentException('Coordinates and error cannot be set at the same time');
}
return parseObject(params, Emulation$1.SetGeolocationOverrideParametersSchema);
}
Emulation.parseSetGeolocationOverrideParams = parseSetGeolocationOverrideParams;
function parseSetLocaleOverrideParams(params) {
return parseObject(params, Emulation$1.SetLocaleOverrideParametersSchema);
}
Emulation.parseSetLocaleOverrideParams = parseSetLocaleOverrideParams;
function parseSetScreenOrientationOverrideParams(params) {
return parseObject(params, Emulation$1.SetScreenOrientationOverrideParametersSchema);
}
Emulation.parseSetScreenOrientationOverrideParams = parseSetScreenOrientationOverrideParams;
function parseSetScriptingEnabledParams(params) {
return parseObject(params, Emulation$1.SetScriptingEnabledParametersSchema);
}
Emulation.parseSetScriptingEnabledParams = parseSetScriptingEnabledParams;
function parseSetTimezoneOverrideParams(params) {
return parseObject(params, Emulation$1.SetTimezoneOverrideParametersSchema);
}
Emulation.parseSetTimezoneOverrideParams = parseSetTimezoneOverrideParams;
})(Emulation || (Emulation = {}));
var Input;
(function (Input) {
function parsePerformActionsParams(params) {
return parseObject(params, Input$1.PerformActionsParametersSchema);
}
Input.parsePerformActionsParams = parsePerformActionsParams;
function parseReleaseActionsParams(params) {
return parseObject(params, Input$1.ReleaseActionsParametersSchema);
}
Input.parseReleaseActionsParams = parseReleaseActionsParams;
function parseSetFilesParams(params) {
return parseObject(params, Input$1.SetFilesParametersSchema);
}
Input.parseSetFilesParams = parseSetFilesParams;
})(Input || (Input = {}));
var Storage;
(function (Storage) {
function parseDeleteCookiesParams(params) {
return parseObject(params, Storage$1.DeleteCookiesParametersSchema);
}
Storage.parseDeleteCookiesParams = parseDeleteCookiesParams;
function parseGetCookiesParams(params) {
return parseObject(params, Storage$1.GetCookiesParametersSchema);
}
Storage.parseGetCookiesParams = parseGetCookiesParams;
function parseSetCookieParams(params) {
return parseObject(params, Storage$1.SetCookieParametersSchema);
}
Storage.parseSetCookieParams = parseSetCookieParams;
})(Storage || (Storage = {}));
var Cdp;
(function (Cdp) {
const GetSessionRequestSchema = objectType({
context: BrowsingContext$1.BrowsingContextSchema,
});
const ResolveRealmRequestSchema = objectType({
realm: Script$1.RealmSchema,
});
const SendCommandRequestSchema = objectType({
method: stringType(),
params: objectType({}).passthrough().optional(),
session: stringType().optional(),
});
function parseGetSessionRequest(params) {
return parseObject(params, GetSessionRequestSchema);
}
Cdp.parseGetSessionRequest = parseGetSessionRequest;
function parseResolveRealmRequest(params) {
return parseObject(params, ResolveRealmRequestSchema);
}
Cdp.parseResolveRealmRequest = parseResolveRealmRequest;
function parseSendCommandRequest(params) {
return parseObject(params, SendCommandRequestSchema);
}
Cdp.parseSendCommandRequest = parseSendCommandRequest;
})(Cdp || (Cdp = {}));
var Permissions;
(function (Permissions) {
function parseSetPermissionsParams(params) {
return {
...params,
...parseObject(params, Permissions$1.SetPermissionParametersSchema),
};
}
Permissions.parseSetPermissionsParams = parseSetPermissionsParams;
})(Permissions || (Permissions = {}));
var Bluetooth;
(function (Bluetooth) {
function parseDisableSimulationParameters(params) {
return parseObject(params, Bluetooth$1.DisableSimulationParametersSchema);
}
Bluetooth.parseDisableSimulationParameters = parseDisableSimulationParameters;
function parseHandleRequestDevicePromptParams(params) {
return parseObject(params, Bluetooth$1
.HandleRequestDevicePromptParametersSchema);
}
Bluetooth.parseHandleRequestDevicePromptParams = parseHandleRequestDevicePromptParams;
function parseSimulateAdapterParams(params) {
return parseObject(params, Bluetooth$1.SimulateAdapterParametersSchema);
}
Bluetooth.parseSimulateAdapterParams = parseSimulateAdapterParams;
function parseSimulateAdvertisementParams(params) {
return parseObject(params, Bluetooth$1.SimulateAdvertisementParametersSchema);
}
Bluetooth.parseSimulateAdvertisementParams = parseSimulateAdvertisementParams;
function parseSimulateCharacteristicParams(params) {
return parseObject(params, Bluetooth$1.SimulateCharacteristicParametersSchema);
}
Bluetooth.parseSimulateCharacteristicParams = parseSimulateCharacteristicParams;
function parseSimulateCharacteristicResponseParams(params) {
return parseObject(params, Bluetooth$1
.SimulateCharacteristicResponseParametersSchema);
}
Bluetooth.parseSimulateCharacteristicResponseParams = parseSimulateCharacteristicResponseParams;
function parseSimulateDescriptorParams(params) {
return parseObject(params, Bluetooth$1.SimulateDescriptorParametersSchema);
}
Bluetooth.parseSimulateDescriptorParams = parseSimulateDescriptorParams;
function parseSimulateDescriptorResponseParams(params) {
return parseObject(params, Bluetooth$1
.SimulateDescriptorResponseParametersSchema);
}
Bluetooth.parseSimulateDescriptorResponseParams = parseSimulateDescriptorResponseParams;
function parseSimulateGattConnectionResponseParams(params) {
return parseObject(params, Bluetooth$1
.SimulateGattConnectionResponseParametersSchema);
}
Bluetooth.parseSimulateGattConnectionResponseParams = parseSimulateGattConnectionResponseParams;
function parseSimulateGattDisconnectionParams(params) {
return parseObject(params, Bluetooth$1
.SimulateGattDisconnectionParametersSchema);
}
Bluetooth.parseSimulateGattDisconnectionParams = parseSimulateGattDisconnectionParams;
function parseSimulatePreconnectedPeripheralParams(params) {
return parseObject(params, Bluetooth$1
.SimulatePreconnectedPeripheralParametersSchema);
}
Bluetooth.parseSimulatePreconnectedPeripheralParams = parseSimulatePreconnectedPeripheralParams;
function parseSimulateServiceParams(params) {
return parseObject(params, Bluetooth$1.SimulateServiceParametersSchema);
}
Bluetooth.parseSimulateServiceParams = parseSimulateServiceParams;
})(Bluetooth || (Bluetooth = {}));
var WebModule;
(function (WebModule) {
function parseInstallParams(params) {
return parseObject(params, WebExtension.InstallParametersSchema);
}
WebModule.parseInstallParams = parseInstallParams;
function parseUninstallParams(params) {
return parseObject(params, WebExtension.UninstallParametersSchema);
}
WebModule.parseUninstallParams = parseUninstallParams;
})(WebModule || (WebModule = {}));
class BidiParser {
parseDisableSimulationParameters(params) {
return Bluetooth.parseDisableSimulationParameters(params);
}
parseHandleRequestDevicePromptParams(params) {
return Bluetooth.parseHandleRequestDevicePromptParams(params);
}
parseSimulateAdapterParameters(params) {
return Bluetooth.parseSimulateAdapterParams(params);
}
parseSimulateAdvertisementParameters(params) {
return Bluetooth.parseSimulateAdvertisementParams(params);
}
parseSimulateCharacteristicParameters(params) {
return Bluetooth.parseSimulateCharacteristicParams(params);
}
parseSimulateCharacteristicResponseParameters(params) {
return Bluetooth.parseSimulateCharacteristicResponseParams(params);
}
parseSimulateDescriptorParameters(params) {
return Bluetooth.parseSimulateDescriptorParams(params);
}
parseSimulateDescriptorResponseParameters(params) {
return Bluetooth.parseSimulateDescriptorResponseParams(params);
}
parseSimulateGattConnectionResponseParameters(params) {
return Bluetooth.parseSimulateGattConnectionResponseParams(params);
}
parseSimulateGattDisconnectionParameters(params) {
return Bluetooth.parseSimulateGattDisconnectionParams(params);
}
parseSimulatePreconnectedPeripheralParameters(params) {
return Bluetooth.parseSimulatePreconnectedPeripheralParams(params);
}
parseSimulateServiceParameters(params) {
return Bluetooth.parseSimulateServiceParams(params);
}
parseCreateUserContextParameters(params) {
Browser.parseCreateUserContextParameters(params);
return params;
}
parseRemoveUserContextParameters(params) {
return Browser.parseRemoveUserContextParameters(params);
}
parseSetClientWindowStateParameters(params) {
return Browser.parseSetClientWindowStateParameters(params);
}
parseActivateParams(params) {
return BrowsingContext.parseActivateParams(params);
}
parseCaptureScreenshotParams(params) {
return BrowsingContext.parseCaptureScreenshotParams(params);
}
parseCloseParams(params) {
return BrowsingContext.parseCloseParams(params);
}
parseCreateParams(params) {
return BrowsingContext.parseCreateParams(params);
}
parseGetTreeParams(params) {
return BrowsingContext.parseGetTreeParams(params);
}
parseHandleUserPromptParams(params) {
return BrowsingContext.parseHandleUserPromptParameters(params);
}
parseLocateNodesParams(params) {
return BrowsingContext.parseLocateNodesParams(params);
}
parseNavigateParams(params) {
return BrowsingContext.parseNavigateParams(params);
}
parsePrintParams(params) {
return BrowsingContext.parsePrintParams(params);
}
parseReloadParams(params) {
return BrowsingContext.parseReloadParams(params);
}
parseSetViewportParams(params) {
return BrowsingContext.parseSetViewportParams(params);
}
parseTraverseHistoryParams(params) {
return BrowsingContext.parseTraverseHistoryParams(params);
}
parseGetSessionParams(params) {
return Cdp.parseGetSessionRequest(params);
}
parseResolveRealmParams(params) {
return Cdp.parseResolveRealmRequest(params);
}
parseSendCommandParams(params) {
return Cdp.parseSendCommandRequest(params);
}
parseSetForcedColorsModeThemeOverrideParams(params) {
return Emulation.parseSetForcedColorsModeThemeOverrideParams(params);
}
parseSetGeolocationOverrideParams(params) {
return Emulation.parseSetGeolocationOverrideParams(params);
}
parseSetLocaleOverrideParams(params) {
return Emulation.parseSetLocaleOverrideParams(params);
}
parseSetScreenOrientationOverrideParams(params) {
return Emulation.parseSetScreenOrientationOverrideParams(params);
}
parseSetScriptingEnabledParams(params) {
return Emulation.parseSetScriptingEnabledParams(params);
}
parseSetTimezoneOverrideParams(params) {
return Emulation.parseSetTimezoneOverrideParams(params);
}
parsePerformActionsParams(params) {
return Input.parsePerformActionsParams(params);
}
parseReleaseActionsParams(params) {
return Input.parseReleaseActionsParams(params);
}
parseSetFilesParams(params) {
return Input.parseSetFilesParams(params);
}
parseAddDataCollectorParams(params) {
return Network.parseAddDataCollectorParameters(params);
}
parseAddInterceptParams(params) {
return Network.parseAddInterceptParameters(params);
}
parseContinueRequestParams(params) {
return Network.parseContinueRequestParameters(params);
}
parseContinueResponseParams(params) {
return Network.parseContinueResponseParameters(params);
}
parseContinueWithAuthParams(params) {
return Network.parseContinueWithAuthParameters(params);
}
parseDisownDataParams(params) {
return Network.parseDisownDataParameters(params);
}
parseFailRequestParams(params) {
return Network.parseFailRequestParameters(params);
}
parseGetDataParams(params) {
return Network.parseGetDataParameters(params);
}
parseProvideResponseParams(params) {
return Network.parseProvideResponseParameters(params);
}
parseRemoveDataCollectorParams(params) {
return Network.parseRemoveDataCollectorParameters(params);
}
parseRemoveInterceptParams(params) {
return Network.parseRemoveInterceptParameters(params);
}
parseSetCacheBehaviorParams(params) {
return Network.parseSetCacheBehaviorParameters(params);
}
parseSetExtraHeadersParams(params) {
return Network.parseSetExtraHeadersParameters(params);
}
parseSetPermissionsParams(params) {
return Permissions.parseSetPermissionsParams(params);
}
parseAddPreloadScriptParams(params) {
return Script.parseAddPreloadScriptParams(params);
}
parseCallFunctionParams(params) {
return Script.parseCallFunctionParams(params);
}
parseDisownParams(params) {
return Script.parseDisownParams(params);
}
parseEvaluateParams(params) {
return Script.parseEvaluateParams(params);
}
parseGetRealmsParams(params) {
return Script.parseGetRealmsParams(params);
}
parseRemovePreloadScriptParams(params) {
return Script.parseRemovePreloadScriptParams(params);
}
parseSubscribeParams(params) {
return Session.parseSubscribeParams(params);
}
parseUnsubscribeParams(params) {
return Session.parseUnsubscribeParams(params);
}
parseDeleteCookiesParams(params) {
return Storage.parseDeleteCookiesParams(params);
}
parseGetCookiesParams(params) {
return Storage.parseGetCookiesParams(params);
}
parseSetCookieParams(params) {
return Storage.parseSetCookieParams(params);
}
parseInstallParams(params) {
return WebModule.parseInstallParams(params);
}
parseUninstallParams(params) {
return WebModule.parseUninstallParams(params);
}
}
/**
* Copyright 2022 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const mapperPageSource = '<!DOCTYPE html><title>BiDi-CDP Mapper</title><style>body{font-family: Roboto,serif;font-size:13px;color:#202124;}.log{padding: 10px;font-family:Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;font-size:11px;line-height:180%;background: #f1f3f4;border-radius:4px;}.pre{overflow-wrap: break-word; margin:10px;}.card{margin:60px auto;padding:2px 0;max-width:900px;box-shadow:0 1px 4px rgba(0,0,0,0.15),0 1px 6px rgba(0,0,0,0.2);border-radius:8px;}.divider{height:1px;background:#f0f0f0;}.item{padding:16px 20px;}</style><div class="card"><div class="item"><h1>BiDi-CDP Mapper is controlling this tab</h1><p>Closing or reloading it will stop the BiDi process. <a target="_blank" title="BiDi-CDP Mapper GitHub Repository" href="https://github.com/GoogleChromeLabs/chromium-bidi">Details.</a></p></div><div class="item"><div id="logs" class="log"></div></div></div></div>';
function generatePage() {
if (!globalThis.document.documentElement) {
return;
}
globalThis.document.documentElement.innerHTML = mapperPageSource;
globalThis.window.onbeforeunload = () => 'Closing or reloading this tab will stop the BiDi process. Are you sure you want to leave?';
}
function stringify(message) {
if (typeof message === 'object') {
return JSON.stringify(message, null, 2);
}
return message;
}
function log(logPrefix, ...messages) {
if (!globalThis.document.documentElement) {
return;
}
if (!logPrefix.startsWith(LogType.bidi)) {
globalThis.window?.sendDebugMessage?.(JSON.stringify({ logType: logPrefix, messages }, null, 2));
}
const debugContainer = document.getElementById('logs');
if (!debugContainer) {
return;
}
const lineElement = document.createElement('div');
lineElement.className = 'pre';
lineElement.textContent = [logPrefix, ...messages].map(stringify).join(' ');
debugContainer.appendChild(lineElement);
if (debugContainer.childNodes.length > 400) {
debugContainer.removeChild(debugContainer.childNodes[0]);
}
}
var _a;
class WindowBidiTransport {
static LOGGER_PREFIX_RECV = `${LogType.bidi}:RECV ◂`;
static LOGGER_PREFIX_SEND = `${LogType.bidi}:SEND ▸`;
static LOGGER_PREFIX_WARN = LogType.debugWarn;
#onMessage = null;
constructor() {
window.onBidiMessage = (message) => {
log(_a.LOGGER_PREFIX_RECV, message);
try {
const command = _a.#parseBidiMessage(message);
this.#onMessage?.call(null, command);
}
catch (e) {
const error = e instanceof Error ? e : new Error(e);
this.#respondWithError(message, "invalid argument" , error, null);
}
};
}
setOnMessage(onMessage) {
this.#onMessage = onMessage;
}
sendMessage(message) {
log(_a.LOGGER_PREFIX_SEND, message);
const json = JSON.stringify(message);
window.sendBidiResponse(json);
}
close() {
this.#onMessage = null;
window.onBidiMessage = null;
}
#respondWithError(plainCommandData, errorCode, error, googChannel) {
const errorResponse = _a.#getErrorResponse(plainCommandData, errorCode, error);
if (googChannel) {
this.sendMessage({
...errorResponse,
'goog:channel': googChannel,
});
}
else {
this.sendMessage(errorResponse);
}
}
static #getJsonType(value) {
if (value === null) {
return 'null';
}
if (Array.isArray(value)) {
return 'array';
}
return typeof value;
}
static #getErrorResponse(message, errorCode, error) {
let messageId;
try {
const command = JSON.parse(message);
if (_a.#getJsonType(command) === 'object' &&
'id' in command) {
messageId = command.id;
}
}
catch { }
return {
type: 'error',
id: messageId,
error: errorCode,
message: error.message,
};
}
static #parseBidiMessage(message) {
let command;
try {
command = JSON.parse(message);
}
catch {
throw new Error('Cannot parse data as JSON');
}
const type = _a.#getJsonType(command);
if (type !== 'object') {
throw new Error(`Expected JSON object but got ${type}`);
}
const { id, method, params } = command;
const idType = _a.#getJsonType(id);
if (idType !== 'number' || !Number.isInteger(id) || id < 0) {
throw new Error(`Expected unsigned integer but got ${idType}`);
}
const methodType = _a.#getJsonType(method);
if (methodType !== 'string') {
throw new Error(`Expected string method but got ${methodType}`);
}
const paramsType = _a.#getJsonType(params);
if (paramsType !== 'object') {
throw new Error(`Expected object params but got ${paramsType}`);
}
let googChannel = command['goog:channel'];
if (googChannel !== undefined) {
const googChannelType = _a.#getJsonType(googChannel);
if (googChannelType !== 'string') {
throw new Error(`Expected string channel but got ${googChannelType}`);
}
if (googChannel === '') {
googChannel = undefined;
}
}
return {
id,
method,
params,
'goog:channel': googChannel,
};
}
}
_a = WindowBidiTransport;
class WindowCdpTransport {
#onMessage = null;
#cdpSend;
constructor() {
this.#cdpSend = window.cdp.send;
window.cdp.send = undefined;
window.cdp.onmessage = (message) => {
this.#onMessage?.call(null, message);
};
}
setOnMessage(onMessage) {
this.#onMessage = onMessage;
}
sendMessage(message) {
this.#cdpSend(message);
}
close() {
this.#onMessage = null;
window.cdp.onmessage = null;
}
}
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @license
*/
generatePage();
const mapperTabToServerTransport = new WindowBidiTransport();
const cdpTransport = new WindowCdpTransport();
const cdpConnection = new MapperCdpConnection(cdpTransport, log);
async function runMapperInstance(selfTargetId) {
console.log('Launching Mapper instance with selfTargetId:', selfTargetId);
const bidiServer = await BidiServer.createAndStart(mapperTabToServerTransport, cdpConnection,
await cdpConnection.createBrowserSession(), selfTargetId, new BidiParser(), log);
log(LogType.debugInfo, 'Mapper instance has been launched');
return bidiServer;
}
window.runMapperInstance = async (selfTargetId) => {
await runMapperInstance(selfTargetId);
};
})();
//# sourceMappingURL=mapperTab.js.map