camou 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.
Files changed (89) hide show
  1. package/README.md +229 -0
  2. package/dist/browser/actions.d.ts +4 -0
  3. package/dist/browser/actions.js +15 -0
  4. package/dist/browser/actions.js.map +1 -0
  5. package/dist/browser/manager.d.ts +85 -0
  6. package/dist/browser/manager.js +300 -0
  7. package/dist/browser/manager.js.map +1 -0
  8. package/dist/browser/snapshot.d.ts +17 -0
  9. package/dist/browser/snapshot.js +93 -0
  10. package/dist/browser/snapshot.js.map +1 -0
  11. package/dist/browser/tabs.d.ts +24 -0
  12. package/dist/browser/tabs.js +8 -0
  13. package/dist/browser/tabs.js.map +1 -0
  14. package/dist/camoufox/config.d.ts +67 -0
  15. package/dist/camoufox/config.js +121 -0
  16. package/dist/camoufox/config.js.map +1 -0
  17. package/dist/camoufox/env.d.ts +3 -0
  18. package/dist/camoufox/env.js +27 -0
  19. package/dist/camoufox/env.js.map +1 -0
  20. package/dist/camoufox/installer.d.ts +24 -0
  21. package/dist/camoufox/installer.js +291 -0
  22. package/dist/camoufox/installer.js.map +1 -0
  23. package/dist/camoufox/launcher.d.ts +22 -0
  24. package/dist/camoufox/launcher.js +105 -0
  25. package/dist/camoufox/launcher.js.map +1 -0
  26. package/dist/camoufox/prefs.d.ts +5 -0
  27. package/dist/camoufox/prefs.js +27 -0
  28. package/dist/camoufox/prefs.js.map +1 -0
  29. package/dist/camoufox/presets.d.ts +14 -0
  30. package/dist/camoufox/presets.js +73 -0
  31. package/dist/camoufox/presets.js.map +1 -0
  32. package/dist/camoufox/registry.d.ts +30 -0
  33. package/dist/camoufox/registry.js +195 -0
  34. package/dist/camoufox/registry.js.map +1 -0
  35. package/dist/camoufox/validation.d.ts +4 -0
  36. package/dist/camoufox/validation.js +103 -0
  37. package/dist/camoufox/validation.js.map +1 -0
  38. package/dist/cli/daemon.d.ts +2 -0
  39. package/dist/cli/daemon.js +59 -0
  40. package/dist/cli/daemon.js.map +1 -0
  41. package/dist/cli/main.d.ts +2 -0
  42. package/dist/cli/main.js +147 -0
  43. package/dist/cli/main.js.map +1 -0
  44. package/dist/cli/output.d.ts +1 -0
  45. package/dist/cli/output.js +108 -0
  46. package/dist/cli/output.js.map +1 -0
  47. package/dist/cli/program.d.ts +42 -0
  48. package/dist/cli/program.js +214 -0
  49. package/dist/cli/program.js.map +1 -0
  50. package/dist/daemon/daemon.d.ts +12 -0
  51. package/dist/daemon/daemon.js +36 -0
  52. package/dist/daemon/daemon.js.map +1 -0
  53. package/dist/daemon/main.d.ts +2 -0
  54. package/dist/daemon/main.js +28 -0
  55. package/dist/daemon/main.js.map +1 -0
  56. package/dist/daemon/router.d.ts +7 -0
  57. package/dist/daemon/router.js +43 -0
  58. package/dist/daemon/router.js.map +1 -0
  59. package/dist/daemon/runtime.d.ts +11 -0
  60. package/dist/daemon/runtime.js +54 -0
  61. package/dist/daemon/runtime.js.map +1 -0
  62. package/dist/doctor/diagnostics.d.ts +38 -0
  63. package/dist/doctor/diagnostics.js +152 -0
  64. package/dist/doctor/diagnostics.js.map +1 -0
  65. package/dist/ipc/client.d.ts +6 -0
  66. package/dist/ipc/client.js +63 -0
  67. package/dist/ipc/client.js.map +1 -0
  68. package/dist/ipc/protocol.d.ts +775 -0
  69. package/dist/ipc/protocol.js +128 -0
  70. package/dist/ipc/protocol.js.map +1 -0
  71. package/dist/ipc/server.d.ts +10 -0
  72. package/dist/ipc/server.js +99 -0
  73. package/dist/ipc/server.js.map +1 -0
  74. package/dist/state/paths.d.ts +32 -0
  75. package/dist/state/paths.js +121 -0
  76. package/dist/state/paths.js.map +1 -0
  77. package/dist/state/store.d.ts +4 -0
  78. package/dist/state/store.js +30 -0
  79. package/dist/state/store.js.map +1 -0
  80. package/dist/util/errors.d.ts +45 -0
  81. package/dist/util/errors.js +82 -0
  82. package/dist/util/errors.js.map +1 -0
  83. package/dist/util/log.d.ts +19 -0
  84. package/dist/util/log.js +71 -0
  85. package/dist/util/log.js.map +1 -0
  86. package/dist/util/platform.d.ts +12 -0
  87. package/dist/util/platform.js +44 -0
  88. package/dist/util/platform.js.map +1 -0
  89. package/package.json +58 -0
