@modeloslab/modelcode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -0
- package/SPEC.md +127 -0
- package/agents/code-reviewer.md +49 -0
- package/agents/debugger.md +25 -0
- package/agents/explore.md +22 -0
- package/agents/general-purpose.md +25 -0
- package/agents/plan.md +28 -0
- package/agents/researcher.md +26 -0
- package/agents/security-auditor.md +44 -0
- package/dist/BrowserWebSocketTransport-e6g854ra.mjs +8 -0
- package/dist/LaunchOptions-d24f2e73.mjs +8 -0
- package/dist/NodeWebSocketTransport-s3fsfh3j.mjs +9 -0
- package/dist/bidi-fwqajnyx.mjs +17261 -0
- package/dist/cli.mjs +1669 -0
- package/dist/devtools-fkz8mzpk.mjs +83 -0
- package/dist/fileFromPath-s8scncrt.mjs +128 -0
- package/dist/helpers-667kxskd.mjs +17 -0
- package/dist/index-4706p1xh.mjs +3238 -0
- package/dist/index-gp8nzd9n.mjs +1561 -0
- package/dist/main-0r35eyef.mjs +16229 -0
- package/dist/main-2aqyq9g6.mjs +24239 -0
- package/dist/main-5vqwebnv.mjs +54 -0
- package/dist/main-7f2pnmhh.mjs +2901 -0
- package/dist/main-7jta7ark.mjs +57 -0
- package/dist/main-8y3fe7c3.mjs +48 -0
- package/dist/main-9w13grbs.mjs +41 -0
- package/dist/main-d71btkt1.mjs +2478 -0
- package/dist/main-h8e68gyt.mjs +2819 -0
- package/dist/main-p2xnn95s.mjs +2240 -0
- package/dist/main-qfprs50h.mjs +1629 -0
- package/dist/main-tqg5vhra.mjs +19 -0
- package/dist/puppeteer-core-qdv3v3fq.mjs +1486 -0
- package/dist/tui-0r2q70wm.mjs +23768 -0
- package/package.json +66 -0
- package/skills/commit/SKILL.md +34 -0
- package/skills/debug/SKILL.md +44 -0
- package/skills/docker/SKILL.md +18 -0
- package/skills/init/SKILL.md +36 -0
- package/skills/nextjs-app-router/SKILL.md +16 -0
- package/skills/nextjs-data-fetching/SKILL.md +16 -0
- package/skills/nextjs-env-config/SKILL.md +18 -0
- package/skills/nextjs-metadata-seo/SKILL.md +17 -0
- package/skills/nextjs-middleware/SKILL.md +18 -0
- package/skills/nextjs-performance/SKILL.md +17 -0
- package/skills/nextjs-route-handler/SKILL.md +18 -0
- package/skills/nextjs-server-actions/SKILL.md +17 -0
- package/skills/nextjs-server-components/SKILL.md +18 -0
- package/skills/power-ui/SKILL.md +40 -0
- package/skills/pr/SKILL.md +38 -0
- package/skills/refactor/SKILL.md +40 -0
- package/skills/remember/SKILL.md +39 -0
- package/skills/review/SKILL.md +22 -0
- package/skills/security-review/SKILL.md +21 -0
- package/skills/simplify/SKILL.md +47 -0
- package/skills/skill-create/SKILL.md +37 -0
- package/skills/test/SKILL.md +34 -0
- package/skills/vercel-deploy/SKILL.md +16 -0
|
@@ -0,0 +1,1486 @@
|
|
|
1
|
+
import {
|
|
2
|
+
convertPuppeteerChannelToBrowsersChannel
|
|
3
|
+
} from "./main-tqg5vhra.mjs";
|
|
4
|
+
import {
|
|
5
|
+
Browser as Browser2,
|
|
6
|
+
CDP_WEBSOCKET_ENDPOINT_REGEX,
|
|
7
|
+
TimeoutError as TimeoutError2,
|
|
8
|
+
WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX,
|
|
9
|
+
computeExecutablePath,
|
|
10
|
+
computeSystemExecutablePath,
|
|
11
|
+
createProfile,
|
|
12
|
+
detectBrowserPlatform,
|
|
13
|
+
getInstalledBrowsers,
|
|
14
|
+
launch,
|
|
15
|
+
resolveBuildId,
|
|
16
|
+
uninstall
|
|
17
|
+
} from "./main-d71btkt1.mjs";
|
|
18
|
+
import {
|
|
19
|
+
ARIAQueryHandler,
|
|
20
|
+
Accessibility,
|
|
21
|
+
AsyncDisposableStack,
|
|
22
|
+
AsyncDisposableStackPolyfill,
|
|
23
|
+
AsyncIterableUtil,
|
|
24
|
+
Binding,
|
|
25
|
+
Browser,
|
|
26
|
+
BrowserContext,
|
|
27
|
+
CDPSession,
|
|
28
|
+
CDPSessionEvent,
|
|
29
|
+
CDP_BINDING_PREFIX,
|
|
30
|
+
CSSCoverage,
|
|
31
|
+
Callback,
|
|
32
|
+
CallbackRegistry,
|
|
33
|
+
CdpBluetoothEmulation,
|
|
34
|
+
CdpBrowser,
|
|
35
|
+
CdpBrowserContext,
|
|
36
|
+
CdpCDPSession,
|
|
37
|
+
CdpDeviceRequestPrompt,
|
|
38
|
+
CdpDeviceRequestPromptManager,
|
|
39
|
+
CdpDialog,
|
|
40
|
+
CdpElementHandle,
|
|
41
|
+
CdpFrame,
|
|
42
|
+
CdpHTTPRequest,
|
|
43
|
+
CdpHTTPResponse,
|
|
44
|
+
CdpJSHandle,
|
|
45
|
+
CdpKeyboard,
|
|
46
|
+
CdpMouse,
|
|
47
|
+
CdpPage,
|
|
48
|
+
CdpPreloadScript,
|
|
49
|
+
CdpTarget,
|
|
50
|
+
CdpTouchHandle,
|
|
51
|
+
CdpTouchscreen,
|
|
52
|
+
CdpWebWorker,
|
|
53
|
+
Connection,
|
|
54
|
+
ConsoleMessage,
|
|
55
|
+
Coverage,
|
|
56
|
+
CustomQueryHandlerRegistry,
|
|
57
|
+
DEFAULT_INTERCEPT_RESOLUTION_PRIORITY,
|
|
58
|
+
Deferred,
|
|
59
|
+
DelegatedLocator,
|
|
60
|
+
DevToolsTarget,
|
|
61
|
+
DeviceRequestPrompt,
|
|
62
|
+
Dialog,
|
|
63
|
+
DisposableStack,
|
|
64
|
+
DisposableStackPolyfill,
|
|
65
|
+
ElementHandle,
|
|
66
|
+
EmulatedState,
|
|
67
|
+
EmulationManager,
|
|
68
|
+
EventEmitter,
|
|
69
|
+
ExecutionContext,
|
|
70
|
+
Extension,
|
|
71
|
+
ExtensionTransport,
|
|
72
|
+
FileChooser,
|
|
73
|
+
FilteredLocator,
|
|
74
|
+
Frame,
|
|
75
|
+
FrameEvent,
|
|
76
|
+
FrameManager,
|
|
77
|
+
FrameManagerEvent,
|
|
78
|
+
FrameTree,
|
|
79
|
+
FunctionLocator,
|
|
80
|
+
HTTPRequest,
|
|
81
|
+
HTTPResponse,
|
|
82
|
+
InitializationStatus,
|
|
83
|
+
InterceptResolutionAction,
|
|
84
|
+
IsolatedWorld,
|
|
85
|
+
JSCoverage,
|
|
86
|
+
JSHandle,
|
|
87
|
+
Keyboard,
|
|
88
|
+
KnownDevices,
|
|
89
|
+
LazyArg,
|
|
90
|
+
LifecycleWatcher,
|
|
91
|
+
Locator,
|
|
92
|
+
LocatorEvent,
|
|
93
|
+
MAIN_WORLD,
|
|
94
|
+
MappedLocator,
|
|
95
|
+
Mouse,
|
|
96
|
+
MouseButton,
|
|
97
|
+
Mutex,
|
|
98
|
+
NetworkEventManager,
|
|
99
|
+
NetworkManager,
|
|
100
|
+
NetworkManagerEvent,
|
|
101
|
+
NodeLocator,
|
|
102
|
+
OtherTarget,
|
|
103
|
+
PQueryHandler,
|
|
104
|
+
PUPPETEER_REVISIONS,
|
|
105
|
+
PUPPETEER_WORLD,
|
|
106
|
+
Page,
|
|
107
|
+
PageTarget,
|
|
108
|
+
PierceQueryHandler,
|
|
109
|
+
PredefinedNetworkConditions,
|
|
110
|
+
Puppeteer,
|
|
111
|
+
QueryHandler,
|
|
112
|
+
RETRY_DELAY,
|
|
113
|
+
RaceLocator,
|
|
114
|
+
Realm,
|
|
115
|
+
STATUS_TEXTS,
|
|
116
|
+
ScriptInjector,
|
|
117
|
+
SecurityDetails,
|
|
118
|
+
SuppressedError,
|
|
119
|
+
Target,
|
|
120
|
+
TargetManager,
|
|
121
|
+
TargetType,
|
|
122
|
+
TaskManager,
|
|
123
|
+
TaskQueue,
|
|
124
|
+
TextQueryHandler,
|
|
125
|
+
TimeoutSettings,
|
|
126
|
+
Touchscreen,
|
|
127
|
+
Tracing,
|
|
128
|
+
WEB_PERMISSION_TO_PROTOCOL_PERMISSION,
|
|
129
|
+
WaitTask,
|
|
130
|
+
WebMCP,
|
|
131
|
+
WebMCPTool,
|
|
132
|
+
WebMCPToolCall,
|
|
133
|
+
WebWorker,
|
|
134
|
+
WebWorkerEvent,
|
|
135
|
+
WorkerTarget,
|
|
136
|
+
XPathQueryHandler,
|
|
137
|
+
_connectToCdpBrowser,
|
|
138
|
+
_keyDefinitions,
|
|
139
|
+
addPageBinding,
|
|
140
|
+
assertSupportedUrlRestrictions,
|
|
141
|
+
asyncDisposeSymbol,
|
|
142
|
+
bindIsolatedHandle,
|
|
143
|
+
convertConsoleMessageLevel,
|
|
144
|
+
convertCookiesPartitionKeyFromPuppeteerToCdp,
|
|
145
|
+
convertSameSiteFromPuppeteerToCdp,
|
|
146
|
+
createClientError,
|
|
147
|
+
createConsoleMessage,
|
|
148
|
+
createEvaluationError,
|
|
149
|
+
createIncrementalIdGenerator,
|
|
150
|
+
createProtocolErrorMessage,
|
|
151
|
+
customQueryHandlers,
|
|
152
|
+
disposeSymbol,
|
|
153
|
+
getQueryHandlerAndSelector,
|
|
154
|
+
guarded,
|
|
155
|
+
handleError,
|
|
156
|
+
headersArray,
|
|
157
|
+
isErrnoException,
|
|
158
|
+
isErrorLike,
|
|
159
|
+
isTargetClosedError,
|
|
160
|
+
normalizeHeaderValue,
|
|
161
|
+
pageBindingInitString,
|
|
162
|
+
parsePSelectors,
|
|
163
|
+
referrerPolicyToProtocol,
|
|
164
|
+
releaseObject,
|
|
165
|
+
rewriteError,
|
|
166
|
+
scriptInjector,
|
|
167
|
+
setDefaultScreenshotOptions,
|
|
168
|
+
supportedMetrics,
|
|
169
|
+
throwIfDetached,
|
|
170
|
+
transposeIterableHandle,
|
|
171
|
+
valueFromJSHandle,
|
|
172
|
+
valueFromPrimitiveRemoteObject,
|
|
173
|
+
valueFromRemoteObjectReference
|
|
174
|
+
} from "./main-0r35eyef.mjs";
|
|
175
|
+
import {
|
|
176
|
+
NodeWebSocketTransport
|
|
177
|
+
} from "./main-5vqwebnv.mjs";
|
|
178
|
+
import"./main-7f2pnmhh.mjs";
|
|
179
|
+
import {
|
|
180
|
+
BrowserWebSocketTransport
|
|
181
|
+
} from "./main-9w13grbs.mjs";
|
|
182
|
+
import {
|
|
183
|
+
ConnectionClosedError,
|
|
184
|
+
DEFAULT_VIEWPORT,
|
|
185
|
+
NETWORK_IDLE_TIME,
|
|
186
|
+
ProtocolError,
|
|
187
|
+
PuppeteerError,
|
|
188
|
+
PuppeteerURL,
|
|
189
|
+
SOURCE_URL_REGEX,
|
|
190
|
+
TargetCloseError,
|
|
191
|
+
TimeoutError,
|
|
192
|
+
TouchError,
|
|
193
|
+
UTILITY_WORLD_NAME,
|
|
194
|
+
UnsupportedOperation,
|
|
195
|
+
assert,
|
|
196
|
+
bufferCount,
|
|
197
|
+
concatMap,
|
|
198
|
+
debug,
|
|
199
|
+
debugError,
|
|
200
|
+
environment,
|
|
201
|
+
evaluationString,
|
|
202
|
+
filter,
|
|
203
|
+
filterAsync,
|
|
204
|
+
firstValueFrom,
|
|
205
|
+
from,
|
|
206
|
+
fromAbortSignal,
|
|
207
|
+
fromEmitterEvent,
|
|
208
|
+
fromEvent,
|
|
209
|
+
getCapturedLogs,
|
|
210
|
+
getReadableAsTypedArray,
|
|
211
|
+
getReadableFromProtocolStream,
|
|
212
|
+
getSourcePuppeteerURLIfAvailable,
|
|
213
|
+
getSourceUrlComment,
|
|
214
|
+
importDebug,
|
|
215
|
+
isDate,
|
|
216
|
+
isNumber,
|
|
217
|
+
isPlainObject,
|
|
218
|
+
isRegExp,
|
|
219
|
+
isString,
|
|
220
|
+
lastValueFrom,
|
|
221
|
+
map,
|
|
222
|
+
paperFormats,
|
|
223
|
+
parsePDFOptions,
|
|
224
|
+
race,
|
|
225
|
+
setLogCapture,
|
|
226
|
+
takeUntil,
|
|
227
|
+
tap,
|
|
228
|
+
timeout,
|
|
229
|
+
timer,
|
|
230
|
+
unitToPixels,
|
|
231
|
+
validateDialogType,
|
|
232
|
+
withSourcePuppeteerURLIfNone
|
|
233
|
+
} from "./main-h8e68gyt.mjs";
|
|
234
|
+
import {
|
|
235
|
+
__require
|
|
236
|
+
} from "./main-8y3fe7c3.mjs";
|
|
237
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/ChromeLauncher.js
|
|
238
|
+
import { mkdtemp } from "node:fs/promises";
|
|
239
|
+
import os from "node:os";
|
|
240
|
+
import path from "node:path";
|
|
241
|
+
|
|
242
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/BrowserLauncher.js
|
|
243
|
+
import { existsSync } from "node:fs";
|
|
244
|
+
import { tmpdir } from "node:os";
|
|
245
|
+
import { join } from "node:path";
|
|
246
|
+
|
|
247
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/PipeTransport.js
|
|
248
|
+
class PipeTransport {
|
|
249
|
+
#pipeWrite;
|
|
250
|
+
#subscriptions = new DisposableStack;
|
|
251
|
+
#isClosed = false;
|
|
252
|
+
#pendingMessage = [];
|
|
253
|
+
onclose;
|
|
254
|
+
onmessage;
|
|
255
|
+
constructor(pipeWrite, pipeRead) {
|
|
256
|
+
this.#pipeWrite = pipeWrite;
|
|
257
|
+
const pipeReadEmitter = this.#subscriptions.use(new EventEmitter(pipeRead));
|
|
258
|
+
pipeReadEmitter.on("data", (buffer) => {
|
|
259
|
+
return this.#dispatch(buffer);
|
|
260
|
+
});
|
|
261
|
+
pipeReadEmitter.on("close", () => {
|
|
262
|
+
if (this.onclose) {
|
|
263
|
+
this.onclose.call(null);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
pipeReadEmitter.on("error", debugError);
|
|
267
|
+
const pipeWriteEmitter = this.#subscriptions.use(new EventEmitter(pipeWrite));
|
|
268
|
+
pipeWriteEmitter.on("error", debugError);
|
|
269
|
+
}
|
|
270
|
+
send(message) {
|
|
271
|
+
assert(!this.#isClosed, "`PipeTransport` is closed.");
|
|
272
|
+
this.#pipeWrite.write(message);
|
|
273
|
+
this.#pipeWrite.write("\x00");
|
|
274
|
+
}
|
|
275
|
+
#dispatch(buffer) {
|
|
276
|
+
assert(!this.#isClosed, "`PipeTransport` is closed.");
|
|
277
|
+
this.#pendingMessage.push(buffer);
|
|
278
|
+
if (buffer.indexOf("\x00") === -1) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const concatBuffer = Buffer.concat(this.#pendingMessage);
|
|
282
|
+
let start = 0;
|
|
283
|
+
let end = concatBuffer.indexOf("\x00");
|
|
284
|
+
while (end !== -1) {
|
|
285
|
+
const message = concatBuffer.toString(undefined, start, end);
|
|
286
|
+
setImmediate(() => {
|
|
287
|
+
if (this.onmessage) {
|
|
288
|
+
this.onmessage.call(null, message);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
start = end + 1;
|
|
292
|
+
end = concatBuffer.indexOf("\x00", start);
|
|
293
|
+
}
|
|
294
|
+
if (start >= concatBuffer.length) {
|
|
295
|
+
this.#pendingMessage = [];
|
|
296
|
+
} else {
|
|
297
|
+
this.#pendingMessage = [concatBuffer.subarray(start)];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
close() {
|
|
301
|
+
this.#isClosed = true;
|
|
302
|
+
this.#subscriptions.dispose();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/BrowserLauncher.js
|
|
307
|
+
class BrowserLauncher {
|
|
308
|
+
#browser;
|
|
309
|
+
puppeteer;
|
|
310
|
+
constructor(puppeteer, browser) {
|
|
311
|
+
this.puppeteer = puppeteer;
|
|
312
|
+
this.#browser = browser;
|
|
313
|
+
}
|
|
314
|
+
get browser() {
|
|
315
|
+
return this.#browser;
|
|
316
|
+
}
|
|
317
|
+
async launch(options = {}) {
|
|
318
|
+
const { dumpio = false, enableExtensions = false, env = process.env, handleSIGINT = true, handleSIGTERM = true, handleSIGHUP = true, acceptInsecureCerts = false, networkEnabled = true, issuesEnabled = true, defaultViewport = DEFAULT_VIEWPORT, downloadBehavior, slowMo = 0, timeout: timeout2 = 30000, waitForInitialPage = true, protocolTimeout, handleDevToolsAsPage, idGenerator = createIncrementalIdGenerator(), blocklist, allowlist } = options;
|
|
319
|
+
let { protocol } = options;
|
|
320
|
+
if (this.#browser === "firefox" && protocol === undefined) {
|
|
321
|
+
protocol = "webDriverBiDi";
|
|
322
|
+
}
|
|
323
|
+
assertSupportedUrlRestrictions({
|
|
324
|
+
allowlist,
|
|
325
|
+
blocklist,
|
|
326
|
+
protocol
|
|
327
|
+
});
|
|
328
|
+
if (this.#browser === "firefox" && protocol === "cdp") {
|
|
329
|
+
throw new Error("Connecting to Firefox using CDP is no longer supported");
|
|
330
|
+
}
|
|
331
|
+
const launchArgs = await this.computeLaunchArguments({
|
|
332
|
+
...options,
|
|
333
|
+
protocol
|
|
334
|
+
});
|
|
335
|
+
if (!existsSync(launchArgs.executablePath)) {
|
|
336
|
+
throw new Error(`Browser was not found at the configured executablePath (${launchArgs.executablePath})`);
|
|
337
|
+
}
|
|
338
|
+
const usePipe = launchArgs.args.includes("--remote-debugging-pipe");
|
|
339
|
+
const onProcessExit = async () => {
|
|
340
|
+
await this.cleanUserDataDir(launchArgs.userDataDir, {
|
|
341
|
+
isTemp: launchArgs.isTempUserDataDir
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
if (this.#browser === "firefox" && protocol === "webDriverBiDi" && usePipe) {
|
|
345
|
+
throw new Error("Pipe connections are not supported with Firefox and WebDriver BiDi");
|
|
346
|
+
}
|
|
347
|
+
const browserProcess = launch({
|
|
348
|
+
executablePath: launchArgs.executablePath,
|
|
349
|
+
args: launchArgs.args,
|
|
350
|
+
handleSIGHUP,
|
|
351
|
+
handleSIGTERM,
|
|
352
|
+
handleSIGINT,
|
|
353
|
+
dumpio,
|
|
354
|
+
env,
|
|
355
|
+
pipe: usePipe,
|
|
356
|
+
onExit: onProcessExit,
|
|
357
|
+
signal: options.signal
|
|
358
|
+
});
|
|
359
|
+
let browser;
|
|
360
|
+
let cdpConnection;
|
|
361
|
+
let closing = false;
|
|
362
|
+
const browserCloseCallback = async () => {
|
|
363
|
+
if (closing) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
closing = true;
|
|
367
|
+
await this.closeBrowser(browserProcess, cdpConnection);
|
|
368
|
+
};
|
|
369
|
+
try {
|
|
370
|
+
if (this.#browser === "firefox") {
|
|
371
|
+
browser = await this.createBiDiBrowser(browserProcess, browserCloseCallback, {
|
|
372
|
+
timeout: timeout2,
|
|
373
|
+
protocolTimeout,
|
|
374
|
+
slowMo,
|
|
375
|
+
defaultViewport,
|
|
376
|
+
acceptInsecureCerts,
|
|
377
|
+
networkEnabled,
|
|
378
|
+
idGenerator
|
|
379
|
+
});
|
|
380
|
+
} else {
|
|
381
|
+
if (usePipe) {
|
|
382
|
+
cdpConnection = await this.createCdpPipeConnection(browserProcess, {
|
|
383
|
+
timeout: timeout2,
|
|
384
|
+
protocolTimeout,
|
|
385
|
+
slowMo,
|
|
386
|
+
idGenerator
|
|
387
|
+
});
|
|
388
|
+
} else {
|
|
389
|
+
cdpConnection = await this.createCdpSocketConnection(browserProcess, {
|
|
390
|
+
timeout: timeout2,
|
|
391
|
+
protocolTimeout,
|
|
392
|
+
slowMo,
|
|
393
|
+
idGenerator
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
if (protocol === "webDriverBiDi") {
|
|
397
|
+
browser = await this.createBiDiOverCdpBrowser(browserProcess, cdpConnection, browserCloseCallback, {
|
|
398
|
+
defaultViewport,
|
|
399
|
+
acceptInsecureCerts,
|
|
400
|
+
networkEnabled,
|
|
401
|
+
issuesEnabled
|
|
402
|
+
});
|
|
403
|
+
} else {
|
|
404
|
+
browser = await CdpBrowser._create(cdpConnection, [], acceptInsecureCerts, defaultViewport, downloadBehavior, browserProcess.nodeProcess, browserCloseCallback, options.targetFilter, undefined, undefined, networkEnabled, issuesEnabled, handleDevToolsAsPage, blocklist, allowlist);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
} catch (error) {
|
|
408
|
+
browserCloseCallback();
|
|
409
|
+
const logs = browserProcess.getRecentLogs().join(`
|
|
410
|
+
`);
|
|
411
|
+
if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync(join(launchArgs.userDataDir, "lockfile"))) {
|
|
412
|
+
throw new Error(`The browser is already running for ${launchArgs.userDataDir}. Use a different \`userDataDir\` or stop the running browser first.`);
|
|
413
|
+
}
|
|
414
|
+
if (logs.includes("Missing X server") && options.headless === false) {
|
|
415
|
+
throw new Error(`Missing X server to start the headful browser. Either set headless to true or use xvfb-run to run your Puppeteer script.`);
|
|
416
|
+
}
|
|
417
|
+
if (error instanceof TimeoutError2) {
|
|
418
|
+
throw new TimeoutError(error.message);
|
|
419
|
+
}
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
422
|
+
if (Array.isArray(enableExtensions)) {
|
|
423
|
+
if (this.#browser === "chrome" && !usePipe) {
|
|
424
|
+
throw new Error("To use `enableExtensions` with a list of paths in Chrome, you must be connected with `--remote-debugging-pipe` (`pipe: true`).");
|
|
425
|
+
}
|
|
426
|
+
await Promise.all([
|
|
427
|
+
enableExtensions.map((path) => {
|
|
428
|
+
return browser.installExtension(path);
|
|
429
|
+
})
|
|
430
|
+
]);
|
|
431
|
+
}
|
|
432
|
+
if (waitForInitialPage) {
|
|
433
|
+
await this.waitForPageTarget(browser, timeout2);
|
|
434
|
+
}
|
|
435
|
+
return browser;
|
|
436
|
+
}
|
|
437
|
+
async closeBrowser(browserProcess, cdpConnection) {
|
|
438
|
+
if (cdpConnection) {
|
|
439
|
+
try {
|
|
440
|
+
await cdpConnection.closeBrowser();
|
|
441
|
+
await browserProcess.hasClosed();
|
|
442
|
+
} catch (error) {
|
|
443
|
+
debugError(error);
|
|
444
|
+
await browserProcess.close();
|
|
445
|
+
}
|
|
446
|
+
} else {
|
|
447
|
+
await firstValueFrom(race(from(browserProcess.hasClosed()), timer(5000).pipe(map(() => {
|
|
448
|
+
return from(browserProcess.close());
|
|
449
|
+
}))));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
async waitForPageTarget(browser, timeout2) {
|
|
453
|
+
try {
|
|
454
|
+
await browser.waitForTarget((t) => {
|
|
455
|
+
return t.type() === "page";
|
|
456
|
+
}, { timeout: timeout2 });
|
|
457
|
+
} catch (error) {
|
|
458
|
+
await browser.close();
|
|
459
|
+
throw error;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
async createCdpSocketConnection(browserProcess, opts) {
|
|
463
|
+
const browserWSEndpoint = await browserProcess.waitForLineOutput(CDP_WEBSOCKET_ENDPOINT_REGEX, opts.timeout);
|
|
464
|
+
const transport = await NodeWebSocketTransport.create(browserWSEndpoint);
|
|
465
|
+
return new Connection(browserWSEndpoint, transport, opts.slowMo, opts.protocolTimeout, false, opts.idGenerator);
|
|
466
|
+
}
|
|
467
|
+
async createCdpPipeConnection(browserProcess, opts) {
|
|
468
|
+
const { 3: pipeWrite, 4: pipeRead } = browserProcess.nodeProcess.stdio;
|
|
469
|
+
const transport = new PipeTransport(pipeWrite, pipeRead);
|
|
470
|
+
return new Connection("", transport, opts.slowMo, opts.protocolTimeout, false, opts.idGenerator);
|
|
471
|
+
}
|
|
472
|
+
async createBiDiOverCdpBrowser(browserProcess, cdpConnection, closeCallback, opts) {
|
|
473
|
+
const bidiOnly = process.env["PUPPETEER_WEBDRIVER_BIDI_ONLY"] === "true";
|
|
474
|
+
const BiDi = await import("./bidi-fwqajnyx.mjs");
|
|
475
|
+
const bidiConnection = await BiDi.connectBidiOverCdp(cdpConnection);
|
|
476
|
+
return await BiDi.BidiBrowser.create({
|
|
477
|
+
connection: bidiConnection,
|
|
478
|
+
cdpConnection: bidiOnly ? undefined : cdpConnection,
|
|
479
|
+
closeCallback,
|
|
480
|
+
process: browserProcess.nodeProcess,
|
|
481
|
+
defaultViewport: opts.defaultViewport,
|
|
482
|
+
acceptInsecureCerts: opts.acceptInsecureCerts,
|
|
483
|
+
networkEnabled: opts.networkEnabled,
|
|
484
|
+
issuesEnabled: opts.issuesEnabled
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
async createBiDiBrowser(browserProcess, closeCallback, opts) {
|
|
488
|
+
const browserWSEndpoint = await browserProcess.waitForLineOutput(WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX, opts.timeout) + "/session";
|
|
489
|
+
const transport = await NodeWebSocketTransport.create(browserWSEndpoint);
|
|
490
|
+
const BiDi = await import("./bidi-fwqajnyx.mjs");
|
|
491
|
+
const bidiConnection = new BiDi.BidiConnection(browserWSEndpoint, transport, opts.idGenerator, opts.slowMo, opts.protocolTimeout);
|
|
492
|
+
return await BiDi.BidiBrowser.create({
|
|
493
|
+
connection: bidiConnection,
|
|
494
|
+
closeCallback,
|
|
495
|
+
process: browserProcess.nodeProcess,
|
|
496
|
+
defaultViewport: opts.defaultViewport,
|
|
497
|
+
acceptInsecureCerts: opts.acceptInsecureCerts,
|
|
498
|
+
networkEnabled: opts.networkEnabled ?? true,
|
|
499
|
+
issuesEnabled: opts.issuesEnabled ?? true
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
async getProfilePath() {
|
|
503
|
+
const config = await this.puppeteer.configuration();
|
|
504
|
+
return join(config.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
|
|
505
|
+
}
|
|
506
|
+
async resolveExecutablePath(headless, validatePath = true) {
|
|
507
|
+
const config = await this.puppeteer.configuration();
|
|
508
|
+
let executablePath = config.executablePath;
|
|
509
|
+
if (executablePath) {
|
|
510
|
+
if (validatePath && !existsSync(executablePath)) {
|
|
511
|
+
throw new Error(`Tried to find the browser at the configured path (${executablePath}), but no executable was found.`);
|
|
512
|
+
}
|
|
513
|
+
return executablePath;
|
|
514
|
+
}
|
|
515
|
+
function puppeteerBrowserToInstalledBrowser(browser, headless2) {
|
|
516
|
+
switch (browser) {
|
|
517
|
+
case "chrome":
|
|
518
|
+
if (headless2 === "shell") {
|
|
519
|
+
return Browser2.CHROMEHEADLESSSHELL;
|
|
520
|
+
}
|
|
521
|
+
return Browser2.CHROME;
|
|
522
|
+
case "firefox":
|
|
523
|
+
return Browser2.FIREFOX;
|
|
524
|
+
}
|
|
525
|
+
return Browser2.CHROME;
|
|
526
|
+
}
|
|
527
|
+
const browserType = puppeteerBrowserToInstalledBrowser(this.browser, headless);
|
|
528
|
+
const defaultDownloadPath = await this.puppeteer.defaultDownloadPath();
|
|
529
|
+
const browserVersion = await this.puppeteer.browserVersion();
|
|
530
|
+
executablePath = computeExecutablePath({
|
|
531
|
+
cacheDir: defaultDownloadPath,
|
|
532
|
+
browser: browserType,
|
|
533
|
+
buildId: browserVersion
|
|
534
|
+
});
|
|
535
|
+
if (validatePath && !existsSync(executablePath)) {
|
|
536
|
+
const configVersion = config?.[this.browser]?.version;
|
|
537
|
+
if (configVersion) {
|
|
538
|
+
throw new Error(`Tried to find the browser at the configured path (${executablePath}) for version ${configVersion}, but no executable was found.`);
|
|
539
|
+
}
|
|
540
|
+
switch (this.browser) {
|
|
541
|
+
case "chrome":
|
|
542
|
+
throw new Error(`Could not find Chrome (ver. ${browserVersion}). This can occur if either
|
|
543
|
+
1. you did not perform an installation before running the script (e.g. \`npx puppeteer browsers install ${browserType}\`) or
|
|
544
|
+
2. your cache path is incorrectly configured (which is: ${config.cacheDirectory}).
|
|
545
|
+
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.`);
|
|
546
|
+
case "firefox":
|
|
547
|
+
throw new Error(`Could not find Firefox (rev. ${browserVersion}). This can occur if either
|
|
548
|
+
1. you did not perform an installation for Firefox before running the script (e.g. \`npx puppeteer browsers install firefox\`) or
|
|
549
|
+
2. your cache path is incorrectly configured (which is: ${config.cacheDirectory}).
|
|
550
|
+
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
return executablePath;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/util/fs.js
|
|
558
|
+
import fs from "node:fs";
|
|
559
|
+
var rmOptions = {
|
|
560
|
+
force: true,
|
|
561
|
+
recursive: true,
|
|
562
|
+
maxRetries: 5
|
|
563
|
+
};
|
|
564
|
+
async function rm(path) {
|
|
565
|
+
await fs.promises.rm(path, rmOptions);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/ChromeLauncher.js
|
|
569
|
+
class ChromeLauncher extends BrowserLauncher {
|
|
570
|
+
constructor(puppeteer) {
|
|
571
|
+
super(puppeteer, "chrome");
|
|
572
|
+
}
|
|
573
|
+
async launch(options = {}) {
|
|
574
|
+
const config = await this.puppeteer.configuration();
|
|
575
|
+
if (config.logLevel === "warn" && process.platform === "darwin" && process.arch === "x64") {
|
|
576
|
+
const cpus = os.cpus();
|
|
577
|
+
if (cpus[0]?.model.includes("Apple")) {
|
|
578
|
+
console.warn([
|
|
579
|
+
"\x1B[1m\x1B[43m\x1B[30m",
|
|
580
|
+
"Degraded performance warning:\x1B[0m\x1B[33m",
|
|
581
|
+
"Launching Chrome on Mac Silicon (arm64) from an x64 Node installation results in",
|
|
582
|
+
"Rosetta translating the Chrome binary, even if Chrome is already arm64. This would",
|
|
583
|
+
"result in huge performance issues. To resolve this, you must run Puppeteer with",
|
|
584
|
+
"a version of Node built for arm64."
|
|
585
|
+
].join(`
|
|
586
|
+
`));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return await super.launch(options);
|
|
590
|
+
}
|
|
591
|
+
async computeLaunchArguments(options = {}) {
|
|
592
|
+
const { ignoreDefaultArgs = false, args = [], pipe = false, debuggingPort, channel, executablePath } = options;
|
|
593
|
+
const chromeArguments = [];
|
|
594
|
+
if (!ignoreDefaultArgs) {
|
|
595
|
+
chromeArguments.push(...this.defaultArgs(options));
|
|
596
|
+
} else if (Array.isArray(ignoreDefaultArgs)) {
|
|
597
|
+
chromeArguments.push(...this.defaultArgs(options).filter((arg) => {
|
|
598
|
+
return !ignoreDefaultArgs.includes(arg);
|
|
599
|
+
}));
|
|
600
|
+
} else {
|
|
601
|
+
chromeArguments.push(...args);
|
|
602
|
+
}
|
|
603
|
+
if (!chromeArguments.some((argument) => {
|
|
604
|
+
return argument.startsWith("--remote-debugging-");
|
|
605
|
+
})) {
|
|
606
|
+
if (pipe) {
|
|
607
|
+
assert(!debuggingPort, "Browser should be launched with either pipe or debugging port - not both.");
|
|
608
|
+
chromeArguments.push("--remote-debugging-pipe");
|
|
609
|
+
} else {
|
|
610
|
+
chromeArguments.push(`--remote-debugging-port=${debuggingPort || 0}`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
let isTempUserDataDir = false;
|
|
614
|
+
let userDataDirIndex = chromeArguments.findIndex((arg) => {
|
|
615
|
+
return arg.startsWith("--user-data-dir");
|
|
616
|
+
});
|
|
617
|
+
if (userDataDirIndex < 0) {
|
|
618
|
+
isTempUserDataDir = true;
|
|
619
|
+
chromeArguments.push(`--user-data-dir=${await mkdtemp(await this.getProfilePath())}`);
|
|
620
|
+
userDataDirIndex = chromeArguments.length - 1;
|
|
621
|
+
}
|
|
622
|
+
const userDataDir = chromeArguments[userDataDirIndex].split("=", 2)[1];
|
|
623
|
+
assert(typeof userDataDir === "string", "`--user-data-dir` is malformed");
|
|
624
|
+
let chromeExecutable = executablePath;
|
|
625
|
+
if (!chromeExecutable) {
|
|
626
|
+
assert(channel || !this.puppeteer._isPuppeteerCore, `An \`executablePath\` or \`channel\` must be specified for \`puppeteer-core\``);
|
|
627
|
+
chromeExecutable = channel ? await this.executablePath(channel) : await this.resolveExecutablePath(options.headless ?? true);
|
|
628
|
+
}
|
|
629
|
+
return {
|
|
630
|
+
executablePath: chromeExecutable,
|
|
631
|
+
args: chromeArguments,
|
|
632
|
+
isTempUserDataDir,
|
|
633
|
+
userDataDir
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
async cleanUserDataDir(path2, opts) {
|
|
637
|
+
if (opts.isTemp) {
|
|
638
|
+
try {
|
|
639
|
+
await rm(path2);
|
|
640
|
+
} catch (error) {
|
|
641
|
+
debugError(error);
|
|
642
|
+
throw error;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
defaultArgs(options = {}) {
|
|
647
|
+
const userDisabledFeatures = getFeatures("--disable-features", options.args);
|
|
648
|
+
if (options.args && userDisabledFeatures.length > 0) {
|
|
649
|
+
removeMatchingFlags(options.args, "--disable-features");
|
|
650
|
+
}
|
|
651
|
+
const turnOnExperimentalFeaturesForTesting = process.env["PUPPETEER_TEST_EXPERIMENTAL_CHROME_FEATURES"] === "true";
|
|
652
|
+
const userEnabledFeatures = getFeatures("--enable-features", options.args);
|
|
653
|
+
if (options.args && userEnabledFeatures.length > 0) {
|
|
654
|
+
removeMatchingFlags(options.args, "--enable-features");
|
|
655
|
+
}
|
|
656
|
+
const enabledFeatures = [
|
|
657
|
+
"PdfOopif",
|
|
658
|
+
...userEnabledFeatures
|
|
659
|
+
].filter((feature) => {
|
|
660
|
+
return feature !== "";
|
|
661
|
+
});
|
|
662
|
+
const disabledFeatures = [
|
|
663
|
+
"Translate",
|
|
664
|
+
"AcceptCHFrame",
|
|
665
|
+
"MediaRouter",
|
|
666
|
+
"OptimizationHints",
|
|
667
|
+
"WebUIReloadButton",
|
|
668
|
+
...turnOnExperimentalFeaturesForTesting ? [] : [
|
|
669
|
+
"ProcessPerSiteUpToMainFrameThreshold",
|
|
670
|
+
"IsolateSandboxedIframes"
|
|
671
|
+
],
|
|
672
|
+
...userDisabledFeatures
|
|
673
|
+
].filter((feature) => {
|
|
674
|
+
return feature !== "";
|
|
675
|
+
}).filter((disabledFeature) => {
|
|
676
|
+
return !enabledFeatures.includes(disabledFeature);
|
|
677
|
+
});
|
|
678
|
+
const chromeArguments = [
|
|
679
|
+
"--allow-pre-commit-input",
|
|
680
|
+
"--disable-background-networking",
|
|
681
|
+
"--disable-background-timer-throttling",
|
|
682
|
+
"--disable-backgrounding-occluded-windows",
|
|
683
|
+
"--disable-breakpad",
|
|
684
|
+
"--disable-client-side-phishing-detection",
|
|
685
|
+
"--disable-component-extensions-with-background-pages",
|
|
686
|
+
"--disable-crash-reporter",
|
|
687
|
+
"--disable-default-apps",
|
|
688
|
+
"--disable-dev-shm-usage",
|
|
689
|
+
"--disable-hang-monitor",
|
|
690
|
+
"--disable-infobars",
|
|
691
|
+
"--disable-ipc-flooding-protection",
|
|
692
|
+
"--disable-popup-blocking",
|
|
693
|
+
"--disable-prompt-on-repost",
|
|
694
|
+
"--disable-renderer-backgrounding",
|
|
695
|
+
"--disable-search-engine-choice-screen",
|
|
696
|
+
"--disable-sync",
|
|
697
|
+
"--enable-automation",
|
|
698
|
+
"--export-tagged-pdf",
|
|
699
|
+
"--force-color-profile=srgb",
|
|
700
|
+
"--generate-pdf-document-outline",
|
|
701
|
+
"--metrics-recording-only",
|
|
702
|
+
"--no-first-run",
|
|
703
|
+
"--password-store=basic",
|
|
704
|
+
"--use-mock-keychain",
|
|
705
|
+
`--disable-features=${disabledFeatures.join(",")}`,
|
|
706
|
+
`--enable-features=${enabledFeatures.join(",")}`
|
|
707
|
+
].filter((arg) => {
|
|
708
|
+
return arg !== "";
|
|
709
|
+
});
|
|
710
|
+
const { devtools = false, headless = !devtools, args = [], userDataDir, enableExtensions = false } = options;
|
|
711
|
+
if (process.env["PUPPETEER_DANGEROUS_NO_SANDBOX"] === "true" && !args.includes("--no-sandbox")) {
|
|
712
|
+
chromeArguments.push("--no-sandbox");
|
|
713
|
+
}
|
|
714
|
+
if (userDataDir) {
|
|
715
|
+
chromeArguments.push(`--user-data-dir=${path.posix.isAbsolute(userDataDir) || path.win32.isAbsolute(userDataDir) ? userDataDir : path.resolve(userDataDir)}`);
|
|
716
|
+
}
|
|
717
|
+
if (devtools) {
|
|
718
|
+
chromeArguments.push("--auto-open-devtools-for-tabs");
|
|
719
|
+
}
|
|
720
|
+
if (headless) {
|
|
721
|
+
chromeArguments.push(headless === "shell" ? "--headless" : "--headless=new", "--hide-scrollbars", "--mute-audio");
|
|
722
|
+
}
|
|
723
|
+
chromeArguments.push(enableExtensions ? "--enable-unsafe-extension-debugging" : "--disable-extensions");
|
|
724
|
+
if (args.every((arg) => {
|
|
725
|
+
return arg.startsWith("-");
|
|
726
|
+
})) {
|
|
727
|
+
chromeArguments.push("about:blank");
|
|
728
|
+
}
|
|
729
|
+
chromeArguments.push(...args);
|
|
730
|
+
return chromeArguments;
|
|
731
|
+
}
|
|
732
|
+
async executablePath(channel, validatePath = true) {
|
|
733
|
+
if (channel) {
|
|
734
|
+
return computeSystemExecutablePath({
|
|
735
|
+
browser: Browser2.CHROME,
|
|
736
|
+
channel: convertPuppeteerChannelToBrowsersChannel(channel)
|
|
737
|
+
});
|
|
738
|
+
} else {
|
|
739
|
+
return await this.resolveExecutablePath(undefined, validatePath);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
function getFeatures(flag, options = []) {
|
|
744
|
+
const prefix = flag.endsWith("=") ? flag : `${flag}=`;
|
|
745
|
+
return options.filter((s) => {
|
|
746
|
+
return s.startsWith(prefix);
|
|
747
|
+
}).flatMap((s) => {
|
|
748
|
+
return s.substring(s.indexOf("=") + 1).trim().split(",").map((feature) => {
|
|
749
|
+
return feature.trim();
|
|
750
|
+
});
|
|
751
|
+
}).filter((s) => {
|
|
752
|
+
return s;
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
function removeMatchingFlags(array, flag) {
|
|
756
|
+
const prefix = flag.endsWith("=") ? flag : `${flag}=`;
|
|
757
|
+
let i = 0;
|
|
758
|
+
while (i < array.length) {
|
|
759
|
+
if (array[i].startsWith(prefix)) {
|
|
760
|
+
array.splice(i, 1);
|
|
761
|
+
} else {
|
|
762
|
+
i++;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return array;
|
|
766
|
+
}
|
|
767
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/FirefoxLauncher.js
|
|
768
|
+
import fs2 from "node:fs";
|
|
769
|
+
import { rename, unlink, mkdtemp as mkdtemp2 } from "node:fs/promises";
|
|
770
|
+
import os2 from "node:os";
|
|
771
|
+
import path2 from "node:path";
|
|
772
|
+
class FirefoxLauncher extends BrowserLauncher {
|
|
773
|
+
constructor(puppeteer) {
|
|
774
|
+
super(puppeteer, "firefox");
|
|
775
|
+
}
|
|
776
|
+
static getPreferences(extraPrefsFirefox) {
|
|
777
|
+
return {
|
|
778
|
+
...extraPrefsFirefox,
|
|
779
|
+
"fission.webContentIsolationStrategy": 0
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
async computeLaunchArguments(options = {}) {
|
|
783
|
+
const { ignoreDefaultArgs = false, args = [], executablePath, pipe = false, extraPrefsFirefox = {}, debuggingPort = null } = options;
|
|
784
|
+
const firefoxArguments = [];
|
|
785
|
+
if (!ignoreDefaultArgs) {
|
|
786
|
+
firefoxArguments.push(...this.defaultArgs(options));
|
|
787
|
+
} else if (Array.isArray(ignoreDefaultArgs)) {
|
|
788
|
+
firefoxArguments.push(...this.defaultArgs(options).filter((arg) => {
|
|
789
|
+
return !ignoreDefaultArgs.includes(arg);
|
|
790
|
+
}));
|
|
791
|
+
} else {
|
|
792
|
+
firefoxArguments.push(...args);
|
|
793
|
+
}
|
|
794
|
+
if (!firefoxArguments.some((argument) => {
|
|
795
|
+
return argument.startsWith("--remote-debugging-");
|
|
796
|
+
})) {
|
|
797
|
+
if (pipe) {
|
|
798
|
+
assert(debuggingPort === null, "Browser should be launched with either pipe or debugging port - not both.");
|
|
799
|
+
}
|
|
800
|
+
firefoxArguments.push(`--remote-debugging-port=${debuggingPort || 0}`);
|
|
801
|
+
}
|
|
802
|
+
let userDataDir;
|
|
803
|
+
let isTempUserDataDir = true;
|
|
804
|
+
const profileArgIndex = firefoxArguments.findIndex((arg) => {
|
|
805
|
+
return ["-profile", "--profile"].includes(arg);
|
|
806
|
+
});
|
|
807
|
+
if (profileArgIndex !== -1) {
|
|
808
|
+
userDataDir = firefoxArguments[profileArgIndex + 1];
|
|
809
|
+
if (!userDataDir) {
|
|
810
|
+
throw new Error(`Missing value for profile command line argument`);
|
|
811
|
+
}
|
|
812
|
+
isTempUserDataDir = false;
|
|
813
|
+
} else {
|
|
814
|
+
const profilePath = await this.getProfilePath();
|
|
815
|
+
userDataDir = await mkdtemp2(profilePath);
|
|
816
|
+
firefoxArguments.push("--profile");
|
|
817
|
+
firefoxArguments.push(userDataDir);
|
|
818
|
+
}
|
|
819
|
+
await createProfile(Browser2.FIREFOX, {
|
|
820
|
+
path: userDataDir,
|
|
821
|
+
preferences: FirefoxLauncher.getPreferences(extraPrefsFirefox)
|
|
822
|
+
});
|
|
823
|
+
let firefoxExecutable;
|
|
824
|
+
if (this.puppeteer._isPuppeteerCore || executablePath) {
|
|
825
|
+
assert(executablePath, `An \`executablePath\` must be specified for \`puppeteer-core\``);
|
|
826
|
+
firefoxExecutable = executablePath;
|
|
827
|
+
} else {
|
|
828
|
+
firefoxExecutable = await this.executablePath(undefined);
|
|
829
|
+
}
|
|
830
|
+
return {
|
|
831
|
+
isTempUserDataDir,
|
|
832
|
+
userDataDir,
|
|
833
|
+
args: firefoxArguments,
|
|
834
|
+
executablePath: firefoxExecutable
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
async cleanUserDataDir(userDataDir, opts) {
|
|
838
|
+
if (opts.isTemp) {
|
|
839
|
+
try {
|
|
840
|
+
await rm(userDataDir);
|
|
841
|
+
} catch (error) {
|
|
842
|
+
debugError(error);
|
|
843
|
+
throw error;
|
|
844
|
+
}
|
|
845
|
+
} else {
|
|
846
|
+
try {
|
|
847
|
+
const backupSuffix = ".puppeteer";
|
|
848
|
+
const backupFiles = ["prefs.js", "user.js"];
|
|
849
|
+
const results = await Promise.allSettled(backupFiles.map(async (file) => {
|
|
850
|
+
const prefsBackupPath = path2.join(userDataDir, file + backupSuffix);
|
|
851
|
+
if (fs2.existsSync(prefsBackupPath)) {
|
|
852
|
+
const prefsPath = path2.join(userDataDir, file);
|
|
853
|
+
await unlink(prefsPath);
|
|
854
|
+
await rename(prefsBackupPath, prefsPath);
|
|
855
|
+
}
|
|
856
|
+
}));
|
|
857
|
+
for (const result of results) {
|
|
858
|
+
if (result.status === "rejected") {
|
|
859
|
+
throw result.reason;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
} catch (error) {
|
|
863
|
+
debugError(error);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
async executablePath(_, validatePath = true) {
|
|
868
|
+
return await this.resolveExecutablePath(undefined, validatePath);
|
|
869
|
+
}
|
|
870
|
+
defaultArgs(options = {}) {
|
|
871
|
+
const { devtools = false, headless = !devtools, args = [], userDataDir = null } = options;
|
|
872
|
+
const firefoxArguments = [];
|
|
873
|
+
switch (os2.platform()) {
|
|
874
|
+
case "darwin":
|
|
875
|
+
firefoxArguments.push("--foreground");
|
|
876
|
+
break;
|
|
877
|
+
case "win32":
|
|
878
|
+
firefoxArguments.push("--wait-for-browser");
|
|
879
|
+
break;
|
|
880
|
+
}
|
|
881
|
+
if (userDataDir) {
|
|
882
|
+
firefoxArguments.push("--profile");
|
|
883
|
+
firefoxArguments.push(userDataDir);
|
|
884
|
+
}
|
|
885
|
+
if (headless) {
|
|
886
|
+
firefoxArguments.push("--headless");
|
|
887
|
+
}
|
|
888
|
+
if (devtools) {
|
|
889
|
+
firefoxArguments.push("--devtools");
|
|
890
|
+
}
|
|
891
|
+
if (args.every((arg) => {
|
|
892
|
+
return arg.startsWith("-");
|
|
893
|
+
})) {
|
|
894
|
+
firefoxArguments.push("about:blank");
|
|
895
|
+
}
|
|
896
|
+
firefoxArguments.push(...args);
|
|
897
|
+
return firefoxArguments;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/PuppeteerNode.js
|
|
901
|
+
class PuppeteerNode extends Puppeteer {
|
|
902
|
+
#launcher;
|
|
903
|
+
#lastLaunchedBrowser;
|
|
904
|
+
configuration;
|
|
905
|
+
constructor(settings) {
|
|
906
|
+
const { configuration, ...commonSettings } = settings;
|
|
907
|
+
super(commonSettings);
|
|
908
|
+
if (configuration) {
|
|
909
|
+
this.configuration = configuration;
|
|
910
|
+
} else {
|
|
911
|
+
this.configuration = () => {
|
|
912
|
+
return Promise.resolve({});
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
this.connect = this.connect.bind(this);
|
|
916
|
+
this.launch = this.launch.bind(this);
|
|
917
|
+
this.executablePath = this.executablePath.bind(this);
|
|
918
|
+
this.defaultArgs = this.defaultArgs.bind(this);
|
|
919
|
+
this.trimCache = this.trimCache.bind(this);
|
|
920
|
+
}
|
|
921
|
+
connect(options) {
|
|
922
|
+
return super.connect(options);
|
|
923
|
+
}
|
|
924
|
+
async launch(options = {}) {
|
|
925
|
+
const { browser = await this.defaultBrowser() } = options;
|
|
926
|
+
this.#lastLaunchedBrowser = browser;
|
|
927
|
+
if (!["chrome", "firefox"].includes(browser)) {
|
|
928
|
+
throw new Error(`Unknown product: ${browser}`);
|
|
929
|
+
}
|
|
930
|
+
this.#launcher = this.#getLauncher(browser);
|
|
931
|
+
return await this.#launcher.launch(options);
|
|
932
|
+
}
|
|
933
|
+
#getLauncher(browser) {
|
|
934
|
+
if (this.#launcher && this.#launcher.browser === browser) {
|
|
935
|
+
return this.#launcher;
|
|
936
|
+
}
|
|
937
|
+
switch (browser) {
|
|
938
|
+
case "chrome":
|
|
939
|
+
return new ChromeLauncher(this);
|
|
940
|
+
case "firefox":
|
|
941
|
+
return new FirefoxLauncher(this);
|
|
942
|
+
default:
|
|
943
|
+
throw new Error(`Unknown product: ${browser}`);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
async executablePath(optsOrChannel) {
|
|
947
|
+
if (optsOrChannel === undefined) {
|
|
948
|
+
return await this.#getLauncher(await this.lastLaunchedBrowser()).executablePath(undefined, false);
|
|
949
|
+
}
|
|
950
|
+
if (typeof optsOrChannel === "string") {
|
|
951
|
+
return await this.#getLauncher("chrome").executablePath(optsOrChannel, false);
|
|
952
|
+
}
|
|
953
|
+
return await this.#getLauncher(optsOrChannel.browser ?? await this.lastLaunchedBrowser()).resolveExecutablePath(optsOrChannel.headless, false);
|
|
954
|
+
}
|
|
955
|
+
async browserVersion() {
|
|
956
|
+
const config = await this.configuration();
|
|
957
|
+
const lastLaunched = await this.lastLaunchedBrowser();
|
|
958
|
+
return config?.[lastLaunched]?.version ?? PUPPETEER_REVISIONS[lastLaunched];
|
|
959
|
+
}
|
|
960
|
+
async defaultDownloadPath() {
|
|
961
|
+
const config = await this.configuration();
|
|
962
|
+
return config.cacheDirectory;
|
|
963
|
+
}
|
|
964
|
+
async lastLaunchedBrowser() {
|
|
965
|
+
return this.#lastLaunchedBrowser ?? await this.defaultBrowser();
|
|
966
|
+
}
|
|
967
|
+
async defaultBrowser() {
|
|
968
|
+
const config = await this.configuration();
|
|
969
|
+
return config.defaultBrowser ?? "chrome";
|
|
970
|
+
}
|
|
971
|
+
async defaultArgs(options = {}) {
|
|
972
|
+
return this.#getLauncher(options.browser ?? await this.lastLaunchedBrowser()).defaultArgs(options);
|
|
973
|
+
}
|
|
974
|
+
async trimCache() {
|
|
975
|
+
const platform = detectBrowserPlatform();
|
|
976
|
+
if (!platform) {
|
|
977
|
+
throw new Error("The current platform is not supported.");
|
|
978
|
+
}
|
|
979
|
+
const config = await this.configuration();
|
|
980
|
+
const cacheDir = config.cacheDirectory;
|
|
981
|
+
const installedBrowsers = await getInstalledBrowsers({
|
|
982
|
+
cacheDir
|
|
983
|
+
});
|
|
984
|
+
const puppeteerBrowsers = [
|
|
985
|
+
{
|
|
986
|
+
product: "chrome",
|
|
987
|
+
browser: Browser2.CHROME,
|
|
988
|
+
currentBuildId: ""
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
product: "firefox",
|
|
992
|
+
browser: Browser2.FIREFOX,
|
|
993
|
+
currentBuildId: ""
|
|
994
|
+
}
|
|
995
|
+
];
|
|
996
|
+
await Promise.all(puppeteerBrowsers.map(async (item) => {
|
|
997
|
+
const tag = config?.[item.product]?.version ?? PUPPETEER_REVISIONS[item.product];
|
|
998
|
+
item.currentBuildId = await resolveBuildId(item.browser, platform, tag);
|
|
999
|
+
}));
|
|
1000
|
+
const currentBrowserBuilds = new Set(puppeteerBrowsers.map((browser) => {
|
|
1001
|
+
return `${browser.browser}_${browser.currentBuildId}`;
|
|
1002
|
+
}));
|
|
1003
|
+
const currentBrowsers = new Set(puppeteerBrowsers.map((browser) => {
|
|
1004
|
+
return browser.browser;
|
|
1005
|
+
}));
|
|
1006
|
+
for (const installedBrowser of installedBrowsers) {
|
|
1007
|
+
if (!currentBrowsers.has(installedBrowser.browser)) {
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
if (currentBrowserBuilds.has(`${installedBrowser.browser}_${installedBrowser.buildId}`)) {
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
await uninstall({
|
|
1014
|
+
browser: installedBrowser.browser,
|
|
1015
|
+
platform,
|
|
1016
|
+
cacheDir,
|
|
1017
|
+
buildId: installedBrowser.buildId
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
// node_modules/puppeteer-core/lib/puppeteer/node/ScreenRecorder.js
|
|
1023
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
1024
|
+
import fs3 from "node:fs";
|
|
1025
|
+
import os3 from "node:os";
|
|
1026
|
+
import { dirname } from "node:path";
|
|
1027
|
+
import { PassThrough } from "node:stream";
|
|
1028
|
+
var __runInitializers = function(thisArg, initializers, value) {
|
|
1029
|
+
var useValue = arguments.length > 2;
|
|
1030
|
+
for (var i = 0;i < initializers.length; i++) {
|
|
1031
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
1032
|
+
}
|
|
1033
|
+
return useValue ? value : undefined;
|
|
1034
|
+
};
|
|
1035
|
+
var __esDecorate = function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
1036
|
+
function accept(f) {
|
|
1037
|
+
if (f !== undefined && typeof f !== "function")
|
|
1038
|
+
throw new TypeError("Function expected");
|
|
1039
|
+
return f;
|
|
1040
|
+
}
|
|
1041
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
1042
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
1043
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
1044
|
+
var _, done = false;
|
|
1045
|
+
for (var i = decorators.length - 1;i >= 0; i--) {
|
|
1046
|
+
var context = {};
|
|
1047
|
+
for (var p in contextIn)
|
|
1048
|
+
context[p] = p === "access" ? {} : contextIn[p];
|
|
1049
|
+
for (var p in contextIn.access)
|
|
1050
|
+
context.access[p] = contextIn.access[p];
|
|
1051
|
+
context.addInitializer = function(f) {
|
|
1052
|
+
if (done)
|
|
1053
|
+
throw new TypeError("Cannot add initializers after decoration has completed");
|
|
1054
|
+
extraInitializers.push(accept(f || null));
|
|
1055
|
+
};
|
|
1056
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
1057
|
+
if (kind === "accessor") {
|
|
1058
|
+
if (result === undefined)
|
|
1059
|
+
continue;
|
|
1060
|
+
if (result === null || typeof result !== "object")
|
|
1061
|
+
throw new TypeError("Object expected");
|
|
1062
|
+
if (_ = accept(result.get))
|
|
1063
|
+
descriptor.get = _;
|
|
1064
|
+
if (_ = accept(result.set))
|
|
1065
|
+
descriptor.set = _;
|
|
1066
|
+
if (_ = accept(result.init))
|
|
1067
|
+
initializers.unshift(_);
|
|
1068
|
+
} else if (_ = accept(result)) {
|
|
1069
|
+
if (kind === "field")
|
|
1070
|
+
initializers.unshift(_);
|
|
1071
|
+
else
|
|
1072
|
+
descriptor[key] = _;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (target)
|
|
1076
|
+
Object.defineProperty(target, contextIn.name, descriptor);
|
|
1077
|
+
done = true;
|
|
1078
|
+
};
|
|
1079
|
+
var __setFunctionName = function(f, name, prefix) {
|
|
1080
|
+
if (typeof name === "symbol")
|
|
1081
|
+
name = name.description ? "[".concat(name.description, "]") : "";
|
|
1082
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
1083
|
+
};
|
|
1084
|
+
var CRF_VALUE = 30;
|
|
1085
|
+
var DEFAULT_FPS = 30;
|
|
1086
|
+
var debugFfmpeg = debug("puppeteer:ffmpeg");
|
|
1087
|
+
var ScreenRecorder = (() => {
|
|
1088
|
+
let _classSuper = PassThrough;
|
|
1089
|
+
let _instanceExtraInitializers = [];
|
|
1090
|
+
let _private_writeFrame_decorators;
|
|
1091
|
+
let _private_writeFrame_descriptor;
|
|
1092
|
+
let _stop_decorators;
|
|
1093
|
+
return class ScreenRecorder2 extends _classSuper {
|
|
1094
|
+
static {
|
|
1095
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : undefined;
|
|
1096
|
+
__esDecorate(this, _private_writeFrame_descriptor = { value: __setFunctionName(async function(buffer) {
|
|
1097
|
+
const error = await new Promise((resolve) => {
|
|
1098
|
+
this.#process.stdin.write(buffer, resolve);
|
|
1099
|
+
});
|
|
1100
|
+
if (error) {
|
|
1101
|
+
console.log(`ffmpeg failed to write: ${error.message}.`);
|
|
1102
|
+
}
|
|
1103
|
+
}, "#writeFrame") }, _private_writeFrame_decorators, { kind: "method", name: "#writeFrame", static: false, private: true, access: { has: (obj) => (#writeFrame in obj), get: (obj) => obj.#writeFrame }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
1104
|
+
__esDecorate(this, null, _stop_decorators, { kind: "method", name: "stop", static: false, private: false, access: { has: (obj) => ("stop" in obj), get: (obj) => obj.stop }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
1105
|
+
if (_metadata)
|
|
1106
|
+
Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
1107
|
+
}
|
|
1108
|
+
#page = __runInitializers(this, _instanceExtraInitializers);
|
|
1109
|
+
#process;
|
|
1110
|
+
#controller = new AbortController;
|
|
1111
|
+
#lastFrame;
|
|
1112
|
+
#fps;
|
|
1113
|
+
constructor(page, width, height, { ffmpegPath, speed, scale, crop, format, fps, loop, delay, quality, colors, path: path3, overwrite } = {}) {
|
|
1114
|
+
super({ allowHalfOpen: false });
|
|
1115
|
+
ffmpegPath ??= "ffmpeg";
|
|
1116
|
+
format ??= "webm";
|
|
1117
|
+
fps ??= DEFAULT_FPS;
|
|
1118
|
+
loop ||= -1;
|
|
1119
|
+
delay ??= -1;
|
|
1120
|
+
quality ??= CRF_VALUE;
|
|
1121
|
+
colors ??= 256;
|
|
1122
|
+
overwrite ??= true;
|
|
1123
|
+
this.#fps = fps;
|
|
1124
|
+
const { error } = spawnSync(ffmpegPath);
|
|
1125
|
+
if (error) {
|
|
1126
|
+
throw error;
|
|
1127
|
+
}
|
|
1128
|
+
const filters = [
|
|
1129
|
+
`crop='min(${width},iw):min(${height},ih):0:0'`,
|
|
1130
|
+
`pad=${width}:${height}:0:0`
|
|
1131
|
+
];
|
|
1132
|
+
if (speed) {
|
|
1133
|
+
filters.push(`setpts=${1 / speed}*PTS`);
|
|
1134
|
+
}
|
|
1135
|
+
if (crop) {
|
|
1136
|
+
filters.push(`crop=${crop.width}:${crop.height}:${crop.x}:${crop.y}`);
|
|
1137
|
+
}
|
|
1138
|
+
if (scale) {
|
|
1139
|
+
filters.push(`scale=iw*${scale}:-1:flags=lanczos`);
|
|
1140
|
+
}
|
|
1141
|
+
const formatArgs = this.#getFormatArgs(format, fps, loop, delay, quality, colors);
|
|
1142
|
+
const vf = formatArgs.indexOf("-vf");
|
|
1143
|
+
if (vf !== -1) {
|
|
1144
|
+
filters.push(formatArgs.splice(vf, 2).at(-1) ?? "");
|
|
1145
|
+
}
|
|
1146
|
+
if (path3) {
|
|
1147
|
+
fs3.mkdirSync(dirname(path3), { recursive: overwrite });
|
|
1148
|
+
}
|
|
1149
|
+
this.#process = spawn(ffmpegPath, [
|
|
1150
|
+
["-loglevel", "error"],
|
|
1151
|
+
["-avioflags", "direct"],
|
|
1152
|
+
[
|
|
1153
|
+
"-fpsprobesize",
|
|
1154
|
+
"0",
|
|
1155
|
+
"-probesize",
|
|
1156
|
+
"32",
|
|
1157
|
+
"-analyzeduration",
|
|
1158
|
+
"0",
|
|
1159
|
+
"-fflags",
|
|
1160
|
+
"nobuffer"
|
|
1161
|
+
],
|
|
1162
|
+
["-f", "image2pipe", "-vcodec", "png", "-i", "pipe:0"],
|
|
1163
|
+
["-an"],
|
|
1164
|
+
["-threads", "1"],
|
|
1165
|
+
["-framerate", `${fps}`],
|
|
1166
|
+
["-b:v", "0"],
|
|
1167
|
+
formatArgs,
|
|
1168
|
+
["-vf", filters.join()],
|
|
1169
|
+
[overwrite ? "-y" : "-n"],
|
|
1170
|
+
"pipe:1"
|
|
1171
|
+
].flat(), { stdio: ["pipe", "pipe", "pipe"] });
|
|
1172
|
+
this.#process.stdout.pipe(this);
|
|
1173
|
+
this.#process.stderr.on("data", (data) => {
|
|
1174
|
+
debugFfmpeg(data.toString("utf8"));
|
|
1175
|
+
});
|
|
1176
|
+
this.#page = page;
|
|
1177
|
+
const { client } = this.#page.mainFrame();
|
|
1178
|
+
client.once(CDPSessionEvent.Disconnected, () => {
|
|
1179
|
+
this.stop().catch(debugError);
|
|
1180
|
+
});
|
|
1181
|
+
this.#lastFrame = lastValueFrom(fromEmitterEvent(client, "Page.screencastFrame").pipe(tap((event) => {
|
|
1182
|
+
client.send("Page.screencastFrameAck", {
|
|
1183
|
+
sessionId: event.sessionId
|
|
1184
|
+
});
|
|
1185
|
+
}), filter((event) => {
|
|
1186
|
+
return event.metadata.timestamp !== undefined;
|
|
1187
|
+
}), map((event) => {
|
|
1188
|
+
return {
|
|
1189
|
+
buffer: Buffer.from(event.data, "base64"),
|
|
1190
|
+
timestamp: event.metadata.timestamp
|
|
1191
|
+
};
|
|
1192
|
+
}), bufferCount(2, 1), concatMap(([{ timestamp: previousTimestamp, buffer }, { timestamp }]) => {
|
|
1193
|
+
return from(Array(Math.round(fps * Math.max(timestamp - previousTimestamp, 0))).fill(buffer));
|
|
1194
|
+
}), map((buffer) => {
|
|
1195
|
+
this.#writeFrame(buffer);
|
|
1196
|
+
return [buffer, performance.now()];
|
|
1197
|
+
}), takeUntil(fromEvent(this.#controller.signal, "abort"))), { defaultValue: [Buffer.from([]), performance.now()] });
|
|
1198
|
+
}
|
|
1199
|
+
#getFormatArgs(format, fps, loop, delay, quality, colors) {
|
|
1200
|
+
const libvpx = [
|
|
1201
|
+
["-vcodec", "vp9"],
|
|
1202
|
+
["-crf", `${quality}`],
|
|
1203
|
+
[
|
|
1204
|
+
"-deadline",
|
|
1205
|
+
"realtime",
|
|
1206
|
+
"-cpu-used",
|
|
1207
|
+
`${Math.min(os3.cpus().length / 2, 8)}`
|
|
1208
|
+
]
|
|
1209
|
+
];
|
|
1210
|
+
switch (format) {
|
|
1211
|
+
case "webm":
|
|
1212
|
+
return [
|
|
1213
|
+
...libvpx,
|
|
1214
|
+
["-f", "webm"]
|
|
1215
|
+
].flat();
|
|
1216
|
+
case "gif":
|
|
1217
|
+
fps = DEFAULT_FPS === fps ? 20 : "source_fps";
|
|
1218
|
+
if (loop === Infinity) {
|
|
1219
|
+
loop = 0;
|
|
1220
|
+
}
|
|
1221
|
+
if (delay !== -1) {
|
|
1222
|
+
delay /= 10;
|
|
1223
|
+
}
|
|
1224
|
+
return [
|
|
1225
|
+
[
|
|
1226
|
+
"-vf",
|
|
1227
|
+
`fps=${fps},split[s0][s1];[s0]palettegen=stats_mode=diff:max_colors=${colors}[p];[s1][p]paletteuse=dither=bayer`
|
|
1228
|
+
],
|
|
1229
|
+
["-loop", `${loop}`],
|
|
1230
|
+
["-final_delay", `${delay}`],
|
|
1231
|
+
["-f", "gif"]
|
|
1232
|
+
].flat();
|
|
1233
|
+
case "mp4":
|
|
1234
|
+
return [
|
|
1235
|
+
...libvpx,
|
|
1236
|
+
["-movflags", "hybrid_fragmented"],
|
|
1237
|
+
["-f", "mp4"]
|
|
1238
|
+
].flat();
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
get #writeFrame() {
|
|
1242
|
+
return _private_writeFrame_descriptor.value;
|
|
1243
|
+
}
|
|
1244
|
+
async stop() {
|
|
1245
|
+
if (this.#controller.signal.aborted) {
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
await this.#page._stopScreencast().catch(debugError);
|
|
1249
|
+
this.#controller.abort();
|
|
1250
|
+
const [buffer, timestamp] = await this.#lastFrame;
|
|
1251
|
+
await Promise.all(Array(Math.max(1, Math.round(this.#fps * (performance.now() - timestamp) / 1000))).fill(buffer).map(this.#writeFrame.bind(this)));
|
|
1252
|
+
this.#process.stdin.end();
|
|
1253
|
+
await new Promise((resolve) => {
|
|
1254
|
+
this.#process.once("close", resolve);
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
async[(_private_writeFrame_decorators = [guarded()], _stop_decorators = [guarded()], asyncDisposeSymbol)]() {
|
|
1258
|
+
await this.stop();
|
|
1259
|
+
await super[asyncDisposeSymbol]();
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
})();
|
|
1263
|
+
// node_modules/puppeteer-core/lib/puppeteer/puppeteer-core.js
|
|
1264
|
+
import fs4 from "node:fs";
|
|
1265
|
+
import path3 from "node:path";
|
|
1266
|
+
environment.value = {
|
|
1267
|
+
fs: fs4,
|
|
1268
|
+
path: path3,
|
|
1269
|
+
ScreenRecorder
|
|
1270
|
+
};
|
|
1271
|
+
var puppeteer = new PuppeteerNode({
|
|
1272
|
+
isPuppeteerCore: true
|
|
1273
|
+
});
|
|
1274
|
+
var {
|
|
1275
|
+
connect,
|
|
1276
|
+
defaultArgs,
|
|
1277
|
+
executablePath,
|
|
1278
|
+
launch: launch2
|
|
1279
|
+
} = puppeteer;
|
|
1280
|
+
var puppeteer_core_default = puppeteer;
|
|
1281
|
+
export {
|
|
1282
|
+
withSourcePuppeteerURLIfNone,
|
|
1283
|
+
valueFromRemoteObjectReference,
|
|
1284
|
+
valueFromPrimitiveRemoteObject,
|
|
1285
|
+
valueFromJSHandle,
|
|
1286
|
+
validateDialogType,
|
|
1287
|
+
unitToPixels,
|
|
1288
|
+
transposeIterableHandle,
|
|
1289
|
+
timeout,
|
|
1290
|
+
throwIfDetached,
|
|
1291
|
+
supportedMetrics,
|
|
1292
|
+
setLogCapture,
|
|
1293
|
+
setDefaultScreenshotOptions,
|
|
1294
|
+
scriptInjector,
|
|
1295
|
+
rewriteError,
|
|
1296
|
+
removeMatchingFlags,
|
|
1297
|
+
releaseObject,
|
|
1298
|
+
referrerPolicyToProtocol,
|
|
1299
|
+
parsePSelectors,
|
|
1300
|
+
parsePDFOptions,
|
|
1301
|
+
paperFormats,
|
|
1302
|
+
pageBindingInitString,
|
|
1303
|
+
normalizeHeaderValue,
|
|
1304
|
+
launch2 as launch,
|
|
1305
|
+
isTargetClosedError,
|
|
1306
|
+
isString,
|
|
1307
|
+
isRegExp,
|
|
1308
|
+
isPlainObject,
|
|
1309
|
+
isNumber,
|
|
1310
|
+
isErrorLike,
|
|
1311
|
+
isErrnoException,
|
|
1312
|
+
isDate,
|
|
1313
|
+
importDebug,
|
|
1314
|
+
headersArray,
|
|
1315
|
+
handleError,
|
|
1316
|
+
getSourceUrlComment,
|
|
1317
|
+
getSourcePuppeteerURLIfAvailable,
|
|
1318
|
+
getReadableFromProtocolStream,
|
|
1319
|
+
getReadableAsTypedArray,
|
|
1320
|
+
getQueryHandlerAndSelector,
|
|
1321
|
+
getFeatures,
|
|
1322
|
+
getCapturedLogs,
|
|
1323
|
+
fromEmitterEvent,
|
|
1324
|
+
fromAbortSignal,
|
|
1325
|
+
filterAsync,
|
|
1326
|
+
executablePath,
|
|
1327
|
+
evaluationString,
|
|
1328
|
+
disposeSymbol,
|
|
1329
|
+
defaultArgs,
|
|
1330
|
+
puppeteer_core_default as default,
|
|
1331
|
+
debugError,
|
|
1332
|
+
debug,
|
|
1333
|
+
customQueryHandlers,
|
|
1334
|
+
createProtocolErrorMessage,
|
|
1335
|
+
createIncrementalIdGenerator,
|
|
1336
|
+
createEvaluationError,
|
|
1337
|
+
createConsoleMessage,
|
|
1338
|
+
createClientError,
|
|
1339
|
+
convertSameSiteFromPuppeteerToCdp,
|
|
1340
|
+
convertCookiesPartitionKeyFromPuppeteerToCdp,
|
|
1341
|
+
convertConsoleMessageLevel,
|
|
1342
|
+
connect,
|
|
1343
|
+
bindIsolatedHandle,
|
|
1344
|
+
asyncDisposeSymbol,
|
|
1345
|
+
assert,
|
|
1346
|
+
addPageBinding,
|
|
1347
|
+
_keyDefinitions,
|
|
1348
|
+
_connectToCdpBrowser,
|
|
1349
|
+
XPathQueryHandler,
|
|
1350
|
+
WorkerTarget,
|
|
1351
|
+
WebWorkerEvent,
|
|
1352
|
+
WebWorker,
|
|
1353
|
+
WebMCPToolCall,
|
|
1354
|
+
WebMCPTool,
|
|
1355
|
+
WebMCP,
|
|
1356
|
+
WaitTask,
|
|
1357
|
+
WEB_PERMISSION_TO_PROTOCOL_PERMISSION,
|
|
1358
|
+
UnsupportedOperation,
|
|
1359
|
+
UTILITY_WORLD_NAME,
|
|
1360
|
+
Tracing,
|
|
1361
|
+
Touchscreen,
|
|
1362
|
+
TouchError,
|
|
1363
|
+
TimeoutSettings,
|
|
1364
|
+
TimeoutError,
|
|
1365
|
+
TextQueryHandler,
|
|
1366
|
+
TaskQueue,
|
|
1367
|
+
TaskManager,
|
|
1368
|
+
TargetType,
|
|
1369
|
+
TargetManager,
|
|
1370
|
+
TargetCloseError,
|
|
1371
|
+
Target,
|
|
1372
|
+
SuppressedError,
|
|
1373
|
+
SecurityDetails,
|
|
1374
|
+
ScriptInjector,
|
|
1375
|
+
ScreenRecorder,
|
|
1376
|
+
STATUS_TEXTS,
|
|
1377
|
+
SOURCE_URL_REGEX,
|
|
1378
|
+
Realm,
|
|
1379
|
+
RaceLocator,
|
|
1380
|
+
RETRY_DELAY,
|
|
1381
|
+
QueryHandler,
|
|
1382
|
+
PuppeteerURL,
|
|
1383
|
+
PuppeteerNode,
|
|
1384
|
+
PuppeteerError,
|
|
1385
|
+
Puppeteer,
|
|
1386
|
+
ProtocolError,
|
|
1387
|
+
PredefinedNetworkConditions,
|
|
1388
|
+
PipeTransport,
|
|
1389
|
+
PierceQueryHandler,
|
|
1390
|
+
PageTarget,
|
|
1391
|
+
Page,
|
|
1392
|
+
PUPPETEER_WORLD,
|
|
1393
|
+
PUPPETEER_REVISIONS,
|
|
1394
|
+
PQueryHandler,
|
|
1395
|
+
OtherTarget,
|
|
1396
|
+
NodeLocator,
|
|
1397
|
+
NetworkManagerEvent,
|
|
1398
|
+
NetworkManager,
|
|
1399
|
+
NetworkEventManager,
|
|
1400
|
+
NETWORK_IDLE_TIME,
|
|
1401
|
+
Mutex,
|
|
1402
|
+
MouseButton,
|
|
1403
|
+
Mouse,
|
|
1404
|
+
MappedLocator,
|
|
1405
|
+
MAIN_WORLD,
|
|
1406
|
+
LocatorEvent,
|
|
1407
|
+
Locator,
|
|
1408
|
+
LifecycleWatcher,
|
|
1409
|
+
LazyArg,
|
|
1410
|
+
KnownDevices,
|
|
1411
|
+
Keyboard,
|
|
1412
|
+
JSHandle,
|
|
1413
|
+
JSCoverage,
|
|
1414
|
+
IsolatedWorld,
|
|
1415
|
+
InterceptResolutionAction,
|
|
1416
|
+
InitializationStatus,
|
|
1417
|
+
HTTPResponse,
|
|
1418
|
+
HTTPRequest,
|
|
1419
|
+
FunctionLocator,
|
|
1420
|
+
FrameTree,
|
|
1421
|
+
FrameManagerEvent,
|
|
1422
|
+
FrameManager,
|
|
1423
|
+
FrameEvent,
|
|
1424
|
+
Frame,
|
|
1425
|
+
FirefoxLauncher,
|
|
1426
|
+
FilteredLocator,
|
|
1427
|
+
FileChooser,
|
|
1428
|
+
ExtensionTransport,
|
|
1429
|
+
Extension,
|
|
1430
|
+
ExecutionContext,
|
|
1431
|
+
EventEmitter,
|
|
1432
|
+
EmulationManager,
|
|
1433
|
+
EmulatedState,
|
|
1434
|
+
ElementHandle,
|
|
1435
|
+
DisposableStackPolyfill,
|
|
1436
|
+
DisposableStack,
|
|
1437
|
+
Dialog,
|
|
1438
|
+
DeviceRequestPrompt,
|
|
1439
|
+
DevToolsTarget,
|
|
1440
|
+
DelegatedLocator,
|
|
1441
|
+
Deferred,
|
|
1442
|
+
DEFAULT_VIEWPORT,
|
|
1443
|
+
DEFAULT_INTERCEPT_RESOLUTION_PRIORITY,
|
|
1444
|
+
CustomQueryHandlerRegistry,
|
|
1445
|
+
Coverage,
|
|
1446
|
+
ConsoleMessage,
|
|
1447
|
+
ConnectionClosedError,
|
|
1448
|
+
Connection,
|
|
1449
|
+
ChromeLauncher,
|
|
1450
|
+
CdpWebWorker,
|
|
1451
|
+
CdpTouchscreen,
|
|
1452
|
+
CdpTouchHandle,
|
|
1453
|
+
CdpTarget,
|
|
1454
|
+
CdpPreloadScript,
|
|
1455
|
+
CdpPage,
|
|
1456
|
+
CdpMouse,
|
|
1457
|
+
CdpKeyboard,
|
|
1458
|
+
CdpJSHandle,
|
|
1459
|
+
CdpHTTPResponse,
|
|
1460
|
+
CdpHTTPRequest,
|
|
1461
|
+
CdpFrame,
|
|
1462
|
+
CdpElementHandle,
|
|
1463
|
+
CdpDialog,
|
|
1464
|
+
CdpDeviceRequestPromptManager,
|
|
1465
|
+
CdpDeviceRequestPrompt,
|
|
1466
|
+
CdpCDPSession,
|
|
1467
|
+
CdpBrowserContext,
|
|
1468
|
+
CdpBrowser,
|
|
1469
|
+
CdpBluetoothEmulation,
|
|
1470
|
+
CallbackRegistry,
|
|
1471
|
+
Callback,
|
|
1472
|
+
CSSCoverage,
|
|
1473
|
+
CDP_BINDING_PREFIX,
|
|
1474
|
+
CDPSessionEvent,
|
|
1475
|
+
CDPSession,
|
|
1476
|
+
BrowserWebSocketTransport,
|
|
1477
|
+
BrowserLauncher,
|
|
1478
|
+
BrowserContext,
|
|
1479
|
+
Browser,
|
|
1480
|
+
Binding,
|
|
1481
|
+
AsyncIterableUtil,
|
|
1482
|
+
AsyncDisposableStackPolyfill,
|
|
1483
|
+
AsyncDisposableStack,
|
|
1484
|
+
Accessibility,
|
|
1485
|
+
ARIAQueryHandler
|
|
1486
|
+
};
|