jumpy-lion 0.1.6-beta.21 → 0.1.6-beta.24

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.
Files changed (41) hide show
  1. package/README.md +188 -0
  2. package/dist/browser-controller.d.ts +13 -0
  3. package/dist/browser-controller.d.ts.map +1 -1
  4. package/dist/browser-controller.js +42 -0
  5. package/dist/browser-controller.js.map +1 -1
  6. package/dist/browser-plugin.d.ts +9 -0
  7. package/dist/browser-plugin.d.ts.map +1 -1
  8. package/dist/browser-plugin.js +61 -4
  9. package/dist/browser-plugin.js.map +1 -1
  10. package/dist/browser-process/anti-detect-config.d.ts +27 -0
  11. package/dist/browser-process/anti-detect-config.d.ts.map +1 -1
  12. package/dist/browser-process/anti-detect-config.js.map +1 -1
  13. package/dist/browser-process/browser.d.ts.map +1 -1
  14. package/dist/browser-process/browser.js +29 -6
  15. package/dist/browser-process/browser.js.map +1 -1
  16. package/dist/index.d.ts +5 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +6 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/page.d.ts +45 -0
  21. package/dist/page.d.ts.map +1 -1
  22. package/dist/page.js +228 -28
  23. package/dist/page.js.map +1 -1
  24. package/dist/session/inject-hook.d.ts +24 -0
  25. package/dist/session/inject-hook.d.ts.map +1 -0
  26. package/dist/session/inject-hook.js +80 -0
  27. package/dist/session/inject-hook.js.map +1 -0
  28. package/dist/session/save.d.ts +21 -0
  29. package/dist/session/save.d.ts.map +1 -0
  30. package/dist/session/save.js +163 -0
  31. package/dist/session/save.js.map +1 -0
  32. package/dist/session/tar-data-dir.d.ts +13 -0
  33. package/dist/session/tar-data-dir.d.ts.map +1 -0
  34. package/dist/session/tar-data-dir.js +107 -0
  35. package/dist/session/tar-data-dir.js.map +1 -0
  36. package/dist/session/types.d.ts +80 -0
  37. package/dist/session/types.d.ts.map +1 -0
  38. package/dist/session/types.js +29 -0
  39. package/dist/session/types.js.map +1 -0
  40. package/dist/tsconfig.build.tsbuildinfo +1 -1
  41. package/package.json +4 -2
