This commit is contained in:
nik
2025-10-03 22:27:28 +03:00
parent 829fad0e17
commit 871cf7e792
16520 changed files with 2967597 additions and 3 deletions

View File

@@ -0,0 +1,9 @@
import { type LoggerFn } from '../../../utils/log.js';
import type { CdpTarget } from '../cdp/CdpTarget.js';
import type { RealmStorage } from '../script/RealmStorage.js';
import type { EventManager } from '../session/EventManager.js';
export declare class LogManager {
#private;
private constructor();
static create(cdpTarget: CdpTarget, realmStorage: RealmStorage, eventManager: EventManager, logger?: LoggerFn): LogManager;
}

View File

@@ -0,0 +1,187 @@
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogManager = void 0;
const protocol_js_1 = require("../../../protocol/protocol.js");
const log_js_1 = require("../../../utils/log.js");
const logHelper_js_1 = require("./logHelper.js");
/** Converts CDP StackTrace object to BiDi StackTrace object. */
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" /* Log.Level.Error */, 'assert'].includes(consoleApiType)) {
return "error" /* Log.Level.Error */;
}
if (["debug" /* Log.Level.Debug */, 'trace'].includes(consoleApiType)) {
return "debug" /* Log.Level.Debug */;
}
if (["warn" /* Log.Level.Warn */, 'warning'].includes(consoleApiType)) {
return "warn" /* Log.Level.Warn */;
}
return "info" /* Log.Level.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(cdpTarget, realmStorage, eventManager, logger);
logManager.#initializeEntryAddedEventListener();
return logManager;
}
/**
* Heuristic serialization of CDP remote object. If possible, return the BiDi value
* without deep serialization.
*/
async #heuristicSerializeArg(arg, realm) {
switch (arg.type) {
// TODO: Implement regexp, array, object, map and set heuristics base on
// preview.
case 'undefined':
return { type: 'undefined' };
case 'boolean':
return { type: 'boolean', value: arg.value };
case 'string':
return { type: 'string', value: arg.value };
case 'number':
// The value can be either a number or a string like `Infinity` or `-0`.
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),
};
}
// Unexpected bigint value, fall back to CDP deep serialization.
break;
case 'object':
if (arg.subtype === 'null') {
return { type: 'null' };
}
// Fall back to CDP deep serialization.
break;
default:
// Fall back to CDP deep serialization.
break;
}
// Fall back to CDP deep serialization.
return await realm.serializeCdpObject(arg, "none" /* Script.ResultOwnership.None */);
}
#initializeEntryAddedEventListener() {
this.#cdpTarget.cdpClient.on('Runtime.consoleAPICalled', (params) => {
// Try to find realm by `cdpSessionId` and `executionContextId`,
// if provided.
const realm = this.#realmStorage.findRealm({
cdpSessionId: this.#cdpTarget.cdpSessionId,
executionContextId: params.executionContextId,
});
if (realm === undefined) {
// Ignore exceptions not attached to any realm.
this.#logger?.(log_js_1.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: protocol_js_1.ChromiumBidi.Log.EventNames.LogEntryAdded,
params: {
level: getLogLevel(params.type),
source: realm.source,
text: (0, logHelper_js_1.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, protocol_js_1.ChromiumBidi.Log.EventNames.LogEntryAdded);
}
});
this.#cdpTarget.cdpClient.on('Runtime.exceptionThrown', (params) => {
// Try to find realm by `cdpSessionId` and `executionContextId`,
// if provided.
const realm = this.#realmStorage.findRealm({
cdpSessionId: this.#cdpTarget.cdpSessionId,
executionContextId: params.exceptionDetails.executionContextId,
});
if (realm === undefined) {
// Ignore exceptions not attached to any realm.
this.#logger?.(log_js_1.LogType.cdp, params);
return;
}
for (const browsingContext of realm.associatedBrowsingContexts) {
this.#eventManager.registerPromiseEvent(_a.#getExceptionText(params, realm).then((text) => ({
kind: 'success',
value: {
type: 'event',
method: protocol_js_1.ChromiumBidi.Log.EventNames.LogEntryAdded,
params: {
level: "error" /* Log.Level.Error */,
source: realm.source,
text,
timestamp: Math.round(params.timestamp),
stackTrace: getBidiStackTrace(params.exceptionDetails.stackTrace),
type: 'javascript',
},
},
}), (error) => ({
kind: 'error',
error,
})), browsingContext.id, protocol_js_1.ChromiumBidi.Log.EventNames.LogEntryAdded);
}
});
}
/**
* Try the best to get the exception text.
*/
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);
}
}
exports.LogManager = LogManager;
_a = LogManager;
//# sourceMappingURL=LogManager.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
/**
* 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.
*/
import type { Script } from '../../../protocol/protocol.js';
/**
* @param args input remote values to be format printed
* @return parsed text of the remote values in specific format
*/
export declare function logMessageFormatter(args: Script.RemoteValue[]): string;
export declare function getRemoteValuesText(args: Script.RemoteValue[], formatText: boolean): string;

View File

@@ -0,0 +1,173 @@
"use strict";
/**
* 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.logMessageFormatter = logMessageFormatter;
exports.getRemoteValuesText = getRemoteValuesText;
const assert_js_1 = require("../../../utils/assert.js");
const specifiers = ['%s', '%d', '%i', '%f', '%o', '%O', '%c'];
function isFormatSpecifier(str) {
return specifiers.some((spec) => str.includes(spec));
}
/**
* @param args input remote values to be format printed
* @return parsed text of the remote values in specific format
*/
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();
// raise an exception when less value is provided
(0, assert_js_1.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 {
// %o, %O, %c
output += toJson(arg);
}
}
else {
output += token;
}
}
// raise an exception when more value is provided
if (argValues.length > 0) {
throw new Error(`More value is provided: "${getRemoteValuesText(args, false)}"`);
}
return output;
}
/**
* @param arg input remote value to be parsed
* @return parsed text of the remote value
*
* input: {"type": "number", "value": 1}
* output: 1
*
* input: {"type": "string", "value": "abc"}
* output: "abc"
*
* input: {"type": "object", "value": [["id", {"type": "number", "value": 1}]]}
* output: '{"id": 1}'
*
* input: {"type": "object", "value": [["font-size", {"type": "string", "value": "20px"}]]}
* output: '{"font-size": "20px"}'
*/
function toJson(arg) {
// arg type validation
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(',') ?? ''}]`;
}
// eslint-disable-next-line @typescript-eslint/no-base-to-string
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 args[0] is a format specifier, format the args as output
if (arg.type === 'string' &&
isFormatSpecifier(arg.value.toString()) &&
formatText) {
return logMessageFormatter(args);
}
// if args[0] is not a format specifier, just join the args with \u0020 (unicode 'SPACE')
return args
.map((arg) => {
return stringFromArg(arg);
})
.join('\u0020');
}
//# sourceMappingURL=logHelper.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logHelper.js","sourceRoot":"","sources":["../../../../../src/bidiMapper/modules/log/logHelper.ts"],"names":[],"mappings":"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"}