268 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| /**
 | |
|  * 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.
 | |
|  */
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.CommandProcessor = void 0;
 | |
| const protocol_js_1 = require("../protocol/protocol.js");
 | |
| const EventEmitter_js_1 = require("../utils/EventEmitter.js");
 | |
| const log_js_1 = require("../utils/log.js");
 | |
| const BidiNoOpParser_js_1 = require("./BidiNoOpParser.js");
 | |
| const BrowserProcessor_js_1 = require("./modules/browser/BrowserProcessor.js");
 | |
| const CdpProcessor_js_1 = require("./modules/cdp/CdpProcessor.js");
 | |
| const BrowsingContextProcessor_js_1 = require("./modules/context/BrowsingContextProcessor.js");
 | |
| const InputProcessor_js_1 = require("./modules/input/InputProcessor.js");
 | |
| const NetworkProcessor_js_1 = require("./modules/network/NetworkProcessor.js");
 | |
| const PermissionsProcessor_js_1 = require("./modules/permissions/PermissionsProcessor.js");
 | |
| const ScriptProcessor_js_1 = require("./modules/script/ScriptProcessor.js");
 | |
| const SessionProcessor_js_1 = require("./modules/session/SessionProcessor.js");
 | |
| const StorageProcessor_js_1 = require("./modules/storage/StorageProcessor.js");
 | |
| const OutgoingMessage_js_1 = require("./OutgoingMessage.js");
 | |
| class CommandProcessor extends EventEmitter_js_1.EventEmitter {
 | |
|     // keep-sorted start
 | |
|     #bluetoothProcessor;
 | |
|     #browserProcessor;
 | |
|     #browsingContextProcessor;
 | |
|     #cdpProcessor;
 | |
|     #inputProcessor;
 | |
|     #networkProcessor;
 | |
|     #permissionsProcessor;
 | |
|     #scriptProcessor;
 | |
|     #sessionProcessor;
 | |
|     #storageProcessor;
 | |
|     // keep-sorted end
 | |
|     #parser;
 | |
|     #logger;
 | |
|     constructor(cdpConnection, browserCdpClient, eventManager, browsingContextStorage, realmStorage, preloadScriptStorage, networkStorage, bluetoothProcessor, parser = new BidiNoOpParser_js_1.BidiNoOpParser(), initConnection, logger) {
 | |
|         super();
 | |
|         this.#parser = parser;
 | |
|         this.#logger = logger;
 | |
|         this.#bluetoothProcessor = bluetoothProcessor;
 | |
|         // keep-sorted start block=yes
 | |
|         this.#browserProcessor = new BrowserProcessor_js_1.BrowserProcessor(browserCdpClient, browsingContextStorage);
 | |
|         this.#browsingContextProcessor = new BrowsingContextProcessor_js_1.BrowsingContextProcessor(browserCdpClient, browsingContextStorage, eventManager);
 | |
|         this.#cdpProcessor = new CdpProcessor_js_1.CdpProcessor(browsingContextStorage, realmStorage, cdpConnection, browserCdpClient);
 | |
|         this.#inputProcessor = new InputProcessor_js_1.InputProcessor(browsingContextStorage);
 | |
|         this.#networkProcessor = new NetworkProcessor_js_1.NetworkProcessor(browsingContextStorage, networkStorage);
 | |
|         this.#permissionsProcessor = new PermissionsProcessor_js_1.PermissionsProcessor(browserCdpClient);
 | |
|         this.#scriptProcessor = new ScriptProcessor_js_1.ScriptProcessor(eventManager, browsingContextStorage, realmStorage, preloadScriptStorage, logger);
 | |
|         this.#sessionProcessor = new SessionProcessor_js_1.SessionProcessor(eventManager, browserCdpClient, initConnection);
 | |
|         this.#storageProcessor = new StorageProcessor_js_1.StorageProcessor(browserCdpClient, browsingContextStorage, logger);
 | |
|         // keep-sorted end
 | |
|     }
 | |
|     async #processCommand(command) {
 | |
|         switch (command.method) {
 | |
|             // Bluetooth module
 | |
|             // keep-sorted start block=yes
 | |
|             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.simulatePreconnectedPeripheral':
 | |
|                 return await this.#bluetoothProcessor.simulatePreconnectedPeripheral(this.#parser.parseSimulatePreconnectedPeripheralParameters(command.params));
 | |
|             // keep-sorted end
 | |
|             // Browser module
 | |
|             // keep-sorted start block=yes
 | |
|             case 'browser.close':
 | |
|                 return this.#browserProcessor.close();
 | |
|             case 'browser.createUserContext':
 | |
|                 return await this.#browserProcessor.createUserContext(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.parseRemoveUserContextParams(command.params));
 | |
|             case 'browser.setClientWindowState':
 | |
|                 throw new protocol_js_1.UnknownErrorException(`Method ${command.method} is not implemented.`);
 | |
|             // keep-sorted end
 | |
|             // Browsing Context module
 | |
|             // keep-sorted start block=yes
 | |
|             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));
 | |