@@ -0,0 +1,80 @@
1
+ import { log } from 'crawlee';
2
+ import { assertValidBundle } from './types.js';
3
+ /**
4
+ * Build the script that runs on every new document and replays per-origin
5
+ * localStorage / sessionStorage. Exported so unit tests can compile it in
6
+ * isolation and execute it against a JSDOM-like stub.
7
+ */
8
+ export function buildStorageInjectionScript(localStorageMap, sessionStorageMap) {
9
+ const localJson = JSON.stringify(localStorageMap);
10
+ const sessionJson = JSON.stringify(sessionStorageMap);
11
+ return `(() => {
12
+ try {
13
+ var __cdpcrawler_local = ${localJson};
14
+ var __cdpcrawler_session = ${sessionJson};
15
+ var __origin;
16
+ try { __origin = window.location.origin; } catch (e) { return; }
17
+ var __localValues = __cdpcrawler_local[__origin];
18
+ if (__localValues) {
19
+ for (var __k in __localValues) {
20
+ if (Object.prototype.hasOwnProperty.call(__localValues, __k)) {
21
+ try { window.localStorage.setItem(__k, __localValues[__k]); } catch (e) {}
22
+ }
23
+ }
24
+ }
25
+ var __sessionValues = __cdpcrawler_session[__origin];
26
+ if (__sessionValues) {
27
+ for (var __k2 in __sessionValues) {
28
+ if (Object.prototype.hasOwnProperty.call(__sessionValues, __k2)) {
29
+ try { window.sessionStorage.setItem(__k2, __sessionValues[__k2]); } catch (e) {}
30
+ }
31
+ }
32
+ }
33
+ } catch (e) { /* swallow — replay is best-effort */ }
34
+ })();`;
35
+ }
36
+ /**
37
+ * Cookies + per-origin storage injection. Runs once per page; safe to call before
38
+ * any navigation. Storage replay is registered as `Page.addScriptToEvaluateOnNewDocument`
39
+ * so it survives in-page redirects and manual reloads, matching the naver-session-test
40
+ * pattern.
41
+ */
42
+ export async function installSessionInjectionHook(page, bundle) {
43
+ assertValidBundle(bundle);
44
+ if (bundle.cookies.length > 0) {
45
+ try {
46
+ await page.setCookies(bundle.cookies);
47
+ log.debug('[session] Replayed cookies', { count: bundle.cookies.length });
48
+ }
49
+ catch (err) {
50
+ log.warning('[session] Failed to replay cookies', { err: err.message });
51
+ }
52
+ }
53
+ const hasStorage = Object.keys(bundle.localStorage).length > 0
54
+ || Object.keys(bundle.sessionStorage).length > 0;
55
+ if (hasStorage) {
56
+ try {
57
+ await page.ensurePageEnabled();
58
+ const script = buildStorageInjectionScript(bundle.localStorage, bundle.sessionStorage);
59
+ await page.client.Page.addScriptToEvaluateOnNewDocument({ source: script });
60
+ log.debug('[session] Registered per-origin storage replay script', {
61
+ localOrigins: Object.keys(bundle.localStorage).length,
62
+ sessionOrigins: Object.keys(bundle.sessionStorage).length,
63
+ });
64
+ }
65
+ catch (err) {
66
+ log.warning('[session] Failed to register storage replay script', { err: err.message });
67
+ }
68
+ }
69
+ }
70
+ /**
71
+ * Manual restore entry point — restores cookies + storage on an arbitrary page,
72
+ * for advanced users opening extra targets and wanting them to carry the same
73
+ * web state. The user-data-dir and fingerprintConfig sides of a bundle are
74
+ * applied at launch time (via launchOptions.sessionBundle) and cannot be
75
+ * swapped onto a running browser.
76
+ */
77
+ export async function restoreSession(page, bundle) {
78
+ await installSessionInjectionHook(page, bundle);
79
+ }
80
+ //# sourceMappingURL=inject-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-hook.js","sourceRoot":"","sources":["../../src/session/inject-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAG9B,OAAO,EAAE,iBAAiB,EAAuC,MAAM,YAAY,CAAC;AAEpF;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACvC,eAA2B,EAC3B,iBAA6B;IAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACtD,OAAO;;+BAEoB,SAAS;iCACP,WAAW;;;;;;;;;;;;;;;;;;;;MAoBtC,CAAC;AACP,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,IAAa,EAAE,MAAqB;IAClF,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtC,GAAG,CAAC,KAAK,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,GAAG,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,GAAG,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvF,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC;WACvD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAErD,IAAI,UAAU,EAAE,CAAC;QACb,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,2BAA2B,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;YACvF,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5E,GAAG,CAAC,KAAK,CAAC,uDAAuD,EAAE;gBAC/D,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM;gBACrD,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM;aAC5D,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,GAAG,CAAC,OAAO,CAAC,oDAAoD,EAAE,EAAE,GAAG,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvG,CAAC;IACL,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAa,EAAE,MAAqB;IACrE,MAAM,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type CdpPage from '../page.js';
2
+ import { type SessionBundle, type SessionBundleProxyMeta } from './types.js';
3
+ export interface SaveSessionOptions {
4
+ /** Capture and inline the Chrome user-data-dir as a gzipped tar. Default: true. */
5
+ includeUserDataDir?: boolean;
6
+ /** Call Storage.flushBrowserCookies before snapshotting cookies. Default: true. */
7
+ flushCookies?: boolean;
8
+ /** Override the user-data-dir path; defaults to the path the browser was launched with. */
9
+ userDataDirPath?: string;
10
+ /** URLs forwarded to Network.getCookies when Storage.getCookies is unavailable. Default: all cookies. */
11
+ cookieUrls?: string[];
12
+ /** Proxy metadata to stamp on the bundle for diagnostics (not replayed on restore). */
13
+ proxyMeta?: SessionBundleProxyMeta;
14
+ }
15
+ /**
16
+ * Capture a SessionBundle from a running CdpPage. Bundle is a single JSON-serializable
17
+ * value suitable for storage in an Apify KV store; pass it back via
18
+ * `launchOptions.sessionBundle` on a new crawler to reproduce the same browser state.
19
+ */
20
+ export declare function saveSession(page: CdpPage, options?: SaveSessionOptions): Promise<SessionBundle>;
21
+ //# sourceMappingURL=save.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/session/save.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,YAAY,CAAC;AAGtC,OAAO,EAEH,KAAK,aAAa,EAGlB,KAAK,sBAAsB,EAE9B,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IAC/B,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mFAAmF;IACnF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2FAA2F;IAC3F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,uFAAuF;IACvF,SAAS,CAAC,EAAE,sBAAsB,CAAC;CACtC;AA6FD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkFzG"}
@@ -0,0 +1,163 @@
1
+ import { log } from 'crawlee';
2
+ import { tarUserDataDir } from './tar-data-dir.js';
3
+ import { SCHEMA_VERSION, } from './types.js';
4
+ function originOf(url) {
5
+ try {
6
+ return new URL(url).origin;
7
+ }
8
+ catch {
9
+ return '';
10
+ }
11
+ }
12
+ async function collectCookies(page, urls) {
13
+ // Storage.getCookies returns cookies across the whole browser, which is what we want
14
+ // when the user has visited multiple origins. Fall back to Network.getCookies (page-scoped).
15
+ try {
16
+ const { Storage } = page.client;
17
+ if (Storage?.getCookies) {
18
+ const result = await Storage.getCookies();
19
+ return result.cookies ?? [];
20
+ }
21
+ }
22
+ catch (err) {
23
+ log.debug('[session] Storage.getCookies failed, falling back to Network.getCookies', { err: err.message });
24
+ }
25
+ return page.getCookies(urls);
26
+ }
27
+ async function collectStorage(page) {
28
+ const pageUrl = await page.evaluate(() => window.location.href);
29
+ const origin = originOf(pageUrl);
30
+ if (!origin) {
31
+ return { localStorage: {}, sessionStorage: {} };
32
+ }
33
+ const result = await page.evaluate(() => {
34
+ const local = {};
35
+ const session = {};
36
+ for (let i = 0; i < window.localStorage.length; i++) {
37
+ const k = window.localStorage.key(i);
38
+ if (k != null)
39
+ local[k] = window.localStorage.getItem(k) ?? '';
40
+ }
41
+ for (let i = 0; i < window.sessionStorage.length; i++) {
42
+ const k = window.sessionStorage.key(i);
43
+ if (k != null)
44
+ session[k] = window.sessionStorage.getItem(k) ?? '';
45
+ }
46
+ return { local, session };
47
+ });
48
+ return {
49
+ localStorage: Object.keys(result.local).length ? { [origin]: result.local } : {},
50
+ sessionStorage: Object.keys(result.session).length ? { [origin]: result.session } : {},
51
+ };
52
+ }
53
+ async function collectBrowserProfile(page) {
54
+ const profile = await page.evaluate(() => {
55
+ let webglRenderer = '';
56
+ let webglVendor = '';
57
+ try {
58
+ const canvas = document.createElement('canvas');
59
+ const gl = canvas.getContext('webgl');
60
+ if (gl) {
61
+ const dbg = gl.getExtension('WEBGL_debug_renderer_info');
62
+ if (dbg) {
63
+ webglRenderer = gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL) ?? '';
64
+ webglVendor = gl.getParameter(dbg.UNMASKED_VENDOR_WEBGL) ?? '';
65
+ }
66
+ }
67
+ }
68
+ catch { /* WebGL may be blocked; leave empty */ }
69
+ return {
70
+ userAgent: navigator.userAgent,
71
+ platform: navigator.platform,
72
+ language: navigator.language,
73
+ screenWidth: window.screen.width,
74
+ screenHeight: window.screen.height,
75
+ devicePixelRatio: window.devicePixelRatio,
76
+ webglRenderer,
77
+ webglVendor,
78
+ };
79
+ });
80
+ return profile;
81
+ }
82
+ function readPackageVersion() {
83
+ // Pulled from package.json at compile time would require tooling; reading it at
84
+ // runtime keeps things simple and ESM-safe. Falls back gracefully.
85
+ try {
86
+ return process.env.npm_package_version ?? '0.0.0';
87
+ }
88
+ catch {
89
+ return '0.0.0';
90
+ }
91
+ }
92
+ /**
93
+ * Capture a SessionBundle from a running CdpPage. Bundle is a single JSON-serializable
94
+ * value suitable for storage in an Apify KV store; pass it back via
95
+ * `launchOptions.sessionBundle` on a new crawler to reproduce the same browser state.
96
+ */
97
+ export async function saveSession(page, options = {}) {
98
+ const { includeUserDataDir = true, flushCookies = true, userDataDirPath, cookieUrls, proxyMeta, } = options;
99
+ const snapshot = page.getLaunchSnapshot();
100
+ if (!snapshot.fingerprintConfig) {
101
+ throw new Error('saveSession: fingerprintConfig is missing from the page launch snapshot. '
102
+ + 'Ensure the crawler was launched with useNativeStealth and that the page came from the CDPBrowserController.');
103
+ }
104
+ if (!snapshot.fingerprint) {
105
+ throw new Error('saveSession: fingerprint is missing from the page launch snapshot.');
106
+ }
107
+ if (!snapshot.resolvedLocale) {
108
+ throw new Error('saveSession: resolvedLocale is missing from the page launch snapshot.');
109
+ }
110
+ if (flushCookies) {
111
+ try {
112
+ await page.client
113
+ .Storage.flushBrowserCookies();
114
+ }
115
+ catch (err) {
116
+ log.debug('[session] Storage.flushBrowserCookies unavailable', { err: err.message });
117
+ }
118
+ }
119
+ const [cookies, storage, browserProfile] = await Promise.all([
120
+ collectCookies(page, cookieUrls),
121
+ collectStorage(page),
122
+ collectBrowserProfile(page),
123
+ ]);
124
+ let userDataDir = null;
125
+ if (includeUserDataDir) {
126
+ const dirPath = userDataDirPath ?? snapshot.userDataDir;
127
+ if (dirPath) {
128
+ userDataDir = await tarUserDataDir(dirPath);
129
+ if (!userDataDir) {
130
+ log.warning('[session] userDataDir path did not exist or was unreadable', { dirPath });
131
+ }
132
+ }
133
+ else {
134
+ log.warning('[session] includeUserDataDir was requested but no userDataDir path was recorded on the page snapshot');
135
+ }
136
+ }
137
+ const fpOpts = (snapshot.fingerprintOptions ?? {});
138
+ const fingerprintInput = {
139
+ ...fpOpts,
140
+ locale: typeof fpOpts.locale === 'string' ? fpOpts.locale : snapshot.resolvedLocale.locale,
141
+ languages: typeof fpOpts.languages === 'string' ? fpOpts.languages : snapshot.resolvedLocale.languages,
142
+ timezone: typeof fpOpts.timezone === 'string' ? fpOpts.timezone : snapshot.resolvedLocale.timezone,
143
+ platform: typeof fpOpts.platform === 'string' ? fpOpts.platform : undefined,
144
+ seedKey: typeof fpOpts.seedKey === 'string' ? fpOpts.seedKey : undefined,
145
+ useNonApifyFingerprints: false,
146
+ };
147
+ return {
148
+ schemaVersion: SCHEMA_VERSION,
149
+ createdAt: new Date().toISOString(),
150
+ createdBy: { package: 'cdp-crawler', version: readPackageVersion() },
151
+ cookies,
152
+ localStorage: storage.localStorage,
153
+ sessionStorage: storage.sessionStorage,
154
+ userDataDir,
155
+ fingerprintConfig: snapshot.fingerprintConfig,
156
+ fingerprint: snapshot.fingerprint,
157
+ fingerprintInput,
158
+ resolvedLocale: snapshot.resolvedLocale,
159
+ browserProfile,
160
+ proxyMeta: proxyMeta ?? (snapshot.proxyUrl ? { proxyUrl: snapshot.proxyUrl } : undefined),
161
+ };
162
+ }
163
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../../src/session/save.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { SessionBundleUserDataDir } from './types.js';
2
+ /**
3
+ * Pack a Chrome user-data-dir into a base64-encoded gzipped tar suitable for
4
+ * inclusion inside a JSON session bundle. Returns null when the directory does
5
+ * not exist (caller's choice whether to treat that as fatal).
6
+ */
7
+ export declare function tarUserDataDir(dirPath: string): Promise<SessionBundleUserDataDir | null>;
8
+ /**
9
+ * Extract a previously captured user-data-dir blob into destPath. Caller is
10
+ * responsible for ensuring destPath is empty (or will be merged into).
11
+ */
12
+ export declare function untarUserDataDir(payload: SessionBundleUserDataDir, destPath: string): Promise<void>;
13
+ //# sourceMappingURL=tar-data-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tar-data-dir.d.ts","sourceRoot":"","sources":["../../src/session/tar-data-dir.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAmD3D;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAkC9F;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYzG"}
@@ -0,0 +1,107 @@
1
+ import { Buffer } from 'buffer';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import * as tar from 'tar';
5
+ /**
6
+ * Files / subpaths we never include in the bundled tar. These are either
7
+ * process-bound singletons (which break restore on a new Chrome instance) or
8
+ * regenerable caches whose absence costs nothing on restore.
9
+ */
10
+ const ALWAYS_SKIP_PATTERNS = [
11
+ /(^|\/)SingletonCookie$/,
12
+ /(^|\/)SingletonLock$/,
13
+ /(^|\/)SingletonSocket$/,
14
+ /(^|\/)LOCK$/,
15
+ /(^|\/)CrashpadMetrics-.*$/,
16
+ /(^|\/)Crashpad(\/|$)/,
17
+ /(^|\/)BrowserMetrics(\/|$)/,
18
+ /(^|\/)GrShaderCache(\/|$)/,
19
+ /(^|\/)ShaderCache(\/|$)/,
20
+ /(^|\/)GraphiteDawnCache(\/|$)/,
21
+ /(^|\/)GPUCache(\/|$)/,
22
+ /(^|\/)Code Cache(\/|$)/,
23
+ /(^|\/)component_crx_cache(\/|$)/,
24
+ /\.tmp$/,
25
+ ];
26
+ function shouldSkip(relPath) {
27
+ return ALWAYS_SKIP_PATTERNS.some((p) => (typeof p === 'string' ? relPath === p : p.test(relPath)));
28
+ }
29
+ async function countFiles(root) {
30
+ let count = 0;
31
+ async function walk(dir, rel) {
32
+ let entries;
33
+ try {
34
+ entries = await fs.readdir(dir, { withFileTypes: true });
35
+ }
36
+ catch {
37
+ return;
38
+ }
39
+ for (const e of entries) {
40
+ const childRel = rel ? `${rel}/${e.name}` : e.name;
41
+ if (shouldSkip(childRel))
42
+ continue;
43
+ if (e.isDirectory()) {
44
+ await walk(path.join(dir, e.name), childRel);
45
+ }
46
+ else if (e.isFile()) {
47
+ count++;
48
+ }
49
+ }
50
+ }
51
+ await walk(root, '');
52
+ return count;
53
+ }
54
+ /**
55
+ * Pack a Chrome user-data-dir into a base64-encoded gzipped tar suitable for
56
+ * inclusion inside a JSON session bundle. Returns null when the directory does
57
+ * not exist (caller's choice whether to treat that as fatal).
58
+ */
59
+ export async function tarUserDataDir(dirPath) {
60
+ try {
61
+ const st = await fs.stat(dirPath);
62
+ if (!st.isDirectory())
63
+ return null;
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ const capturedFiles = await countFiles(dirPath);
69
+ const chunks = [];
70
+ await new Promise((resolve, reject) => {
71
+ const stream = tar.create({
72
+ gzip: true,
73
+ cwd: dirPath,
74
+ portable: true,
75
+ follow: false,
76
+ filter: (p) => !shouldSkip(p.replace(/^\.?\//, '')),
77
+ }, ['.']);
78
+ stream.on('data', (chunk) => chunks.push(chunk));
79
+ stream.on('end', () => resolve());
80
+ stream.on('error', reject);
81
+ });
82
+ const buf = Buffer.concat(chunks);
83
+ return {
84
+ encoding: 'base64+gzip+tar',
85
+ bytes: buf.toString('base64'),
86
+ sizeBytes: buf.length,
87
+ capturedFiles,
88
+ };
89
+ }
90
+ /**
91
+ * Extract a previously captured user-data-dir blob into destPath. Caller is
92
+ * responsible for ensuring destPath is empty (or will be merged into).
93
+ */
94
+ export async function untarUserDataDir(payload, destPath) {
95
+ if (payload.encoding !== 'base64+gzip+tar') {
96
+ throw new Error(`Unsupported userDataDir encoding: ${payload.encoding}`);
97
+ }
98
+ await fs.mkdir(destPath, { recursive: true });
99
+ const buf = Buffer.from(payload.bytes, 'base64');
100
+ await new Promise((resolve, reject) => {
101
+ const extractor = tar.extract({ cwd: destPath, strip: 0 });
102
+ extractor.on('finish', () => resolve());
103
+ extractor.on('error', reject);
104
+ extractor.end(buf);
105
+ });
106
+ }
107
+ //# sourceMappingURL=tar-data-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tar-data-dir.js","sourceRoot":"","sources":["../../src/session/tar-data-dir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import type { BrowserFingerprintWithHeaders } from 'fingerprint-generator';
2
+ import type { FingerprintConfigJson } from '../browser-process/anti-detect-config.js';
3
+ import type { ResolvedLocale } from '../fingerprinting/locale-resolver.js';
4
+ import type { Cookie } from '../page.js';
5
+ export declare const SCHEMA_VERSION: 1;
6
+ /**
7
+ * Snapshot of launch-time inputs that saveSession() needs to read off a CdpPage
8
+ * to assemble a bundle. Populated by CDPBrowserController before handing the
9
+ * page to user code, so saveSession is a pure call against the page surface.
10
+ */
11
+ export interface LaunchSnapshot {
12
+ fingerprintConfig?: FingerprintConfigJson;
13
+ fingerprintOptions?: Record<string, unknown>;
14
+ resolvedLocale?: ResolvedLocale;
15
+ fingerprint?: BrowserFingerprintWithHeaders;
16
+ userDataDir?: string;
17
+ proxyUrl?: string;
18
+ /** Set when the page was launched from a previously-saved bundle. */
19
+ sessionBundle?: SessionBundle;
20
+ }
21
+ /**
22
+ * Cookie shape as accepted by CDP `Network.setCookie`. Aliased to the Cookie
23
+ * already used across CdpPage so save/restore round-trips byte-for-byte.
24
+ */
25
+ export type SerializedCookie = Cookie;
26
+ /** Origin → key-value map for localStorage / sessionStorage. */
27
+ export type StorageMap = Record<string, Record<string, string>>;
28
+ export interface SessionBundleUserDataDir {
29
+ encoding: 'base64+gzip+tar';
30
+ bytes: string;
31
+ sizeBytes: number;
32
+ capturedFiles: number;
33
+ }
34
+ export interface SessionBundleBrowserProfile {
35
+ userAgent: string;
36
+ platform: string;
37
+ language: string;
38
+ screenWidth: number;
39
+ screenHeight: number;
40
+ devicePixelRatio: number;
41
+ webglRenderer: string;
42
+ webglVendor: string;
43
+ }
44
+ export interface SessionBundleFingerprintInput {
45
+ locale?: string;
46
+ languages?: string;
47
+ timezone?: string;
48
+ platform?: string;
49
+ seedKey?: string;
50
+ /** Pinned on restore so the captured fingerprintConfig is not regenerated. */
51
+ useNonApifyFingerprints: false;
52
+ /** Any other fingerprintOptions keys carried through verbatim. */
53
+ [key: string]: unknown;
54
+ }
55
+ export interface SessionBundleProxyMeta {
56
+ proxyUrl?: string;
57
+ sessionId?: string;
58
+ countryCode?: string;
59
+ }
60
+ export interface SessionBundle {
61
+ schemaVersion: typeof SCHEMA_VERSION;
62
+ createdAt: string;
63
+ createdBy?: {
64
+ package: 'cdp-crawler';
65
+ version: string;
66
+ };
67
+ cookies: SerializedCookie[];
68
+ localStorage: StorageMap;
69
+ sessionStorage: StorageMap;
70
+ userDataDir: SessionBundleUserDataDir | null;
71
+ fingerprintConfig: FingerprintConfigJson;
72
+ fingerprint: BrowserFingerprintWithHeaders;
73
+ fingerprintInput: SessionBundleFingerprintInput;
74
+ resolvedLocale: ResolvedLocale;
75
+ browserProfile: SessionBundleBrowserProfile;
76
+ proxyMeta?: SessionBundleProxyMeta;
77
+ }
78
+ /** Runtime guard so a hand-edited / partial bundle fails fast with a clear message. */
79
+ export declare function assertValidBundle(value: unknown): asserts value is SessionBundle;
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export const SCHEMA_VERSION = 1;
2
+ /** Runtime guard so a hand-edited / partial bundle fails fast with a clear message. */
3
+ export function assertValidBundle(value) {
4
+ if (!value || typeof value !== 'object') {
5
+ throw new Error('Invalid session bundle: expected an object');
6
+ }
7
+ const b = value;
8
+ if (b.schemaVersion !== SCHEMA_VERSION) {
9
+ throw new Error(`Unsupported session bundle schemaVersion: ${String(b.schemaVersion)} (expected ${SCHEMA_VERSION})`);
10
+ }
11
+ for (const key of ['cookies', 'localStorage', 'sessionStorage', 'fingerprintConfig', 'fingerprint', 'fingerprintInput', 'resolvedLocale', 'browserProfile']) {
12
+ if (b[key] === undefined || b[key] === null) {
13
+ throw new Error(`Invalid session bundle: missing required key "${key}"`);
14
+ }
15
+ }
16
+ if (!Array.isArray(b.cookies)) {
17
+ throw new Error('Invalid session bundle: "cookies" must be an array');
18
+ }
19
+ if (b.userDataDir !== null && typeof b.userDataDir !== 'object') {
20
+ throw new Error('Invalid session bundle: "userDataDir" must be an object or null');
21
+ }
22
+ if (b.userDataDir) {
23
+ const u = b.userDataDir;
24
+ if (u.encoding !== 'base64+gzip+tar' || typeof u.bytes !== 'string') {
25
+ throw new Error('Invalid session bundle: malformed userDataDir payload');
26
+ }
27
+ }
28
+ }
29
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,cAAc,GAAG,CAAU,CAAC;AAoFzC,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC5C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,CAAC,CAAC,aAAa,KAAK,cAAc,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACX,6CAA6C,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,cAAc,cAAc,GAAG,CACtG,CAAC;IACN,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,gBAAgB,CAAU,EAAE,CAAC;QACnK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,iDAAiD,GAAG,GAAG,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAsC,CAAC;QACnD,IAAI,CAAC,CAAC,QAAQ,KAAK,iBAAiB,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC;AACL,CAAC"}