@intuned/runtime-dev 1.3.13-kv.1 → 1.3.14-ts-runtime-helpers
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/bin/intuned-get-headless-user-agent +4 -0
- package/dist/commands/get-headless-user-agent.d.ts +1 -0
- package/dist/commands/get-headless-user-agent.js +18 -0
- package/dist/commands/intuned-cli/commands/run_authsession.command.d.ts +6 -6
- package/dist/commands/intuned-cli/commands/types.d.ts +2 -2
- package/dist/commands/intuned-cli/controller/authSession.d.ts +6 -6
- package/dist/commands/intuned-cli/helpers/auth.d.ts +1 -1
- package/dist/commands/intuned-cli/helpers/errors.d.ts +1 -1
- package/dist/commands/intuned-cli/helpers/errors.js +2 -2
- package/dist/commands/intuned-cli/helpers/intunedJson.d.ts +8 -140
- package/dist/commands/intuned-cli/helpers/intunedJson.js +12 -79
- package/dist/common/binStartupScript.js +8 -5
- package/dist/common/constants.d.ts +2 -0
- package/dist/common/constants.js +4 -2
- package/dist/common/{extensionsHelpers.d.ts → extension/extensionsHelpers.d.ts} +1 -1
- package/dist/common/{extensionsHelpers.js → extension/extensionsHelpers.js} +62 -6
- package/dist/common/extension/intunedExtensionServer.d.ts +25 -0
- package/dist/common/extension/intunedExtensionServer.js +164 -0
- package/dist/common/extension/types.d.ts +21 -0
- package/dist/common/extension/types.js +5 -0
- package/dist/common/intunedJson.d.ts +229 -0
- package/dist/common/intunedJson.js +133 -0
- package/dist/common/launchBrowser.d.ts +6 -0
- package/dist/common/launchBrowser.js +42 -17
- package/dist/common/runApi/index.js +6 -0
- package/dist/common/runApi/types.d.ts +20 -20
- package/dist/common/settingsSchema.d.ts +15 -1
- package/dist/common/settingsSchema.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +44 -1
- package/dist/runtime/captcha.d.ts +18 -0
- package/dist/runtime/captcha.js +190 -0
- package/dist/runtime/captcha.test.js +214 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +43 -0
- package/dist/runtime/persistentStore.test.js +101 -0
- package/package.json +4 -1
- package/WebTemplate.zip +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ExtensionServer = void 0;
|
|
7
|
+
exports.cleanIntunedExtensionServer = cleanIntunedExtensionServer;
|
|
8
|
+
exports.getIntunedExtensionServer = getIntunedExtensionServer;
|
|
9
|
+
exports.getTabId = getTabId;
|
|
10
|
+
exports.setupIntunedExtensionServer = setupIntunedExtensionServer;
|
|
11
|
+
var _fastify = _interopRequireDefault(require("fastify"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
class TabCaptchaState {
|
|
14
|
+
constructor(tabId) {
|
|
15
|
+
this.tabId = tabId;
|
|
16
|
+
this.captchasById = new Map();
|
|
17
|
+
this.subscribers = new Array();
|
|
18
|
+
}
|
|
19
|
+
subscribe(handler) {
|
|
20
|
+
this.subscribers.push(handler);
|
|
21
|
+
}
|
|
22
|
+
unsubscribe(handler, status) {
|
|
23
|
+
const index = this.subscribers.findIndex(subscriber => subscriber.handler === handler && (subscriber.status === status || !status));
|
|
24
|
+
if (index !== -1) {
|
|
25
|
+
this.subscribers = this.subscribers.splice(index, 1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
getCaptchas() {
|
|
29
|
+
return [...this.captchasById.values()];
|
|
30
|
+
}
|
|
31
|
+
async upsertCaptcha(captcha) {
|
|
32
|
+
this.captchasById.set(captcha.id, captcha);
|
|
33
|
+
for (const subscriber of this.subscribers) {
|
|
34
|
+
await subscriber.handler(captcha);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class ExtensionServer {
|
|
39
|
+
app = null;
|
|
40
|
+
isHealthy = false;
|
|
41
|
+
constructor() {
|
|
42
|
+
this.tabs = new Map();
|
|
43
|
+
}
|
|
44
|
+
getOrCreateTab(tabId) {
|
|
45
|
+
const existing = this.tabs.get(tabId);
|
|
46
|
+
if (existing) return existing;
|
|
47
|
+
const created = new TabCaptchaState(tabId);
|
|
48
|
+
this.tabs.set(tabId, created);
|
|
49
|
+
return created;
|
|
50
|
+
}
|
|
51
|
+
async handleUpsertCaptcha(captcha) {
|
|
52
|
+
const tab = this.getOrCreateTab(captcha.tabId);
|
|
53
|
+
await tab.upsertCaptcha(captcha);
|
|
54
|
+
}
|
|
55
|
+
async start({
|
|
56
|
+
port,
|
|
57
|
+
host = "0.0.0.0"
|
|
58
|
+
}) {
|
|
59
|
+
if (this.app) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.app = (0, _fastify.default)({
|
|
63
|
+
logger: false,
|
|
64
|
+
bodyLimit: 1_000_000
|
|
65
|
+
});
|
|
66
|
+
this.app.post("/state", async (request, reply) => {
|
|
67
|
+
try {
|
|
68
|
+
const data = request.body ?? {};
|
|
69
|
+
const captcha = {
|
|
70
|
+
id: String(data?.id ?? ""),
|
|
71
|
+
tabId: Number(data?.tabId ?? 0),
|
|
72
|
+
type: data?.type,
|
|
73
|
+
status: data?.status,
|
|
74
|
+
retryCount: data?.retryCount,
|
|
75
|
+
error: data?.error ?? null
|
|
76
|
+
};
|
|
77
|
+
if (!captcha.id || !captcha.tabId || !captcha.type || !captcha.status) {
|
|
78
|
+
return reply.code(400).send({
|
|
79
|
+
error: "Invalid captcha payload"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
await this.handleUpsertCaptcha(captcha);
|
|
83
|
+
return reply.code(200).send({});
|
|
84
|
+
} catch (error) {
|
|
85
|
+
return reply.code(500).send({
|
|
86
|
+
error: "Internal server error",
|
|
87
|
+
message: error?.message ?? String(error)
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
this.app.setNotFoundHandler((_request, reply) => {
|
|
92
|
+
return reply.code(404).send({
|
|
93
|
+
error: "Not found"
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
await this.app.listen({
|
|
97
|
+
port,
|
|
98
|
+
host
|
|
99
|
+
});
|
|
100
|
+
this.isHealthy = true;
|
|
101
|
+
}
|
|
102
|
+
async stop() {
|
|
103
|
+
if (!this.app) return;
|
|
104
|
+
const toClose = this.app;
|
|
105
|
+
this.app = null;
|
|
106
|
+
this.isHealthy = false;
|
|
107
|
+
await toClose.close();
|
|
108
|
+
}
|
|
109
|
+
async getCaptchas(page, status) {
|
|
110
|
+
const tabId = await getTabId(page);
|
|
111
|
+
const tab = this.tabs.get(tabId);
|
|
112
|
+
if (!tab) return [];
|
|
113
|
+
const captchas = tab.getCaptchas();
|
|
114
|
+
if (!status) return captchas;
|
|
115
|
+
return captchas.filter(c => c.status === status && c.tabId === tabId);
|
|
116
|
+
}
|
|
117
|
+
async subscribe(page, handler, status) {
|
|
118
|
+
const tabId = await getTabId(page);
|
|
119
|
+
const tab = this.getOrCreateTab(tabId);
|
|
120
|
+
tab.subscribe({
|
|
121
|
+
handler,
|
|
122
|
+
status
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async unsubscribe(page, handler, status) {
|
|
126
|
+
const tabId = await getTabId(page);
|
|
127
|
+
const tab = this.tabs.get(tabId);
|
|
128
|
+
if (!tab) return;
|
|
129
|
+
tab.unsubscribe(handler, status);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.ExtensionServer = ExtensionServer;
|
|
133
|
+
let extensionServerSingleton = null;
|
|
134
|
+
function getIntunedExtensionServer() {
|
|
135
|
+
if (!extensionServerSingleton) {
|
|
136
|
+
throw new Error("Intuned Extension Server is not initialized.");
|
|
137
|
+
}
|
|
138
|
+
return extensionServerSingleton;
|
|
139
|
+
}
|
|
140
|
+
async function setupIntunedExtensionServer({
|
|
141
|
+
port,
|
|
142
|
+
host
|
|
143
|
+
}) {
|
|
144
|
+
if (!extensionServerSingleton) {
|
|
145
|
+
extensionServerSingleton = new ExtensionServer();
|
|
146
|
+
}
|
|
147
|
+
await extensionServerSingleton.start({
|
|
148
|
+
port,
|
|
149
|
+
host
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
async function cleanIntunedExtensionServer() {
|
|
153
|
+
if (extensionServerSingleton) {
|
|
154
|
+
await extensionServerSingleton.stop();
|
|
155
|
+
extensionServerSingleton = null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async function getTabId(page) {
|
|
159
|
+
await page.waitForFunction("window.__INTUNED_TAB_ID__ !== undefined", {
|
|
160
|
+
timeout: 15_000
|
|
161
|
+
});
|
|
162
|
+
const tabId = await page.evaluate("window.__INTUNED_TAB_ID__");
|
|
163
|
+
return Number(tabId);
|
|
164
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type CaptchaType = "aws" | "cloudflare" | "customcaptcha" | "funcaptcha" | "geetest" | "hcaptcha" | "lemincaptcha" | "recaptcha" | "textcaptcha";
|
|
2
|
+
export type CaptchaStatus = "attached" | "solving" | "solved" | "error" | "detached";
|
|
3
|
+
export type CaptchaError = {
|
|
4
|
+
code: "HIT_LIMIT" | "MAX_RETRIES" | "UNEXPECTED_SERVER_RESPONSE" | "UNEXPECTED_ERROR";
|
|
5
|
+
error?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export type CaptchaBase = {
|
|
8
|
+
id: string;
|
|
9
|
+
tabId: number;
|
|
10
|
+
type: CaptchaType;
|
|
11
|
+
retryCount?: number;
|
|
12
|
+
};
|
|
13
|
+
export type CaptchaNonError = CaptchaBase & {
|
|
14
|
+
status: Exclude<CaptchaStatus, "error">;
|
|
15
|
+
};
|
|
16
|
+
export type CaptchaErrorStatus = CaptchaBase & {
|
|
17
|
+
status: "error";
|
|
18
|
+
error: CaptchaError;
|
|
19
|
+
};
|
|
20
|
+
export type Captcha = CaptchaNonError | CaptchaErrorStatus;
|
|
21
|
+
export type CaptchaCallback = (captcha: Captcha) => void | Promise<void>;
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type Err, type Ok } from "neverthrow";
|
|
3
|
+
export declare const intunedJsonSchema: z.ZodIntersection<z.ZodObject<{
|
|
4
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
5
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
6
|
+
metadata: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
7
|
+
defaultJobInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
8
|
+
defaultRunPlaygroundInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
9
|
+
testAuthSessionInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
defaultJobInput?: Record<string, any> | undefined;
|
|
12
|
+
defaultRunPlaygroundInput?: Record<string, any> | undefined;
|
|
13
|
+
testAuthSessionInput?: Record<string, any> | undefined;
|
|
14
|
+
}, {
|
|
15
|
+
defaultJobInput?: unknown;
|
|
16
|
+
defaultRunPlaygroundInput?: unknown;
|
|
17
|
+
testAuthSessionInput?: unknown;
|
|
18
|
+
}>>>;
|
|
19
|
+
stealthMode: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
20
|
+
enabled: z.ZodBoolean;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
}, {
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
}>>>;
|
|
26
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
27
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
28
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
29
|
+
metadata: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
30
|
+
defaultJobInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
31
|
+
defaultRunPlaygroundInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
32
|
+
testAuthSessionInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
defaultJobInput?: Record<string, any> | undefined;
|
|
35
|
+
defaultRunPlaygroundInput?: Record<string, any> | undefined;
|
|
36
|
+
testAuthSessionInput?: Record<string, any> | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
defaultJobInput?: unknown;
|
|
39
|
+
defaultRunPlaygroundInput?: unknown;
|
|
40
|
+
testAuthSessionInput?: unknown;
|
|
41
|
+
}>>>;
|
|
42
|
+
stealthMode: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
43
|
+
enabled: z.ZodBoolean;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
}, {
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
}>>>;
|
|
49
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
50
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
51
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
52
|
+
metadata: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
53
|
+
defaultJobInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
54
|
+
defaultRunPlaygroundInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
55
|
+
testAuthSessionInput: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
|
|
56
|
+
}, "strip", z.ZodTypeAny, {
|
|
57
|
+
defaultJobInput?: Record<string, any> | undefined;
|
|
58
|
+
defaultRunPlaygroundInput?: Record<string, any> | undefined;
|
|
59
|
+
testAuthSessionInput?: Record<string, any> | undefined;
|
|
60
|
+
}, {
|
|
61
|
+
defaultJobInput?: unknown;
|
|
62
|
+
defaultRunPlaygroundInput?: unknown;
|
|
63
|
+
testAuthSessionInput?: unknown;
|
|
64
|
+
}>>>;
|
|
65
|
+
stealthMode: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
66
|
+
enabled: z.ZodBoolean;
|
|
67
|
+
}, "strip", z.ZodTypeAny, {
|
|
68
|
+
enabled: boolean;
|
|
69
|
+
}, {
|
|
70
|
+
enabled: boolean;
|
|
71
|
+
}>>>;
|
|
72
|
+
}, z.ZodTypeAny, "passthrough">>, z.ZodUnion<[z.ZodObject<{
|
|
73
|
+
authSessions: z.ZodObject<{
|
|
74
|
+
enabled: z.ZodLiteral<false>;
|
|
75
|
+
}, "strip", z.ZodTypeAny, {
|
|
76
|
+
enabled: false;
|
|
77
|
+
}, {
|
|
78
|
+
enabled: false;
|
|
79
|
+
}>;
|
|
80
|
+
apiAccess: z.ZodObject<{
|
|
81
|
+
enabled: z.ZodLiteral<false>;
|
|
82
|
+
}, "strip", z.ZodTypeAny, {
|
|
83
|
+
enabled: false;
|
|
84
|
+
}, {
|
|
85
|
+
enabled: false;
|
|
86
|
+
}>;
|
|
87
|
+
}, "strip", z.ZodTypeAny, {
|
|
88
|
+
authSessions: {
|
|
89
|
+
enabled: false;
|
|
90
|
+
};
|
|
91
|
+
apiAccess: {
|
|
92
|
+
enabled: false;
|
|
93
|
+
};
|
|
94
|
+
}, {
|
|
95
|
+
authSessions: {
|
|
96
|
+
enabled: false;
|
|
97
|
+
};
|
|
98
|
+
apiAccess: {
|
|
99
|
+
enabled: false;
|
|
100
|
+
};
|
|
101
|
+
}>, z.ZodObject<{
|
|
102
|
+
authSessions: z.ZodUnion<[z.ZodObject<{
|
|
103
|
+
enabled: z.ZodLiteral<false>;
|
|
104
|
+
}, "strip", z.ZodTypeAny, {
|
|
105
|
+
enabled: false;
|
|
106
|
+
}, {
|
|
107
|
+
enabled: false;
|
|
108
|
+
}>, z.ZodObject<{
|
|
109
|
+
enabled: z.ZodLiteral<true>;
|
|
110
|
+
type: z.ZodEnum<["MANUAL", "API"]>;
|
|
111
|
+
startUrl: z.ZodOptional<z.ZodString>;
|
|
112
|
+
finishUrl: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
enabled: true;
|
|
115
|
+
type: "API" | "MANUAL";
|
|
116
|
+
startUrl?: string | undefined;
|
|
117
|
+
finishUrl?: string | undefined;
|
|
118
|
+
}, {
|
|
119
|
+
enabled: true;
|
|
120
|
+
type: "API" | "MANUAL";
|
|
121
|
+
startUrl?: string | undefined;
|
|
122
|
+
finishUrl?: string | undefined;
|
|
123
|
+
}>]>;
|
|
124
|
+
apiAccess: z.ZodObject<{
|
|
125
|
+
enabled: z.ZodLiteral<true>;
|
|
126
|
+
}, "strip", z.ZodTypeAny, {
|
|
127
|
+
enabled: true;
|
|
128
|
+
}, {
|
|
129
|
+
enabled: true;
|
|
130
|
+
}>;
|
|
131
|
+
}, "strip", z.ZodTypeAny, {
|
|
132
|
+
authSessions: {
|
|
133
|
+
enabled: false;
|
|
134
|
+
} | {
|
|
135
|
+
enabled: true;
|
|
136
|
+
type: "API" | "MANUAL";
|
|
137
|
+
startUrl?: string | undefined;
|
|
138
|
+
finishUrl?: string | undefined;
|
|
139
|
+
};
|
|
140
|
+
apiAccess: {
|
|
141
|
+
enabled: true;
|
|
142
|
+
};
|
|
143
|
+
}, {
|
|
144
|
+
authSessions: {
|
|
145
|
+
enabled: false;
|
|
146
|
+
} | {
|
|
147
|
+
enabled: true;
|
|
148
|
+
type: "API" | "MANUAL";
|
|
149
|
+
startUrl?: string | undefined;
|
|
150
|
+
finishUrl?: string | undefined;
|
|
151
|
+
};
|
|
152
|
+
apiAccess: {
|
|
153
|
+
enabled: true;
|
|
154
|
+
};
|
|
155
|
+
}>]>>;
|
|
156
|
+
export type IntunedJson = z.infer<typeof intunedJsonSchema>;
|
|
157
|
+
export declare const intunedSettingsFileNames: readonly ["Intuned.json", "Intuned.jsonc", "Intuned.yaml", "Intuned.yml", "Intuned.toml"];
|
|
158
|
+
export declare function loadIntunedJson(): Promise<Err<never, string> | Ok<{
|
|
159
|
+
projectName?: string | undefined;
|
|
160
|
+
workspaceId?: string | undefined;
|
|
161
|
+
metadata?: {
|
|
162
|
+
defaultJobInput?: Record<string, any> | undefined;
|
|
163
|
+
defaultRunPlaygroundInput?: Record<string, any> | undefined;
|
|
164
|
+
testAuthSessionInput?: Record<string, any> | undefined;
|
|
165
|
+
} | undefined;
|
|
166
|
+
stealthMode?: {
|
|
167
|
+
enabled: boolean;
|
|
168
|
+
} | undefined;
|
|
169
|
+
} & {
|
|
170
|
+
[k: string]: unknown;
|
|
171
|
+
} & ({
|
|
172
|
+
authSessions: {
|
|
173
|
+
enabled: false;
|
|
174
|
+
};
|
|
175
|
+
apiAccess: {
|
|
176
|
+
enabled: false;
|
|
177
|
+
};
|
|
178
|
+
} | {
|
|
179
|
+
authSessions: {
|
|
180
|
+
enabled: false;
|
|
181
|
+
} | {
|
|
182
|
+
enabled: true;
|
|
183
|
+
type: "API" | "MANUAL";
|
|
184
|
+
startUrl?: string | undefined;
|
|
185
|
+
finishUrl?: string | undefined;
|
|
186
|
+
};
|
|
187
|
+
apiAccess: {
|
|
188
|
+
enabled: true;
|
|
189
|
+
};
|
|
190
|
+
}), never>>;
|
|
191
|
+
export declare function getIntunedSettingsFile(): Promise<Ok<{
|
|
192
|
+
name: typeof intunedSettingsFileNames[number];
|
|
193
|
+
path: string;
|
|
194
|
+
parse: (content: string) => any;
|
|
195
|
+
}, never> | Err<never, string>>;
|
|
196
|
+
export declare function getIntunedSettingsFileName(): Promise<Err<never, string> | Ok<"Intuned.json" | "Intuned.jsonc" | "Intuned.yaml" | "Intuned.yml" | "Intuned.toml", never>>;
|
|
197
|
+
export declare function loadIntunedJsonSync(): Err<never, string> | Ok<{
|
|
198
|
+
projectName?: string | undefined;
|
|
199
|
+
workspaceId?: string | undefined;
|
|
200
|
+
metadata?: {
|
|
201
|
+
defaultJobInput?: Record<string, any> | undefined;
|
|
202
|
+
defaultRunPlaygroundInput?: Record<string, any> | undefined;
|
|
203
|
+
testAuthSessionInput?: Record<string, any> | undefined;
|
|
204
|
+
} | undefined;
|
|
205
|
+
stealthMode?: {
|
|
206
|
+
enabled: boolean;
|
|
207
|
+
} | undefined;
|
|
208
|
+
} & {
|
|
209
|
+
[k: string]: unknown;
|
|
210
|
+
} & ({
|
|
211
|
+
authSessions: {
|
|
212
|
+
enabled: false;
|
|
213
|
+
};
|
|
214
|
+
apiAccess: {
|
|
215
|
+
enabled: false;
|
|
216
|
+
};
|
|
217
|
+
} | {
|
|
218
|
+
authSessions: {
|
|
219
|
+
enabled: false;
|
|
220
|
+
} | {
|
|
221
|
+
enabled: true;
|
|
222
|
+
type: "API" | "MANUAL";
|
|
223
|
+
startUrl?: string | undefined;
|
|
224
|
+
finishUrl?: string | undefined;
|
|
225
|
+
};
|
|
226
|
+
apiAccess: {
|
|
227
|
+
enabled: true;
|
|
228
|
+
};
|
|
229
|
+
}), never>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getIntunedSettingsFile = getIntunedSettingsFile;
|
|
7
|
+
exports.getIntunedSettingsFileName = getIntunedSettingsFileName;
|
|
8
|
+
exports.intunedSettingsFileNames = exports.intunedJsonSchema = void 0;
|
|
9
|
+
exports.loadIntunedJson = loadIntunedJson;
|
|
10
|
+
exports.loadIntunedJsonSync = loadIntunedJsonSync;
|
|
11
|
+
var _path = _interopRequireDefault(require("path"));
|
|
12
|
+
var fs = _interopRequireWildcard(require("fs-extra"));
|
|
13
|
+
var _zod = require("zod");
|
|
14
|
+
var JSONC = _interopRequireWildcard(require("jsonc-parser"));
|
|
15
|
+
var YAML = _interopRequireWildcard(require("yaml"));
|
|
16
|
+
var TOML = _interopRequireWildcard(require("smol-toml"));
|
|
17
|
+
var _neverthrow = require("neverthrow");
|
|
18
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
19
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
20
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
|
+
const playwright = undefined;
|
|
22
|
+
const intunedJsonSchema = exports.intunedJsonSchema = _zod.z.object({
|
|
23
|
+
projectName: _zod.z.string().optional(),
|
|
24
|
+
workspaceId: _zod.z.string().optional(),
|
|
25
|
+
metadata: _zod.z.object({
|
|
26
|
+
defaultJobInput: _zod.z.record(_zod.z.any()).optional().catch(undefined),
|
|
27
|
+
defaultRunPlaygroundInput: _zod.z.record(_zod.z.any()).optional().catch(undefined),
|
|
28
|
+
testAuthSessionInput: _zod.z.record(_zod.z.any()).optional().catch(undefined)
|
|
29
|
+
}).optional().catch(undefined),
|
|
30
|
+
stealthMode: _zod.z.object({
|
|
31
|
+
enabled: _zod.z.boolean()
|
|
32
|
+
}).optional().catch(undefined)
|
|
33
|
+
}).passthrough().and(_zod.z.union([_zod.z.object({
|
|
34
|
+
authSessions: _zod.z.object({
|
|
35
|
+
enabled: _zod.z.literal(false)
|
|
36
|
+
}),
|
|
37
|
+
apiAccess: _zod.z.object({
|
|
38
|
+
enabled: _zod.z.literal(false)
|
|
39
|
+
})
|
|
40
|
+
}), _zod.z.object({
|
|
41
|
+
authSessions: _zod.z.union([_zod.z.object({
|
|
42
|
+
enabled: _zod.z.literal(false)
|
|
43
|
+
}), _zod.z.object({
|
|
44
|
+
enabled: _zod.z.literal(true),
|
|
45
|
+
type: _zod.z.enum(["MANUAL", "API"]),
|
|
46
|
+
startUrl: _zod.z.string().optional(),
|
|
47
|
+
finishUrl: _zod.z.string().optional()
|
|
48
|
+
})]),
|
|
49
|
+
apiAccess: _zod.z.object({
|
|
50
|
+
enabled: _zod.z.literal(true)
|
|
51
|
+
})
|
|
52
|
+
})]));
|
|
53
|
+
const intunedSettingsFileNames = exports.intunedSettingsFileNames = ["Intuned.json", "Intuned.jsonc", "Intuned.yaml", "Intuned.yml", "Intuned.toml"];
|
|
54
|
+
async function loadIntunedJson() {
|
|
55
|
+
const settingsFileResult = await getIntunedSettingsFile();
|
|
56
|
+
if (!settingsFileResult.isOk()) {
|
|
57
|
+
return settingsFileResult;
|
|
58
|
+
}
|
|
59
|
+
const settingsFile = settingsFileResult.value;
|
|
60
|
+
const intunedJsonContent = await fs.readFile(settingsFile.path, "utf-8");
|
|
61
|
+
let intunedJson;
|
|
62
|
+
try {
|
|
63
|
+
intunedJson = settingsFile.parse(intunedJsonContent);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return (0, _neverthrow.err)(`Failed to parse ${settingsFile.name}: ${e.message}`);
|
|
66
|
+
}
|
|
67
|
+
const parseResult = intunedJsonSchema.safeParse(intunedJson);
|
|
68
|
+
if (!parseResult.success) {
|
|
69
|
+
const formattedError = parseResult.error.errors.map(e => `- ${e.path.join(".")}: ${e.message}`).join("\n");
|
|
70
|
+
return (0, _neverthrow.err)(`${settingsFile.name} is not valid:\n${formattedError}\nPlease fix the errors and try again.`);
|
|
71
|
+
}
|
|
72
|
+
return (0, _neverthrow.ok)(parseResult.data);
|
|
73
|
+
}
|
|
74
|
+
const intunedSettingsParsers = {
|
|
75
|
+
"Intuned.json": JSON.parse,
|
|
76
|
+
"Intuned.jsonc": JSONC.parse,
|
|
77
|
+
"Intuned.yaml": YAML.parse,
|
|
78
|
+
"Intuned.yml": YAML.parse,
|
|
79
|
+
"Intuned.toml": TOML.parse
|
|
80
|
+
};
|
|
81
|
+
async function getIntunedSettingsFile() {
|
|
82
|
+
for (const fileName of intunedSettingsFileNames) {
|
|
83
|
+
const filePath = _path.default.join(process.cwd(), fileName);
|
|
84
|
+
if (await fs.exists(filePath)) {
|
|
85
|
+
return (0, _neverthrow.ok)({
|
|
86
|
+
name: fileName,
|
|
87
|
+
path: filePath,
|
|
88
|
+
parse: intunedSettingsParsers[fileName]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return (0, _neverthrow.err)("No Intuned settings file found.");
|
|
93
|
+
}
|
|
94
|
+
async function getIntunedSettingsFileName() {
|
|
95
|
+
const settingsFileResult = await getIntunedSettingsFile();
|
|
96
|
+
if (!settingsFileResult.isOk()) {
|
|
97
|
+
return settingsFileResult;
|
|
98
|
+
}
|
|
99
|
+
return (0, _neverthrow.ok)(settingsFileResult.value.name);
|
|
100
|
+
}
|
|
101
|
+
function loadIntunedJsonSync() {
|
|
102
|
+
const settingsFileResult = getIntunedSettingsFileSync();
|
|
103
|
+
if (!settingsFileResult.isOk()) {
|
|
104
|
+
return settingsFileResult;
|
|
105
|
+
}
|
|
106
|
+
const settingsFile = settingsFileResult.value;
|
|
107
|
+
const intunedJsonContent = fs.readFileSync(settingsFile.path, "utf-8");
|
|
108
|
+
let intunedJson;
|
|
109
|
+
try {
|
|
110
|
+
intunedJson = settingsFile.parse(intunedJsonContent);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return (0, _neverthrow.err)(`Failed to parse ${settingsFile.name}: ${e.message}`);
|
|
113
|
+
}
|
|
114
|
+
const parseResult = intunedJsonSchema.safeParse(intunedJson);
|
|
115
|
+
if (!parseResult.success) {
|
|
116
|
+
const formattedError = parseResult.error.errors.map(e => `- ${e.path.join(".")}: ${e.message}`).join("\n");
|
|
117
|
+
return (0, _neverthrow.err)(`${settingsFile.name} is not valid:\n${formattedError}\nPlease fix the errors and try again.`);
|
|
118
|
+
}
|
|
119
|
+
return (0, _neverthrow.ok)(parseResult.data);
|
|
120
|
+
}
|
|
121
|
+
function getIntunedSettingsFileSync() {
|
|
122
|
+
for (const fileName of intunedSettingsFileNames) {
|
|
123
|
+
const filePath = _path.default.join(process.cwd(), fileName);
|
|
124
|
+
if (fs.existsSync(filePath)) {
|
|
125
|
+
return (0, _neverthrow.ok)({
|
|
126
|
+
name: fileName,
|
|
127
|
+
path: filePath,
|
|
128
|
+
parse: intunedSettingsParsers[fileName]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return (0, _neverthrow.err)("No Intuned settings file found.");
|
|
133
|
+
}
|
|
@@ -21,5 +21,11 @@ export type LaunchChromiumCdpOptions = {
|
|
|
21
21
|
};
|
|
22
22
|
export declare function launchChromium(options: LaunchChromiumStandaloneOptions): Promise<LaunchBrowserResult>;
|
|
23
23
|
export declare function launchChromium(options: LaunchChromiumCdpOptions): Promise<LaunchBrowserResult>;
|
|
24
|
+
export declare function getBrowserExecutablePath(): Promise<string | undefined>;
|
|
24
25
|
export declare function launchBrowser(options: Omit<LaunchChromiumStandaloneOptions, "executablePath"> | LaunchChromiumCdpOptions): Promise<LaunchBrowserResult>;
|
|
25
26
|
export declare function getLocalCdpAddress(port: number): string;
|
|
27
|
+
export declare function getHeadlessUserAgent({ executablePath, args, ignoreDefaultArgs, }: {
|
|
28
|
+
executablePath?: string;
|
|
29
|
+
args?: string[];
|
|
30
|
+
ignoreDefaultArgs?: string[];
|
|
31
|
+
}): Promise<string | undefined>;
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.getBrowserExecutablePath = getBrowserExecutablePath;
|
|
7
|
+
exports.getHeadlessUserAgent = getHeadlessUserAgent;
|
|
6
8
|
exports.getLocalCdpAddress = getLocalCdpAddress;
|
|
7
9
|
exports.launchBrowser = launchBrowser;
|
|
8
10
|
exports.launchChromium = launchChromium;
|
|
@@ -12,7 +14,8 @@ var fs = _fsExtra;
|
|
|
12
14
|
var _path = require("path");
|
|
13
15
|
var _waitOn = _interopRequireDefault(require("wait-on"));
|
|
14
16
|
var _child_process = require("child_process");
|
|
15
|
-
var _extensionsHelpers = require("./extensionsHelpers");
|
|
17
|
+
var _extensionsHelpers = require("./extension/extensionsHelpers");
|
|
18
|
+
var _intunedExtensionServer = require("./extension/intunedExtensionServer");
|
|
16
19
|
var _util = require("util");
|
|
17
20
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
21
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -86,10 +89,15 @@ async function launchChromium(options) {
|
|
|
86
89
|
executablePath = undefined;
|
|
87
90
|
}
|
|
88
91
|
}
|
|
92
|
+
const viewport = null;
|
|
93
|
+
const userAgent = process.env.__PLAYWRIGHT_USER_AGENT_OVERRIDE ?? (await getHeadlessUserAgent({
|
|
94
|
+
executablePath
|
|
95
|
+
}));
|
|
89
96
|
const context = await playwright.chromium.launchPersistentContext(userDataDir, {
|
|
97
|
+
userAgent,
|
|
90
98
|
executablePath,
|
|
91
99
|
headless,
|
|
92
|
-
viewport
|
|
100
|
+
viewport,
|
|
93
101
|
proxy,
|
|
94
102
|
downloadsPath,
|
|
95
103
|
args: extraArgs,
|
|
@@ -97,6 +105,7 @@ async function launchChromium(options) {
|
|
|
97
105
|
});
|
|
98
106
|
context.once("close", async () => {
|
|
99
107
|
try {
|
|
108
|
+
await (0, _intunedExtensionServer.cleanIntunedExtensionServer)();
|
|
100
109
|
await (0, _fsExtra.rm)(userDataDir, {
|
|
101
110
|
recursive: true,
|
|
102
111
|
force: true,
|
|
@@ -120,25 +129,20 @@ async function launchChromium(options) {
|
|
|
120
129
|
context
|
|
121
130
|
};
|
|
122
131
|
}
|
|
132
|
+
async function getBrowserExecutablePath() {
|
|
133
|
+
const browserType = getBrowserType();
|
|
134
|
+
if (browserType === "brave") {
|
|
135
|
+
return await getBraveExecutablePath();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
123
138
|
async function launchBrowser(options) {
|
|
124
139
|
if ("cdpAddress" in options) {
|
|
125
140
|
return launchChromium(options);
|
|
126
141
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return launchChromium(options);
|
|
132
|
-
}
|
|
133
|
-
case "brave":
|
|
134
|
-
{
|
|
135
|
-
const braveExecutablePath = await getBraveExecutablePath();
|
|
136
|
-
return launchChromium({
|
|
137
|
-
...options,
|
|
138
|
-
executablePath: braveExecutablePath
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
+
return launchChromium({
|
|
143
|
+
...options,
|
|
144
|
+
executablePath: await getBrowserExecutablePath()
|
|
145
|
+
});
|
|
142
146
|
}
|
|
143
147
|
function getBrowserType() {
|
|
144
148
|
if (process.env.BROWSER_TYPE === "brave") {
|
|
@@ -169,4 +173,25 @@ async function waitOnCdpAddress(cdpAddress) {
|
|
|
169
173
|
tcpTimeout: 1000,
|
|
170
174
|
window: 1000
|
|
171
175
|
});
|
|
176
|
+
}
|
|
177
|
+
async function getHeadlessUserAgent({
|
|
178
|
+
executablePath,
|
|
179
|
+
args,
|
|
180
|
+
ignoreDefaultArgs
|
|
181
|
+
}) {
|
|
182
|
+
const browser = await playwright.chromium.launch({
|
|
183
|
+
headless: true,
|
|
184
|
+
executablePath,
|
|
185
|
+
args,
|
|
186
|
+
ignoreDefaultArgs
|
|
187
|
+
});
|
|
188
|
+
const context = await browser.newContext();
|
|
189
|
+
const page = await context.newPage();
|
|
190
|
+
let userAgent = await page.evaluate(() => navigator.userAgent);
|
|
191
|
+
await browser.close();
|
|
192
|
+
if (!userAgent || typeof userAgent !== "string") {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
userAgent = userAgent.replace("HeadlessChrome", "Chrome");
|
|
196
|
+
return userAgent;
|
|
172
197
|
}
|