@@ -0,0 +1,93 @@
1
+ const SNAPSHOT_ATTRIBUTE = 'data-camoucli-ref';
2
+ export async function clearSnapshotRefs(page) {
3
+ await page
4
+ .evaluate((attributeName) => {
5
+ document.querySelectorAll(`[${attributeName}]`).forEach((element) => {
6
+ element.removeAttribute(attributeName);
7
+ });
8
+ }, SNAPSHOT_ATTRIBUTE)
9
+ .catch(() => undefined);
10
+ }
11
+ export async function takeSnapshot(page, interactiveOnly) {
12
+ await clearSnapshotRefs(page);
13
+ const entries = await page.evaluate(({ interactiveOnly, attributeName }) => {
14
+ const interactiveSelectors = [
15
+ 'a[href]',
16
+ 'button',
17
+ 'input',
18
+ 'textarea',
19
+ 'select',
20
+ '[role="button"]',
21
+ '[role="link"]',
22
+ '[role="textbox"]',
23
+ '[tabindex]:not([tabindex="-1"])',
24
+ ];
25
+ const broadSelectors = [
26
+ ...interactiveSelectors,
27
+ 'h1',
28
+ 'h2',
29
+ 'h3',
30
+ 'p',
31
+ 'li',
32
+ 'label',
33
+ 'article',
34
+ 'section',
35
+ ];
36
+ const selectors = interactiveOnly ? interactiveSelectors : broadSelectors;
37
+ function isVisible(element) {
38
+ if (!(element instanceof HTMLElement)) {
39
+ return false;
40
+ }
41
+ const style = window.getComputedStyle(element);
42
+ const rect = element.getBoundingClientRect();
43
+ return (style.display !== 'none' &&
44
+ style.visibility !== 'hidden' &&
45
+ style.opacity !== '0' &&
46
+ rect.width > 0 &&
47
+ rect.height > 0);
48
+ }
49
+ function summarizeText(element) {
50
+ const directText = element.getAttribute('aria-label') ||
51
+ element.getAttribute('alt') ||
52
+ ('value' in element ? String(element.value || '') : '') ||
53
+ ('placeholder' in element ? String(element.placeholder || '') : '') ||
54
+ element.innerText ||
55
+ element.textContent ||
56
+ '';
57
+ return directText.replace(/\s+/g, ' ').trim().slice(0, 140);
58
+ }
59
+ return Array.from(document.querySelectorAll(selectors.join(',')))
60
+ .filter((element, index, list) => list.indexOf(element) === index)
61
+ .filter(isVisible)
62
+ .map((element, index) => {
63
+ const refId = `e${index + 1}`;
64
+ element.setAttribute(attributeName, refId);
65
+ const tag = element.tagName.toLowerCase();
66
+ const role = element.getAttribute('role') || undefined;
67
+ const inputType = element instanceof HTMLInputElement ? element.type || 'text' : undefined;
68
+ const text = summarizeText(element) || tag;
69
+ return {
70
+ ref: `@${refId}`,
71
+ selector: `[${attributeName}="${refId}"]`,
72
+ tag,
73
+ role,
74
+ inputType,
75
+ text,
76
+ };
77
+ });
78
+ }, { interactiveOnly, attributeName: SNAPSHOT_ATTRIBUTE });
79
+ const refs = Object.fromEntries(entries.map((entry) => [entry.ref, entry.selector]));
80
+ const text = entries
81
+ .map((entry) => {
82
+ const detail = entry.role ?? entry.inputType;
83
+ return `${entry.ref} ${entry.tag}${detail ? `[${detail}]` : ''} ${JSON.stringify(entry.text)}`;
84
+ })
85
+ .join('\n');
86
+ return {
87
+ interactive: interactiveOnly,
88
+ text,
89
+ entries,
90
+ refs,
91
+ };
92
+ }
93
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/browser/snapshot.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAkB/C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAU;IAChD,MAAM,IAAI;SACP,QAAQ,CAAC,CAAC,aAAa,EAAE,EAAE;QAC1B,QAAQ,CAAC,gBAAgB,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClE,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,kBAAkB,CAAC;SACrB,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAU,EAAE,eAAwB;IACrE,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CACjC,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,EAAE,EAAE;QACrC,MAAM,oBAAoB,GAAG;YAC3B,SAAS;YACT,QAAQ;YACR,OAAO;YACP,UAAU;YACV,QAAQ;YACR,iBAAiB;YACjB,eAAe;YACf,kBAAkB;YAClB,iCAAiC;SAClC,CAAC;QAEF,MAAM,cAAc,GAAG;YACrB,GAAG,oBAAoB;YACvB,IAAI;YACJ,IAAI;YACJ,IAAI;YACJ,GAAG;YACH,IAAI;YACJ,OAAO;YACP,SAAS;YACT,SAAS;SACV,CAAC;QAEF,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,cAAc,CAAC;QAE1E,SAAS,SAAS,CAAC,OAAgB;YACjC,IAAI,CAAC,CAAC,OAAO,YAAY,WAAW,CAAC,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC;YACf,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAC7C,OAAO,CACL,KAAK,CAAC,OAAO,KAAK,MAAM;gBACxB,KAAK,CAAC,UAAU,KAAK,QAAQ;gBAC7B,KAAK,CAAC,OAAO,KAAK,GAAG;gBACrB,IAAI,CAAC,KAAK,GAAG,CAAC;gBACd,IAAI,CAAC,MAAM,GAAG,CAAC,CAChB,CAAC;QACJ,CAAC;QAED,SAAS,aAAa,CAAC,OAAoB;YACzC,MAAM,UAAU,GACd,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC;gBAClC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC;gBAC3B,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,OAA4B,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7E,CAAC,aAAa,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,OAA4B,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzF,OAAO,CAAC,SAAS;gBACjB,OAAO,CAAC,WAAW;gBACnB,EAAE,CAAC;YAEL,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;aAC9D,MAAM,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC;aACjE,MAAM,CAAC,SAAS,CAAC;aACjB,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;YACvD,MAAM,SAAS,GAAG,OAAO,YAAY,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3F,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC;YAC3C,OAAO;gBACL,GAAG,EAAE,IAAI,KAAK,EAAE;gBAChB,QAAQ,EAAE,IAAI,aAAa,KAAK,KAAK,IAAI;gBACzC,GAAG;gBACH,IAAI;gBACJ,SAAS;gBACT,IAAI;aACL,CAAC;QACJ,CAAC,CAAC,CAAC;IACP,CAAC,EACD,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,CACvD,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,IAAI,GAAG,OAAO;SACjB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC;QAC7C,OAAO,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IACjG,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;QACL,WAAW,EAAE,eAAe;QAC5B,IAAI;QACJ,OAAO;QACP,IAAI;KACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { BrowserContext, Page } from 'playwright-core';
2
+ import type { SessionPaths } from '../state/paths.js';
3
+ import type { LaunchInput, ResolvedLaunchConfig } from '../camoufox/config.js';
4
+ import type { SnapshotResult } from './snapshot.js';
5
+ export type SessionStatus = 'stopped' | 'starting' | 'running' | 'error';
6
+ export interface TabRuntime {
7
+ name: string;
8
+ page: Page;
9
+ refMap: Map<string, string>;
10
+ lastSnapshot?: SnapshotResult | undefined;
11
+ }
12
+ export interface SessionRuntime {
13
+ name: string;
14
+ status: SessionStatus;
15
+ context: BrowserContext;
16
+ tabs: Map<string, TabRuntime>;
17
+ browserVersion: string;
18
+ installPath: string;
19
+ paths: SessionPaths;
20
+ resolvedConfig: ResolvedLaunchConfig;
21
+ launchInput: LaunchInput;
22
+ startedAt: string;
23
+ }
24
+ export declare function createTabRuntime(name: string, page: Page): TabRuntime;
@@ -0,0 +1,8 @@
1
+ export function createTabRuntime(name, page) {
2
+ return {
3
+ name,
4
+ page,
5
+ refMap: new Map(),
6
+ };
7
+ }
8
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/browser/tabs.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,IAAU;IACvD,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,MAAM,EAAE,IAAI,GAAG,EAAkB;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ import { type FirefoxUserPrefs } from './prefs.js';
3
+ export declare const launchInputSchema: z.ZodObject<{
4
+ headless: z.ZodOptional<z.ZodBoolean>;
5
+ configPath: z.ZodOptional<z.ZodString>;
6
+ configJson: z.ZodOptional<z.ZodString>;
7
+ prefsPath: z.ZodOptional<z.ZodString>;
8
+ prefsJson: z.ZodOptional<z.ZodString>;
9
+ preset: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
10
+ proxy: z.ZodOptional<z.ZodString>;
11
+ locale: z.ZodOptional<z.ZodString>;
12
+ timezone: z.ZodOptional<z.ZodString>;
13
+ width: z.ZodOptional<z.ZodNumber>;
14
+ height: z.ZodOptional<z.ZodNumber>;
15
+ browser: z.ZodOptional<z.ZodString>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ headless?: boolean | undefined;
18
+ configPath?: string | undefined;
19
+ configJson?: string | undefined;
20
+ prefsPath?: string | undefined;
21
+ prefsJson?: string | undefined;
22
+ preset?: string[] | undefined;
23
+ proxy?: string | undefined;
24
+ locale?: string | undefined;
25
+ timezone?: string | undefined;
26
+ width?: number | undefined;
27
+ height?: number | undefined;
28
+ browser?: string | undefined;
29
+ }, {
30
+ headless?: boolean | undefined;
31
+ configPath?: string | undefined;
32
+ configJson?: string | undefined;
33
+ prefsPath?: string | undefined;
34
+ prefsJson?: string | undefined;
35
+ preset?: string[] | undefined;
36
+ proxy?: string | undefined;
37
+ locale?: string | undefined;
38
+ timezone?: string | undefined;
39
+ width?: number | undefined;
40
+ height?: number | undefined;
41
+ browser?: string | undefined;
42
+ }>;
43
+ export type LaunchInput = z.infer<typeof launchInputSchema>;
44
+ export interface ProxySettings {
45
+ server: string;
46
+ }
47
+ export interface ResolvedLaunchConfig {
48
+ headless: boolean;
49
+ browser?: string | undefined;
50
+ presetNames: string[];
51
+ camouConfig: Record<string, unknown>;
52
+ firefoxUserPrefs: FirefoxUserPrefs;
53
+ proxy?: ProxySettings | undefined;
54
+ locale?: string | undefined;
55
+ timezoneId?: string | undefined;
56
+ viewport?: {
57
+ width: number;
58
+ height: number;
59
+ } | undefined;
60
+ }
61
+ export declare function loadJsonObjectFile(filePath: string, label: string): Promise<Record<string, unknown>>;
62
+ export declare function parseJsonObjectString(raw: string, label: string): Record<string, unknown>;
63
+ export declare function resolveJsonObjectInput(pathValue: string | undefined, jsonValue: string | undefined, label: string): Promise<Record<string, unknown>>;
64
+ export declare function parseProxyString(proxy?: string): ProxySettings | undefined;
65
+ export declare function validateLocale(locale?: string): string | undefined;
66
+ export declare function validateTimezone(timezone?: string): string | undefined;
67
+ export declare function resolveLaunchConfig(input: LaunchInput): Promise<ResolvedLaunchConfig>;
@@ -0,0 +1,121 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { z } from 'zod';
3
+ import { ValidationError } from '../util/errors.js';
4
+ import { parseFirefoxUserPrefs } from './prefs.js';
5
+ import { resolveCamoufoxPresets } from './presets.js';
6
+ const jsonObjectSchema = z.record(z.string(), z.unknown());
7
+ export const launchInputSchema = z.object({
8
+ headless: z.boolean().optional(),
9
+ configPath: z.string().optional(),
10
+ configJson: z.string().optional(),
11
+ prefsPath: z.string().optional(),
12
+ prefsJson: z.string().optional(),
13
+ preset: z.array(z.string()).optional(),
14
+ proxy: z.string().optional(),
15
+ locale: z.string().optional(),
16
+ timezone: z.string().optional(),
17
+ width: z.number().int().positive().optional(),
18
+ height: z.number().int().positive().optional(),
19
+ browser: z.string().optional(),
20
+ });
21
+ export async function loadJsonObjectFile(filePath, label) {
22
+ let raw;
23
+ try {
24
+ raw = await readFile(filePath, 'utf8');
25
+ }
26
+ catch (error) {
27
+ throw new ValidationError(`Unable to read ${label} file at ${filePath}.`, { filePath }, error);
28
+ }
29
+ return parseJsonObjectString(raw, label);
30
+ }
31
+ export function parseJsonObjectString(raw, label) {
32
+ let parsed;
33
+ try {
34
+ parsed = JSON.parse(raw);
35
+ }
36
+ catch (error) {
37
+ throw new ValidationError(`Unable to parse ${label} JSON.`, undefined, error);
38
+ }
39
+ const result = jsonObjectSchema.safeParse(parsed);
40
+ if (!result.success) {
41
+ throw new ValidationError(`${label} must be a JSON object.`);
42
+ }
43
+ return result.data;
44
+ }
45
+ export async function resolveJsonObjectInput(pathValue, jsonValue, label) {
46
+ if (pathValue && jsonValue) {
47
+ throw new ValidationError(`Pass either ${label} path or ${label} JSON, not both.`);
48
+ }
49
+ if (pathValue) {
50
+ return loadJsonObjectFile(pathValue, label);
51
+ }
52
+ if (jsonValue) {
53
+ return parseJsonObjectString(jsonValue, label);
54
+ }
55
+ return {};
56
+ }
57
+ export function parseProxyString(proxy) {
58
+ if (!proxy) {
59
+ return undefined;
60
+ }
61
+ try {
62
+ const url = new URL(proxy);
63
+ if (!['http:', 'https:', 'socks5:', 'socks4:'].includes(url.protocol)) {
64
+ throw new Error(`Unsupported protocol ${url.protocol}`);
65
+ }
66
+ return { server: url.toString() };
67
+ }
68
+ catch (error) {
69
+ throw new ValidationError(`Invalid proxy URL: ${proxy}`, undefined, error);
70
+ }
71
+ }
72
+ export function validateLocale(locale) {
73
+ if (!locale) {
74
+ return undefined;
75
+ }
76
+ if (Intl.DateTimeFormat.supportedLocalesOf([locale]).length === 0) {
77
+ throw new ValidationError(`Invalid locale: ${locale}`);
78
+ }
79
+ return locale;
80
+ }
81
+ export function validateTimezone(timezone) {
82
+ if (!timezone) {
83
+ return undefined;
84
+ }
85
+ try {
86
+ new Intl.DateTimeFormat('en-US', { timeZone: timezone }).format(new Date());
87
+ }
88
+ catch (error) {
89
+ throw new ValidationError(`Invalid timezone: ${timezone}`, undefined, error);
90
+ }
91
+ return timezone;
92
+ }
93
+ export async function resolveLaunchConfig(input) {
94
+ const presets = resolveCamoufoxPresets(input.preset);
95
+ const rawConfig = await resolveJsonObjectInput(input.configPath, input.configJson, 'config');
96
+ const rawPrefs = await resolveJsonObjectInput(input.prefsPath, input.prefsJson, 'prefs');
97
+ const camouConfig = {
98
+ ...presets.camouConfig,
99
+ ...rawConfig,
100
+ };
101
+ const firefoxUserPrefs = parseFirefoxUserPrefs({
102
+ ...presets.firefoxUserPrefs,
103
+ ...rawPrefs,
104
+ });
105
+ const viewport = input.width && input.height ? { width: input.width, height: input.height } : undefined;
106
+ if ((input.width && !input.height) || (!input.width && input.height)) {
107
+ throw new ValidationError('Both width and height are required when setting window size.');
108
+ }
109
+ return {
110
+ headless: input.headless ?? false,
111
+ browser: input.browser,
112
+ presetNames: presets.presetNames,
113
+ camouConfig,
114
+ firefoxUserPrefs,
115
+ proxy: parseProxyString(input.proxy),
116
+ locale: validateLocale(input.locale),
117
+ timezoneId: validateTimezone(input.timezone),
118
+ viewport,
119
+ };
120
+ }
121
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/camoufox/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function getCamouConfigChunkSize(platform?: NodeJS.Platform): number;
2
+ export declare function chunkCamouConfig(config: Record<string, unknown> | string, platform?: NodeJS.Platform): string[];
3
+ export declare function buildCamouConfigEnv(config: Record<string, unknown>, baseEnv?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): Record<string, string>;
@@ -0,0 +1,27 @@
1
+ const CAMOU_CONFIG_KEY = /^CAMOU_CONFIG_\d+$/;
2
+ export function getCamouConfigChunkSize(platform = process.platform) {
3
+ return platform === 'win32' ? 2047 : 32767;
4
+ }
5
+ export function chunkCamouConfig(config, platform = process.platform) {
6
+ const serialized = typeof config === 'string' ? config : JSON.stringify(config);
7
+ const chunkSize = getCamouConfigChunkSize(platform);
8
+ const chunks = [];
9
+ for (let index = 0; index < serialized.length; index += chunkSize) {
10
+ chunks.push(serialized.slice(index, index + chunkSize));
11
+ }
12
+ return chunks;
13
+ }
14
+ export function buildCamouConfigEnv(config, baseEnv = process.env, platform = process.platform) {
15
+ const nextEnv = {};
16
+ for (const [key, value] of Object.entries(baseEnv)) {
17
+ if (!CAMOU_CONFIG_KEY.test(key) && value !== undefined) {
18
+ nextEnv[key] = value;
19
+ }
20
+ }
21
+ const chunks = chunkCamouConfig(config, platform);
22
+ for (const [index, chunk] of chunks.entries()) {
23
+ nextEnv[`CAMOU_CONFIG_${index + 1}`] = chunk;
24
+ }
25
+ return nextEnv;
26
+ }
27
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/camoufox/env.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAE9C,MAAM,UAAU,uBAAuB,CAAC,WAA4B,OAAO,CAAC,QAAQ;IAClF,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAwC,EACxC,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChF,MAAM,SAAS,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAA+B,EAC/B,UAA6B,OAAO,CAAC,GAAG,EACxC,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9C,OAAO,CAAC,gBAAgB,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IAC/C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { CamoucliPaths } from '../state/paths.js';
2
+ import type { Logger } from '../util/log.js';
3
+ import { type BrowserLaunchProbe } from './launcher.js';
4
+ export interface ResolvedRelease {
5
+ repo: string;
6
+ tag: string;
7
+ version: string;
8
+ assetName: string;
9
+ assetUrl: string;
10
+ prerelease: boolean;
11
+ }
12
+ export declare function resolveRelease(version?: string): Promise<ResolvedRelease>;
13
+ export declare function installCamoufox(paths: CamoucliPaths, options?: {
14
+ version?: string | undefined;
15
+ force?: boolean | undefined;
16
+ logger?: Logger | undefined;
17
+ }): Promise<ResolvedRelease>;
18
+ export declare function removeCamoufox(paths: CamoucliPaths, version: string, logger?: Logger | undefined): Promise<void>;
19
+ export interface CamoufoxInstallInspection {
20
+ playwrightCoreVersion?: string | undefined;
21
+ launchCheck: BrowserLaunchProbe;
22
+ }
23
+ export declare function inspectCamoufoxInstall(paths: CamoucliPaths, version?: string, logger?: Logger): Promise<CamoufoxInstallInspection>;
24
+ export declare function doctorCamoufox(paths: CamoucliPaths, logger?: Logger): Promise<Record<string, unknown>>;