fix(keybord): resolve selectAll/Copy/Paste event (#384)

* fix(keybord): resolve selectAll/Copy/Paste event

* chore: fix e2e test

* chore: upgrade deps

* chore: add keybord commands  ref
This commit is contained in:
Zhou Xiao 2025-02-13 15:53:53 +08:00 committed by GitHub
parent f7c583cdf5
commit 8e69f8d151
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 362 additions and 153 deletions

View File

@ -23,7 +23,7 @@
"dependencies": {
"@midscene/core": "workspace:*",
"@midscene/web": "workspace:*",
"puppeteer": "23.0.2",
"puppeteer": "24.2.0",
"http-server": "14.1.1"
},
"devDependencies": {

View File

@ -144,7 +144,7 @@
"js-sha256": "0.11.0",
"js-yaml": "4.1.0",
"playwright": "1.44.1",
"puppeteer": "23.0.2",
"puppeteer": "24.2.0",
"typescript": "~5.0.4",
"vitest": "^1.6.0",
"webdriverio": "9.0.6"

View File

@ -79,7 +79,11 @@ export class Page implements AbstractPage {
get keyboard() {
return {
type: (text: string) => this.keyboardType(text),
press: (key: WebKeyInput) => this.keyboardPress(key),
press: (
action:
| { key: WebKeyInput; command?: string }
| { key: WebKeyInput; command?: string }[],
) => this.keyboardPressAction(action),
};
}
@ -226,6 +230,38 @@ export class Page implements AbstractPage {
]);
}
private async keyboardPressAction(
action:
| { key: WebKeyInput; command?: string }
| { key: WebKeyInput; command?: string }[],
): Promise<void> {
if (Array.isArray(action)) {
for (const act of action) {
await this.browser.performActions([
{
type: 'key',
id: 'keyboard',
actions: [
{ type: 'keyDown', value: act.key },
{ type: 'keyUp', value: act.key },
],
},
]);
}
} else {
await this.browser.performActions([
{
type: 'key',
id: 'keyboard',
actions: [
{ type: 'keyDown', value: action.key },
{ type: 'keyUp', value: action.key },
],
},
]);
}
}
private async mouseClick(
x: number,
y: number,

View File

@ -389,7 +389,9 @@ export default class ChromeExtensionProxyPage implements AbstractPage {
await sleep(100);
await this.keyboard.press('Backspace');
await this.keyboard.press({
key: 'Backspace',
});
}
mouse = {
@ -465,16 +467,21 @@ export default class ChromeExtensionProxyPage implements AbstractPage {
});
await cdpKeyboard.type(text, { delay: 0 });
},
press: async (key: WebKeyInput | WebKeyInput[]) => {
press: async (
action:
| { key: WebKeyInput; command?: string }
| { key: WebKeyInput; command?: string }[],
) => {
const cdpKeyboard = new CdpKeyboard({
send: this.sendCommandToDebugger.bind(this),
});
const keys = Array.isArray(key) ? key : [key];
const keys = Array.isArray(action) ? action : [action];
for (const k of keys) {
await cdpKeyboard.down(k);
const commands = k.command ? [k.command] : [];
await cdpKeyboard.down(k.key, { commands });
}
for (const k of [...keys].reverse()) {
await cdpKeyboard.up(k);
await cdpKeyboard.up(k.key);
}
},
};

View File

@ -37,6 +37,7 @@ import type { ElementInfo } from '@midscene/shared/extractor';
import type { KeyInput } from 'puppeteer';
import type { WebElementInfo } from '../web-element';
import { TaskCache } from './task-cache';
import { getKeyCommands } from './ui-utils';
import type { WebUIContext } from './utils';
interface ExecutionResult<OutputType = any> {
@ -296,8 +297,9 @@ export class PageTaskExecutor {
thought: plan.thought,
locate: plan.locate,
executor: async (taskParam) => {
assert(taskParam?.value, 'No key to press');
await this.page.keyboard.press(taskParam.value as KeyInput);
const keys = getKeyCommands(taskParam.value);
await this.page.keyboard.press(keys);
},
};
tasks.push(taskActionKeyboardPress);
@ -767,7 +769,7 @@ export class PageTaskExecutor {
const cacheGroup = this.taskCache.getCacheGroupByPrompt(userPrompt);
const isCompleted = false;
let currentActionNumber = 0;
const maxActionNumber = 20;
const maxActionNumber = 40;
while (!isCompleted && currentActionNumber < maxActionNumber) {
currentActionNumber++;

View File

@ -13,6 +13,29 @@ export function typeStr(task: ExecutionTask) {
return task.subType ? `${task.type} / ${task.subType || ''}` : task.type;
}
export function getKeyCommands(
value: string | string[],
): Array<{ key: string; command?: string }> {
// Ensure value is an array of keys
const keys = Array.isArray(value) ? value : [value];
// Process each key to attach a corresponding command if needed, based on the presence of 'Meta' or 'Control' in the keys array.
// ref: https://github.com/puppeteer/puppeteer/pull/9357/files#diff-32cf475237b000f980eb214a0a823e45a902bddb7d2426d677cae96397aa0ae4R94
return keys.reduce((acc: Array<{ key: string; command?: string }>, k) => {
const includeMeta = keys.includes('Meta') || keys.includes('Control');
if (includeMeta && (k === 'a' || k === 'A')) {
return acc.concat([{ key: k, command: 'SelectAll' }]);
}
if (includeMeta && (k === 'c' || k === 'C')) {
return acc.concat([{ key: k, command: 'Copy' }]);
}
if (includeMeta && (k === 'v' || k === 'V')) {
return acc.concat([{ key: k, command: 'Paste' }]);
}
return acc.concat([{ key: k }]);
}, []);
}
export function paramStr(task: ExecutionTask) {
let value: string | undefined | object;
if (task.type === 'Planning') {

View File

@ -21,7 +21,11 @@ export interface MouseAction {
export interface KeyboardAction {
type: (text: string) => Promise<void>;
press: (key: WebKeyInput) => Promise<void>;
press: (
action:
| { key: WebKeyInput; command?: string }
| { key: WebKeyInput; command?: string }[],
) => Promise<void>;
}
export abstract class AbstractPage {
@ -52,7 +56,11 @@ export abstract class AbstractPage {
get keyboard(): KeyboardAction {
return {
type: async (text: string) => {},
press: async (key: WebKeyInput) => {},
press: async (
action:
| { key: WebKeyInput; command?: string }
| { key: WebKeyInput; command?: string }[],
) => {},
};
}

View File

@ -139,14 +139,19 @@ export class Page<
return {
type: async (text: string) =>
this.underlyingPage.keyboard.type(text, { delay: 80 }),
press: async (key: WebKeyInput | WebKeyInput[]) => {
const keys = Array.isArray(key) ? key : [key];
for (const key of keys) {
await this.underlyingPage.keyboard.down(key);
}
for (const key of [...keys].reverse()) {
await this.underlyingPage.keyboard.up(key);
press: async (
action:
| { key: WebKeyInput; command?: string }
| { key: WebKeyInput; command?: string }[],
) => {
const keys = Array.isArray(action) ? action : [action];
for (const k of keys) {
const commands = k.command ? [k.command] : [];
await this.underlyingPage.keyboard.down(k.key, { commands });
}
for (const k of [...keys].reverse()) {
await this.underlyingPage.keyboard.up(k.key);
}
},
down: async (key: WebKeyInput) => {
@ -184,7 +189,7 @@ export class Page<
await this.underlyingPage.keyboard.up('Control');
}
await sleep(100);
await this.keyboard.press('Backspace');
await this.keyboard.press([{ key: 'Backspace' }]);
}
private async moveToPoint(point?: Point): Promise<void> {

View File

@ -6,23 +6,20 @@ import { sleep } from '@midscene/core/utils';
import { describe, expect, it, vi } from 'vitest';
vi.setConfig({
testTimeout: 40 * 60 * 1000,
testTimeout: 300 * 1000,
});
describe.skipIf(!process.env.BRIDGE_MODE)('drag event', () => {
it('agent in cli side, current tab', async () => {
const agent = new AgentOverChromeBridge({
cacheId: 'star-midscene-github',
});
await agent.connectCurrentTab({
trackingActiveTab: true,
// cacheId: 'finish-form-and-submit',
});
await agent.connectCurrentTab();
await agent.aiAction(
'Search midscene github and complete the star like or cancel',
);
await sleep(2000);
await sleep(3000);
await agent.aiAction('输入 "Happy Birthday只需要输入即可"');
await agent.aiQuery('输入框内容Array<string>');
await agent.destroy();
});

View File

@ -13,36 +13,36 @@ test('ai todo', async ({ ai, aiQuery }) => {
}
await ai('Enter "Happy Birthday" in the task box');
// await ai('Enter "Learn JS today"in the task box, then press Enter to create');
await ai('Enter "Learn JS today"in the task box, then press Enter to create');
// await ai(
// 'Enter "Learn Rust tomorrow" in the task box, then press Enter to create',
// );
// await ai(
// 'Enter "Learning AI the day after tomorrow" in the task box, then press Enter to create',
// );
await ai(
'Enter "Learn Rust tomorrow" in the task box, then press Enter to create',
);
await ai(
'Enter "Learning AI the day after tomorrow" in the task box, then press Enter to create',
);
// const allTaskList = await aiQuery<string[]>('string[], tasks in the list');
// console.log('allTaskList', allTaskList);
// // expect(allTaskList.length).toBe(3);
// expect(allTaskList).toContain('Learn JS today');
// expect(allTaskList).toContain('Learn Rust tomorrow');
// expect(allTaskList).toContain('Learning AI the day after tomorrow');
const allTaskList = await aiQuery<string[]>('string[], tasks in the list');
console.log('allTaskList', allTaskList);
// expect(allTaskList.length).toBe(3);
expect(allTaskList).toContain('Learn JS today');
expect(allTaskList).toContain('Learn Rust tomorrow');
expect(allTaskList).toContain('Learning AI the day after tomorrow');
// await ai('Move your mouse over the second item in the task list');
// await ai('Click the delete button to the right of the second task');
// await ai('Click the checkbox next to the second task');
// await ai('Click the "completed" Status button below the task list');
await ai('Move your mouse over the second item in the task list');
await ai('Click the delete button to the right of the second task');
await ai('Click the checkbox next to the second task');
await ai('Click the "completed" Status button below the task list');
// const taskList = await aiQuery<string[]>(
// 'string[], Extract all task names from the list',
// );
// expect(taskList.length).toBe(1);
// expect(taskList[0]).toBe('Learning AI the day after tomorrow');
const taskList = await aiQuery<string[]>(
'string[], Extract all task names from the list',
);
expect(taskList.length).toBe(1);
expect(taskList[0]).toBe('Learning AI the day after tomorrow');
// const placeholder = await ai(
// 'string, return the placeholder text in the input box',
// { type: 'query' },
// );
// expect(placeholder).toBe('What needs to be done?');
const placeholder = await ai(
'string, return the placeholder text in the input box',
{ type: 'query' },
);
expect(placeholder).toBe('What needs to be done?');
});

View File

@ -15,6 +15,13 @@ describe('puppeteer integration', () => {
}
});
it('input and clear text', async () => {
const { originPage, reset } = await launchPage('https://www.google.com/');
resetFn = reset;
const agent = new PuppeteerAgent(originPage);
await agent.aiAction('Enter "happy birthday" and select Delete all');
});
it('Sauce Demo, agent with yaml script', async () => {
const { originPage, reset } = await launchPage('https://www.bing.com/');
resetFn = reset;
@ -22,17 +29,17 @@ describe('puppeteer integration', () => {
await sleep(3000);
const { result } = await agent.runYaml(
`
tasks:
- name: search weather
flow:
- ai: input 'weather today' in input box, click search button
- sleep: 3000
tasks:
- name: search weather
flow:
- ai: input 'weather today' in input box, click search button
- sleep: 3000
- name: query weather
flow:
- aiQuery: "the result shows the weather info, {description: string}"
name: weather
`,
- name: query weather
flow:
- aiQuery: "the result shows the weather info, {description: string}"
name: weather
`,
);
expect(result.weather.description).toBeDefined();
@ -46,11 +53,11 @@ tasks:
try {
await agent.runYaml(
`
tasks:
- name: search weather
flow:
- aiAssert: the result shows food delivery service
`,
tasks:
- name: search weather
flow:
- aiAssert: the result shows food delivery service
`,
);
} catch (e: any) {
errorMsg = e.message;
@ -66,22 +73,22 @@ tasks:
const agent = new PuppeteerAgent(originPage);
const { result } = await agent.runYaml(
`
tasks:
- name: search weather
flow:
- ai: input 'weather today' in input box, click search button
- sleep: 3000
tasks:
- name: search weather
flow:
- ai: input 'weather today' in input box, click search button
- sleep: 3000
- name: query weather
flow:
- aiQuery: "the result shows the weather info, {description: string}"
name: weather
- name: query weather
flow:
- aiQuery: "the result shows the weather info, {description: string}"
name: weather
- name: error
continueOnError: true
flow:
- aiAssert: the result shows food delivery service
`,
- name: error
continueOnError: true
flow:
- aiAssert: the result shows food delivery service
`,
);
expect(result.weather.description).toBeDefined();

View File

@ -1,3 +1,4 @@
import { getKeyCommands } from '@/common/ui-utils';
import { getCurrentExecutionFile } from '@/common/utils';
import { beforeEach, describe, expect, it } from 'vitest';
@ -28,3 +29,43 @@ describe('TaskCache', () => {
expect(currentExecutionFile).toBe(false);
});
});
describe('getKeyCommands', () => {
it('should return a single key without command when no meta or control key is provided', () => {
const result = getKeyCommands('a');
expect(result).toEqual([{ key: 'a' }]);
});
it('should work with array input without meta key', () => {
const result = getKeyCommands(['b', 'd']);
expect(result).toEqual([{ key: 'b' }, { key: 'd' }]);
});
it('should attach "SelectAll" command when "Meta" is present with key "a"', () => {
const result = getKeyCommands(['Meta', 'a', 'b']);
expect(result).toEqual([
{ key: 'Meta' },
{ key: 'a', command: 'SelectAll' },
{ key: 'b' },
]);
});
it('should attach "Copy" command when "Control" is present with key "c"', () => {
const result = getKeyCommands(['Control', 'c', 'x']);
expect(result).toEqual([
{ key: 'Control' },
{ key: 'c', command: 'Copy' },
{ key: 'x' },
]);
});
it('should attach proper commands for uppercase letters when "Meta" is present', () => {
const result = getKeyCommands(['Meta', 'A', 'C', 'V']);
expect(result).toEqual([
{ key: 'Meta' },
{ key: 'A', command: 'SelectAll' },
{ key: 'C', command: 'Copy' },
{ key: 'V', command: 'Paste' },
]);
});
});

View File

@ -15,8 +15,9 @@ dotenv.config({
const aiTestType = process.env.AI_TEST_TYPE;
const unitTests = ['tests/unit-test/**/*.test.ts'];
const aiWebTests = [
'tests/ai/web/**/*.test.ts',
'tests/ai/bridge/**/*.test.ts',
'tests/ai/web/puppeteer/agent.test.ts',
// 'tests/ai/web/**/*.test.ts',
// 'tests/ai/bridge/**/*.test.ts',
];
const aiNativeTests = ['tests/ai/native/**/*.test.ts'];
// const aiNativeTests = ['tests/ai/native/appium/dongchedi.test.ts'];

212
pnpm-lock.yaml generated
View File

@ -91,8 +91,8 @@ importers:
specifier: 14.1.1
version: 14.1.1
puppeteer:
specifier: 23.0.2
version: 23.0.2(typescript@5.0.4)
specifier: 24.2.0
version: 24.2.0(typescript@5.0.4)
devDependencies:
'@modern-js/module-tools':
specifier: 2.60.6
@ -412,8 +412,8 @@ importers:
specifier: 1.44.1
version: 1.44.1
puppeteer:
specifier: 23.0.2
version: 23.0.2(typescript@5.0.4)
specifier: 24.2.0
version: 24.2.0(typescript@5.0.4)
typescript:
specifier: ~5.0.4
version: 5.0.4
@ -3098,13 +3098,13 @@ packages:
'@promptbook/utils@0.69.5':
resolution: {integrity: sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==}
'@puppeteer/browsers@2.3.0':
resolution: {integrity: sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==}
'@puppeteer/browsers@2.4.0':
resolution: {integrity: sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==}
engines: {node: '>=18'}
hasBin: true
'@puppeteer/browsers@2.4.0':
resolution: {integrity: sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==}
'@puppeteer/browsers@2.7.1':
resolution: {integrity: sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==}
engines: {node: '>=18'}
hasBin: true
@ -4361,12 +4361,23 @@ packages:
bare-fs@2.3.5:
resolution: {integrity: sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==}
bare-fs@4.0.1:
resolution: {integrity: sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==}
engines: {bare: '>=1.7.0'}
bare-os@2.4.4:
resolution: {integrity: sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==}
bare-os@3.4.0:
resolution: {integrity: sha512-9Ous7UlnKbe3fMi7Y+qh0DwAup6A1JkYgPnjvMDNOlmnxNRQvQ/7Nst+OnUQKzk0iAT0m9BisbDVp9gCv8+ETA==}
engines: {bare: '>=1.6.0'}
bare-path@2.1.3:
resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==}
bare-path@3.0.0:
resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==}
bare-stream@2.3.2:
resolution: {integrity: sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==}
@ -4634,8 +4645,8 @@ packages:
resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
engines: {node: '>=6.0'}
chromium-bidi@0.6.4:
resolution: {integrity: sha512-8zoq6ogmhQQkAKZVKO2ObFTl4uOkqoX1PlKQX3hZQ5E9cbUotcAb7h4pTNVAGGv8Z36PF3CtdOriEp/Rz82JqQ==}
chromium-bidi@1.2.0:
resolution: {integrity: sha512-XtdJ1GSN6S3l7tO7F77GhNsw0K367p0IsLYf2yZawCVAKKC3lUvDhPdMVrB2FNhmhfW43QGYbEX3Wg6q0maGwQ==}
peerDependencies:
devtools-protocol: '*'
@ -5216,12 +5227,12 @@ packages:
devlop@1.1.0:
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
devtools-protocol@0.0.1312386:
resolution: {integrity: sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==}
devtools-protocol@0.0.1380148:
resolution: {integrity: sha512-1CJABgqLxbYxVI+uJY/UDUHJtJ0KZTSjNYJYKqd9FRoXT33WDakDHNxRapMEgzeJ/C3rcs01+avshMnPmKQbvA==}
devtools-protocol@0.0.1402036:
resolution: {integrity: sha512-JwAYQgEvm3yD45CHB+RmF5kMbWtXBaOGwuxa87sZogHcLCv8c/IqnThaoQ1y60d7pXWjSKWQphPEc+1rAScVdg==}
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
@ -7689,6 +7700,10 @@ packages:
resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==}
engines: {node: '>= 14'}
pac-proxy-agent@7.1.0:
resolution: {integrity: sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==}
engines: {node: '>= 14'}
pac-resolver@7.0.1:
resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
engines: {node: '>= 14'}
@ -8260,6 +8275,10 @@ packages:
resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==}
engines: {node: '>= 14'}
proxy-agent@6.5.0:
resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==}
engines: {node: '>= 14'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@ -8289,12 +8308,12 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
puppeteer-core@23.0.2:
resolution: {integrity: sha512-MvOHn+g1TYkAR2oVd/bf/YWXKqFTJmkhyyurYgxkrjh8rBOL1ZH5VyOsLJi0bLO7/yoipAmk1gFZEx9HUJnaoA==}
puppeteer-core@24.2.0:
resolution: {integrity: sha512-e4A4/xqWdd4kcE6QVHYhJ+Qlx/+XpgjP4d8OwBx0DJoY/nkIRhSgYmKQnv7+XSs1ofBstalt+XPGrkaz4FoXOQ==}
engines: {node: '>=18'}
puppeteer@23.0.2:
resolution: {integrity: sha512-I/l1P8s8brcLG+oW9AwF8hUaOSGGJcGKMflXRgULUH0S3ABptlLI9ZKjqWDo8ipY6v789ZKd+bNKtcCwpTh5Ww==}
puppeteer@24.2.0:
resolution: {integrity: sha512-z8vv7zPEgrilIbOo3WNvM+2mXMnyM9f4z6zdrB88Fzeuo43Oupmjrzk3EpuvuCtyK0A7Lsllfx7Z+4BvEEGJcQ==}
engines: {node: '>=18'}
hasBin: true
@ -9311,6 +9330,10 @@ packages:
resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==}
engines: {node: '>= 14'}
socks-proxy-agent@8.0.5:
resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
engines: {node: '>= 14'}
socks@2.8.3:
resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
@ -9599,6 +9622,9 @@ packages:
tar-fs@3.0.6:
resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==}
tar-fs@3.0.8:
resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==}
tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
@ -9855,6 +9881,9 @@ packages:
resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
engines: {node: '>= 0.4'}
typed-query-selector@2.12.0:
resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==}
typescript@5.0.4:
resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
engines: {node: '>=12.20'}
@ -10769,7 +10798,7 @@ snapshots:
'@babel/core': 7.26.0
'@babel/helper-compilation-targets': 7.25.9
'@babel/helper-plugin-utils': 7.25.9
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
lodash.debounce: 4.0.8
resolve: 1.22.8
transitivePeerDependencies:
@ -13281,8 +13310,8 @@ snapshots:
source-map: 0.7.4
webpack: 5.95.0
webpack-sources: 3.2.3
zod: 3.23.8
zod-validation-error: 1.2.0(zod@3.23.8)
zod: 3.24.1
zod-validation-error: 1.2.0(zod@3.24.1)
transitivePeerDependencies:
- '@swc/core'
- '@types/express'
@ -14352,19 +14381,6 @@ snapshots:
dependencies:
spacetrim: 0.11.59
'@puppeteer/browsers@2.3.0':
dependencies:
debug: 4.3.7(supports-color@5.5.0)
extract-zip: 2.0.1
progress: 2.0.3
proxy-agent: 6.4.0
semver: 7.6.3
tar-fs: 3.0.6
unbzip2-stream: 1.4.3
yargs: 17.7.2
transitivePeerDependencies:
- supports-color
'@puppeteer/browsers@2.4.0':
dependencies:
debug: 4.3.7(supports-color@5.5.0)
@ -14378,6 +14394,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@puppeteer/browsers@2.7.1':
dependencies:
debug: 4.4.0
extract-zip: 2.0.1
progress: 2.0.3
proxy-agent: 6.5.0
semver: 7.7.1
tar-fs: 3.0.8
yargs: 17.7.2
transitivePeerDependencies:
- supports-color
'@rc-component/async-validator@5.0.4':
dependencies:
'@babel/runtime': 7.26.0
@ -14642,8 +14670,8 @@ snapshots:
util: 0.12.5
watchpack: 2.4.2
webpack-sources: 3.2.3
zod: 3.23.8
zod-validation-error: 1.2.0(zod@3.23.8)
zod: 3.24.1
zod-validation-error: 1.2.0(zod@3.24.1)
transitivePeerDependencies:
- '@types/webpack'
- sockjs-client
@ -15538,7 +15566,7 @@ snapshots:
agent-base@6.0.2:
dependencies:
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
transitivePeerDependencies:
- supports-color
@ -15548,8 +15576,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
agent-base@7.1.3:
optional: true
agent-base@7.1.3: {}
agentkeepalive@4.5.0:
dependencies:
@ -15894,14 +15921,29 @@ snapshots:
bare-stream: 2.3.2
optional: true
bare-fs@4.0.1:
dependencies:
bare-events: 2.5.0
bare-path: 3.0.0
bare-stream: 2.3.2
optional: true
bare-os@2.4.4:
optional: true
bare-os@3.4.0:
optional: true
bare-path@2.1.3:
dependencies:
bare-os: 2.4.4
optional: true
bare-path@3.0.0:
dependencies:
bare-os: 3.4.0
optional: true
bare-stream@2.3.2:
dependencies:
streamx: 2.20.1
@ -16219,12 +16261,11 @@ snapshots:
chrome-trace-event@1.0.4: {}
chromium-bidi@0.6.4(devtools-protocol@0.0.1312386):
chromium-bidi@1.2.0(devtools-protocol@0.0.1402036):
dependencies:
devtools-protocol: 0.0.1312386
devtools-protocol: 0.0.1402036
mitt: 3.0.1
urlpattern-polyfill: 10.0.0
zod: 3.23.8
zod: 3.24.1
ci-info@3.9.0: {}
@ -16860,10 +16901,10 @@ snapshots:
dependencies:
dequal: 2.0.3
devtools-protocol@0.0.1312386: {}
devtools-protocol@0.0.1380148: {}
devtools-protocol@0.0.1402036: {}
didyoumean@1.2.2: {}
diff-sequences@29.6.3: {}
@ -17499,7 +17540,7 @@ snapshots:
extract-zip@2.0.1:
dependencies:
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
get-stream: 5.2.0
yauzl: 2.10.0
optionalDependencies:
@ -17817,7 +17858,7 @@ snapshots:
dependencies:
basic-ftp: 5.0.5
data-uri-to-buffer: 6.0.2
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
fs-extra: 11.2.0
transitivePeerDependencies:
- supports-color
@ -18276,7 +18317,7 @@ snapshots:
dependencies:
'@tootallnate/once': 2.0.0
agent-base: 6.0.2
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
transitivePeerDependencies:
- supports-color
@ -18330,7 +18371,7 @@ snapshots:
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
transitivePeerDependencies:
- supports-color
@ -18347,7 +18388,6 @@ snapshots:
debug: 4.4.0
transitivePeerDependencies:
- supports-color
optional: true
human-id@1.0.2: {}
@ -19646,7 +19686,7 @@ snapshots:
micromark@3.2.0:
dependencies:
'@types/debug': 4.1.12
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
decode-named-character-reference: 1.0.2
micromark-core-commonmark: 1.1.0
micromark-factory-space: 1.1.0
@ -20118,7 +20158,7 @@ snapshots:
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
agent-base: 7.1.1
debug: 4.3.7(supports-color@5.5.0)
debug: 4.4.0
get-uri: 6.0.3
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.5
@ -20127,6 +20167,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
pac-proxy-agent@7.1.0:
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
agent-base: 7.1.3
debug: 4.4.0
get-uri: 6.0.3
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
pac-resolver: 7.0.1
socks-proxy-agent: 8.0.5
transitivePeerDependencies:
- supports-color
pac-resolver@7.0.1:
dependencies:
degenerator: 5.0.1
@ -20696,6 +20749,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
proxy-agent@6.5.0:
dependencies:
agent-base: 7.1.3
debug: 4.4.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
lru-cache: 7.18.3
pac-proxy-agent: 7.1.0
proxy-from-env: 1.1.0
socks-proxy-agent: 8.0.5
transitivePeerDependencies:
- supports-color
proxy-from-env@1.1.0: {}
pseudomap@1.0.2: {}
@ -20724,25 +20790,27 @@ snapshots:
punycode@2.3.1: {}
puppeteer-core@23.0.2:
puppeteer-core@24.2.0:
dependencies:
'@puppeteer/browsers': 2.3.0
chromium-bidi: 0.6.4(devtools-protocol@0.0.1312386)
debug: 4.3.7(supports-color@5.5.0)
devtools-protocol: 0.0.1312386
'@puppeteer/browsers': 2.7.1
chromium-bidi: 1.2.0(devtools-protocol@0.0.1402036)
debug: 4.4.0
devtools-protocol: 0.0.1402036
typed-query-selector: 2.12.0
ws: 8.18.0
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
puppeteer@23.0.2(typescript@5.0.4):
puppeteer@24.2.0(typescript@5.0.4):
dependencies:
'@puppeteer/browsers': 2.3.0
chromium-bidi: 0.6.4(devtools-protocol@0.0.1312386)
'@puppeteer/browsers': 2.7.1
chromium-bidi: 1.2.0(devtools-protocol@0.0.1402036)
cosmiconfig: 9.0.0(typescript@5.0.4)
devtools-protocol: 0.0.1312386
puppeteer-core: 23.0.2
devtools-protocol: 0.0.1402036
puppeteer-core: 24.2.0
typed-query-selector: 2.12.0
transitivePeerDependencies:
- bufferutil
- supports-color
@ -21994,6 +22062,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
socks-proxy-agent@8.0.5:
dependencies:
agent-base: 7.1.3
debug: 4.4.0
socks: 2.8.3
transitivePeerDependencies:
- supports-color
socks@2.8.3:
dependencies:
ip-address: 9.0.5
@ -22313,6 +22389,14 @@ snapshots:
bare-fs: 2.3.5
bare-path: 2.1.3
tar-fs@3.0.8:
dependencies:
pump: 3.0.2
tar-stream: 3.1.7
optionalDependencies:
bare-fs: 4.0.1
bare-path: 3.0.0
tar-stream@2.2.0:
dependencies:
bl: 4.1.0
@ -22574,6 +22658,8 @@ snapshots:
is-typed-array: 1.1.13
possible-typed-array-names: 1.0.0
typed-query-selector@2.12.0: {}
typescript@5.0.4: {}
typescript@5.6.3: {}
@ -23294,10 +23380,6 @@ snapshots:
dependencies:
zod: 3.23.8
zod-validation-error@1.2.0(zod@3.23.8):
dependencies:
zod: 3.23.8
zod-validation-error@1.2.0(zod@3.24.1):
dependencies:
zod: 3.24.1