|             // keep-sorted end
 | |
|             // CDP module
 | |
|             // keep-sorted start block=yes
 | |
|             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));
 | |
|             // keep-sorted end
 | |
|             // CDP deprecated domain.
 | |
|             // https://github.com/GoogleChromeLabs/chromium-bidi/issues/2844
 | |
|             // keep-sorted start block=yes
 | |
|             case 'cdp.getSession':
 | |
|                 return this.#cdpProcessor.getSession(this.#parser.parseGetSessionParams(command.params));
 | |
|             case 'cdp.resolveRealm':
 | |
|                 return this.#cdpProcessor.resolveRealm(this.#parser.parseResolveRealmParams(command.params));
 | |
|             case 'cdp.sendCommand':
 | |
|                 return await this.#cdpProcessor.sendCommand(this.#parser.parseSendCommandParams(command.params));
 | |
|             // keep-sorted end
 | |
|             // Input module
 | |
|             // keep-sorted start block=yes
 | |
|             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));
 | |
|             // keep-sorted end
 | |
|             // Network module
 | |
|             // keep-sorted start block=yes
 | |
|             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.failRequest':
 | |
|                 return await this.#networkProcessor.failRequest(this.#parser.parseFailRequestParams(command.params));
 | |
|             case 'network.provideResponse':
 | |
|                 return await this.#networkProcessor.provideResponse(this.#parser.parseProvideResponseParams(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.parseSetCacheBehavior(command.params));
 | |
|             // keep-sorted end
 | |
|             // Permissions module
 | |
|             // keep-sorted start block=yes
 | |
|             case 'permissions.setPermission':
 | |
|                 return await this.#permissionsProcessor.setPermissions(this.#parser.parseSetPermissionsParams(command.params));
 | |
|             // keep-sorted end
 | |
|             // Script module
 | |
|             // keep-sorted start block=yes
 | |
|             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));
 | |
|             // keep-sorted end
 | |
|             // Session module
 | |
|             // keep-sorted start block=yes
 | |
|             case 'session.end':
 | |
|                 throw new protocol_js_1.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.channel);
 | |
|             case 'session.unsubscribe':
 | |
|                 return await this.#sessionProcessor.unsubscribe(this.#parser.parseSubscribeParams(command.params), command.channel);
 | |
|             // keep-sorted end
 | |
|             // Storage module
 | |
|             // keep-sorted start block=yes
 | |
|             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));
 | |
|             // keep-sorted end
 | |
|             // WebExtension module
 | |
|             // keep-sorted start block=yes
 | |
|             case 'webExtension.install':
 | |
|                 throw new protocol_js_1.UnknownErrorException(`Method ${command.method} is not implemented.`);
 | |
|             case 'webExtension.uninstall':
 | |
|                 throw new protocol_js_1.UnknownErrorException(`Method ${command.method} is not implemented.`);
 | |
|             // keep-sorted end
 | |
|         }
 | |
|         // Intentionally kept outside the switch statement to ensure that
 | |
|         // ESLint @typescript-eslint/switch-exhaustiveness-check triggers if a new
 | |
|         // command is added.
 | |
|         throw new protocol_js_1.UnknownCommandException(`Unknown command '${command?.method}'.`);
 | |
|     }
 | |
|     // Workaround for as zod.union always take the first schema
 | |
|     // https://github.com/w3c/webdriver-bidi/issues/635
 | |
|     #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" /* CommandProcessorEvents.Response */, {
 | |
|                 message: OutgoingMessage_js_1.OutgoingMessage.createResolved(response, command.channel),
 | |
|                 event: command.method,
 | |
|             });
 | |
|         }
 | |
|         catch (e) {
 | |
|             if (e instanceof protocol_js_1.Exception) {
 | |
|                 this.emit("response" /* CommandProcessorEvents.Response */, {
 | |
|                     message: OutgoingMessage_js_1.OutgoingMessage.createResolved(e.toErrorResponse(command.id), command.channel),
 | |
|                     event: command.method,
 | |
|                 });
 | |
|             }
 | |
|             else {
 | |
|                 const error = e;
 | |
|                 this.#logger?.(log_js_1.LogType.bidi, error);
 | |
|                 this.emit("response" /* CommandProcessorEvents.Response */, {
 | |
|                     message: OutgoingMessage_js_1.OutgoingMessage.createResolved(new protocol_js_1.UnknownErrorException(error.message, error.stack).toErrorResponse(command.id), command.channel),
 | |
|                     event: command.method,
 | |
|                 });
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| exports.CommandProcessor = CommandProcessor;
 | |
| //# sourceMappingURL=CommandProcessor.js.map
 | 
