@skrillex1224/playwright-toolkit 2.1.285 → 2.1.287
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/dist/browser.js +161 -409
- package/dist/browser.js.map +4 -4
- package/dist/index.cjs +245 -757
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +246 -758
- package/dist/index.js.map +4 -4
- package/dist/internals/proxy-meter.js +51 -5
- package/index.d.ts +6 -59
- package/package.json +1 -7
|
@@ -32,6 +32,25 @@ const state = {
|
|
|
32
32
|
: null,
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
const formatFatalError = (error) => {
|
|
36
|
+
if (error instanceof Error) {
|
|
37
|
+
return error.stack || error.message || String(error);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return JSON.stringify(error);
|
|
41
|
+
} catch {
|
|
42
|
+
return String(error);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const exitAfterFatal = (kind, error) => {
|
|
47
|
+
try {
|
|
48
|
+
console.error(`[proxy-meter] fatal ${kind}: ${formatFatalError(error)}`);
|
|
49
|
+
} catch {}
|
|
50
|
+
flushSnapshot();
|
|
51
|
+
process.exit(1);
|
|
52
|
+
};
|
|
53
|
+
|
|
35
54
|
const getHostBucket = (host) => {
|
|
36
55
|
if (!host) return null;
|
|
37
56
|
if (!state.hosts[host]) {
|
|
@@ -60,6 +79,21 @@ const safeError = (error) => {
|
|
|
60
79
|
return message.length > 240 ? message.slice(0, 240) : message;
|
|
61
80
|
};
|
|
62
81
|
|
|
82
|
+
const sendBadGateway = (res, error = null) => {
|
|
83
|
+
if (!res || res.destroyed || res.writableEnded) return;
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
if (!res.headersSent) {
|
|
87
|
+
res.writeHead(502);
|
|
88
|
+
res.end('Bad Gateway');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Headers are already committed; the only truthful error signal left is closing the stream.
|
|
93
|
+
res.destroy(error instanceof Error ? error : undefined);
|
|
94
|
+
} catch {}
|
|
95
|
+
};
|
|
96
|
+
|
|
63
97
|
const statusLabel = (statusCode, error) => {
|
|
64
98
|
const code = Number(statusCode) || 0;
|
|
65
99
|
if (error || code <= 0) return 'ERR';
|
|
@@ -349,8 +383,7 @@ const forwardHttp = (req, res) => {
|
|
|
349
383
|
|
|
350
384
|
if (!target) {
|
|
351
385
|
tracker.close({ statusCode: 0, error: 'invalid_target_url' });
|
|
352
|
-
res
|
|
353
|
-
res.end('Bad Gateway');
|
|
386
|
+
sendBadGateway(res);
|
|
354
387
|
return;
|
|
355
388
|
}
|
|
356
389
|
|
|
@@ -381,7 +414,19 @@ const forwardHttp = (req, res) => {
|
|
|
381
414
|
let responseStatus = 0;
|
|
382
415
|
const proxyReq = http.request(requestOptions, (proxyRes) => {
|
|
383
416
|
responseStatus = Number(proxyRes.statusCode) || 0;
|
|
384
|
-
res.
|
|
417
|
+
if (res.destroyed || res.writableEnded) {
|
|
418
|
+
tracker.close({ statusCode: responseStatus || 499, error: 'client_response_closed' });
|
|
419
|
+
proxyRes.resume();
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
res.writeHead(responseStatus || 502, proxyRes.headers);
|
|
424
|
+
} catch (error) {
|
|
425
|
+
tracker.close({ statusCode: responseStatus, error: safeError(error) });
|
|
426
|
+
proxyRes.resume();
|
|
427
|
+
sendBadGateway(res, error);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
385
430
|
proxyRes.on('data', (chunk) => {
|
|
386
431
|
const size = chunk?.length || 0;
|
|
387
432
|
addTraffic(hostname, 'in', size);
|
|
@@ -412,8 +457,7 @@ const forwardHttp = (req, res) => {
|
|
|
412
457
|
|
|
413
458
|
proxyReq.on('error', (error) => {
|
|
414
459
|
tracker.close({ statusCode: responseStatus, error: safeError(error) });
|
|
415
|
-
res
|
|
416
|
-
res.end('Bad Gateway');
|
|
460
|
+
sendBadGateway(res, error);
|
|
417
461
|
});
|
|
418
462
|
};
|
|
419
463
|
|
|
@@ -545,5 +589,7 @@ const shutdown = () => {
|
|
|
545
589
|
process.exit(0);
|
|
546
590
|
};
|
|
547
591
|
|
|
592
|
+
process.on('uncaughtException', (error) => exitAfterFatal('uncaughtException', error));
|
|
593
|
+
process.on('unhandledRejection', (error) => exitAfterFatal('unhandledRejection', error));
|
|
548
594
|
process.on('SIGINT', shutdown);
|
|
549
595
|
process.on('SIGTERM', shutdown);
|
package/index.d.ts
CHANGED
|
@@ -18,23 +18,14 @@ export interface StatusType {
|
|
|
18
18
|
Failed: 'FAILED';
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export interface ModeType {
|
|
22
|
-
Default: 'default';
|
|
23
|
-
CloakBrowser: 'cloakbrowser';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type ToolkitMode = 'default' | 'cloakbrowser';
|
|
27
|
-
|
|
28
21
|
export interface ConstantsModule {
|
|
29
22
|
Code: CodeType;
|
|
30
23
|
Status: StatusType;
|
|
31
|
-
Mode: ModeType;
|
|
32
24
|
PresetOfLiveViewKey: string;
|
|
33
25
|
Device: {
|
|
34
26
|
Desktop: 'desktop';
|
|
35
27
|
Mobile: 'mobile';
|
|
36
28
|
};
|
|
37
|
-
normalizeMode(value?: unknown, fallback?: ToolkitMode): ToolkitMode;
|
|
38
29
|
normalizeDevice(value?: unknown, fallback?: RuntimeDevice): RuntimeDevice;
|
|
39
30
|
ActorInfo: Record<string, ActorInfoItem>;
|
|
40
31
|
}
|
|
@@ -42,7 +33,7 @@ export interface ConstantsModule {
|
|
|
42
33
|
export type RuntimeDevice = 'desktop' | 'mobile';
|
|
43
34
|
|
|
44
35
|
export interface ActorShareInfo {
|
|
45
|
-
mode: 'dom' | 'response'
|
|
36
|
+
mode: 'dom' | 'response';
|
|
46
37
|
prefix: string;
|
|
47
38
|
xurl: Array<string | string[]>;
|
|
48
39
|
}
|
|
@@ -426,6 +417,10 @@ export interface CrawlerNavigationHook {
|
|
|
426
417
|
(crawlingContext: any, gotoOptions: Record<string, any>): Promise<void> | void;
|
|
427
418
|
}
|
|
428
419
|
|
|
420
|
+
export interface LaunchHooks {
|
|
421
|
+
modifyPageOptions?: (pageOptions: Record<string, any>, context: { pageId: string; browserController: any }) => Promise<void> | void;
|
|
422
|
+
}
|
|
423
|
+
|
|
429
424
|
export interface GetPlaywrightCrawlerOptionsInput {
|
|
430
425
|
customArgs?: string[];
|
|
431
426
|
proxyConfiguration?: ProxyConfiguration;
|
|
@@ -437,6 +432,7 @@ export interface GetPlaywrightCrawlerOptionsInput {
|
|
|
437
432
|
isRunningOnApify?: boolean;
|
|
438
433
|
launcher?: any;
|
|
439
434
|
runtimeState?: RuntimeEnvState | null;
|
|
435
|
+
hooks?: LaunchHooks;
|
|
440
436
|
preNavigationHooks?: CrawlerNavigationHook[];
|
|
441
437
|
postNavigationHooks?: CrawlerNavigationHook[];
|
|
442
438
|
}
|
|
@@ -450,47 +446,6 @@ export interface LaunchModule {
|
|
|
450
446
|
getPlaywrightCrawlerOptions(options?: GetPlaywrightCrawlerOptionsInput): PlaywrightCrawlerOptions;
|
|
451
447
|
}
|
|
452
448
|
|
|
453
|
-
export interface CloakBrowserResolvedProxy {
|
|
454
|
-
server: string;
|
|
455
|
-
username?: string;
|
|
456
|
-
password?: string;
|
|
457
|
-
bypass?: string;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
export interface CreateCloakBrowserCrawlerRuntimeInput {
|
|
461
|
-
proxyConfiguration?: ProxyConfiguration;
|
|
462
|
-
runInHeadfulMode?: boolean;
|
|
463
|
-
isRunningOnApify?: boolean;
|
|
464
|
-
launcher?: any;
|
|
465
|
-
cloakOptions?: Record<string, any>;
|
|
466
|
-
humanizeOptions?: boolean | Record<string, any>;
|
|
467
|
-
crawlerBaseOptions?: Partial<CrawlerBaseOptions>;
|
|
468
|
-
browserPoolOptions?: Record<string, any>;
|
|
469
|
-
launchContext?: Record<string, any>;
|
|
470
|
-
preNavigationHooks?: CrawlerNavigationHook[];
|
|
471
|
-
postNavigationHooks?: CrawlerNavigationHook[];
|
|
472
|
-
recommendedGotoOptions?: Record<string, any>;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
export interface CloakBrowserCrawlerRuntime {
|
|
476
|
-
headless: boolean;
|
|
477
|
-
launchOptions: LaunchOptions;
|
|
478
|
-
fingerprintArg: string;
|
|
479
|
-
crawlerOptions: PlaywrightCrawlerOptions;
|
|
480
|
-
closeActiveBrowsers(): Promise<void>;
|
|
481
|
-
forceTerminateActiveProcesses(): Promise<void>;
|
|
482
|
-
cleanup(): Promise<void>;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
export interface CloakLaunchModule extends Omit<LaunchModule, 'getPlaywrightCrawlerOptions'> {
|
|
486
|
-
getPlaywrightCrawlerOptions(options?: GetPlaywrightCrawlerOptionsInput | CreateCloakBrowserCrawlerRuntimeInput): Promise<PlaywrightCrawlerOptions>;
|
|
487
|
-
resolveProxyConfiguration(proxyConfiguration?: ProxyConfiguration): string | CloakBrowserResolvedProxy | null;
|
|
488
|
-
extractFingerprintArg(launchOptions?: LaunchOptions): string;
|
|
489
|
-
createStableGotoHook(recommendedGotoOptions?: Record<string, any>): CrawlerNavigationHook;
|
|
490
|
-
buildLaunchOptions(options?: Record<string, any>): Promise<LaunchOptions>;
|
|
491
|
-
createPlaywrightCrawlerRuntime(options?: CreateCloakBrowserCrawlerRuntimeInput): Promise<CloakBrowserCrawlerRuntime>;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
449
|
// =============================================================================
|
|
495
450
|
// LiveView
|
|
496
451
|
// =============================================================================
|
|
@@ -704,8 +659,6 @@ export interface ShareScreenCaptureOptions {
|
|
|
704
659
|
restore?: boolean;
|
|
705
660
|
/** 最大截图高度 (默认: 8000px) */
|
|
706
661
|
maxHeight?: number;
|
|
707
|
-
/** 截图水印合成模式;`cloakbrowser` 时走兼容分支。 */
|
|
708
|
-
mode?: 'default' | 'cloakbrowser';
|
|
709
662
|
/** 返回 base64 字符串的最大字节数,默认 5MiB。 */
|
|
710
663
|
maxBytes?: number;
|
|
711
664
|
/** maxBytes 的别名。 */
|
|
@@ -892,10 +845,6 @@ export interface PlaywrightToolKit {
|
|
|
892
845
|
};
|
|
893
846
|
}
|
|
894
847
|
|
|
895
|
-
export interface CloakPlaywrightToolKit extends PlaywrightToolKit {
|
|
896
|
-
Launch: CloakLaunchModule;
|
|
897
|
-
}
|
|
898
|
-
|
|
899
848
|
/** Browser/Extension version of the toolkit */
|
|
900
849
|
export interface BrowserPlaywrightToolKit {
|
|
901
850
|
Logger: LoggerModule;
|
|
@@ -910,5 +859,3 @@ export interface BrowserPlaywrightToolKit {
|
|
|
910
859
|
}
|
|
911
860
|
|
|
912
861
|
export declare function usePlaywrightToolKit(): PlaywrightToolKit;
|
|
913
|
-
export declare function usePlaywrightToolKit(mode: 'default'): PlaywrightToolKit;
|
|
914
|
-
export declare function usePlaywrightToolKit(mode: 'cloakbrowser'): CloakPlaywrightToolKit;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skrillex1224/playwright-toolkit",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.287",
|
|
4
4
|
"description": "一个在 Apify/Crawlee Actor 中启用实时截图视图的实用工具库。",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -59,16 +59,10 @@
|
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"apify": "*",
|
|
62
|
-
"cloakbrowser": "*",
|
|
63
62
|
"crawlee": "*",
|
|
64
63
|
"ghost-cursor-playwright": "*",
|
|
65
64
|
"playwright": "*"
|
|
66
65
|
},
|
|
67
|
-
"peerDependenciesMeta": {
|
|
68
|
-
"cloakbrowser": {
|
|
69
|
-
"optional": true
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
66
|
"devDependencies": {
|
|
73
67
|
"esbuild": "^0.24.2"
|
|
74
68
|
}
|