@intuned/runtime-dev 0.1.0-test.43 → 0.1.0-test.45
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/11_1.zip +0 -0
- package/2_1.zip +0 -0
- package/InterfaceTemplate/utils.ts +30 -248
- package/WebTemplate/controllers/authSessions/check.ts +1 -1
- package/WebTemplate/controllers/authSessions/create.ts +1 -1
- package/WebTemplate/controllers/runApi/helpers.ts +1 -1
- package/dist/commands/api/run.js +1 -1
- package/dist/commands/auth-sessions/run-check.js +1 -1
- package/dist/commands/auth-sessions/run-create.js +1 -1
- package/dist/commands/interface/run.js +3 -3
- package/dist/common/runApi/index.js +3 -2
- package/dist/common/runApi/types.d.ts +10 -10
- package/dist/common/runApi/types.js +3 -3
- package/package.json +1 -1
package/11_1.zip
ADDED
|
Binary file
|
package/2_1.zip
ADDED
|
Binary file
|
|
@@ -1,214 +1,3 @@
|
|
|
1
|
-
import * as playwright from "@intuned/playwright-core";
|
|
2
|
-
import { Handler, Response } from "@tinyhttp/app";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import { getExecutionContext } from "@intuned/runtime";
|
|
5
|
-
import { setTimeout } from "timers/promises";
|
|
6
|
-
|
|
7
|
-
export class FunctionNotFoundError extends Error {
|
|
8
|
-
functionName: string;
|
|
9
|
-
path: string;
|
|
10
|
-
constructor(functionName: string, path: string) {
|
|
11
|
-
const message = `function ${functionName} not found in ${path}`;
|
|
12
|
-
super(message);
|
|
13
|
-
this.functionName = functionName;
|
|
14
|
-
this.path = path;
|
|
15
|
-
this.name = "FunctionNotFound";
|
|
16
|
-
Object.setPrototypeOf(this, FunctionNotFoundError.prototype);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getIsRetryableError(error: any) {
|
|
21
|
-
if (error?.message) {
|
|
22
|
-
return error.message.includes("ERR_NETWORK_CHANGED");
|
|
23
|
-
}
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function getErrorResponse(error: any): {
|
|
28
|
-
status: number;
|
|
29
|
-
body: any;
|
|
30
|
-
} {
|
|
31
|
-
if (error instanceof FunctionNotFoundError) {
|
|
32
|
-
return {
|
|
33
|
-
status: 404,
|
|
34
|
-
body: {
|
|
35
|
-
message: error.message,
|
|
36
|
-
error: error.name,
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (error instanceof playwright.errors.TimeoutError) {
|
|
41
|
-
return {
|
|
42
|
-
status: 500,
|
|
43
|
-
body: { message: error.message, error: error.name },
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* here we use error.constructor.name instead of error instanceof RunError
|
|
48
|
-
* this is because the error is thrown by importing the runner from the api code on intuned app
|
|
49
|
-
* the definition of class RunError which is imported from here is different than the class RunError
|
|
50
|
-
* imported from the user.
|
|
51
|
-
*/
|
|
52
|
-
if (error.constructor.name === "RunError") {
|
|
53
|
-
return {
|
|
54
|
-
status: 200,
|
|
55
|
-
body: {
|
|
56
|
-
status: error.options.status_code ?? 500,
|
|
57
|
-
message: error.message,
|
|
58
|
-
error: error.options.error_code ?? error.name,
|
|
59
|
-
intunedOptions: error.options,
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
status: 500,
|
|
65
|
-
body: { error: error?.name ?? error, message: error?.message },
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function handlePlaywrightExecutionError(error: any, res: Response) {
|
|
70
|
-
const { status, body } = getErrorResponse(error);
|
|
71
|
-
return res.status(status).json(body);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
type EventTraceEvent = {
|
|
75
|
-
type: "event";
|
|
76
|
-
time: number;
|
|
77
|
-
class: string;
|
|
78
|
-
method: string;
|
|
79
|
-
params: any;
|
|
80
|
-
pageId?: string;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
type AppHandlerParams = Parameters<Handler>;
|
|
84
|
-
|
|
85
|
-
export function errorRetryMiddleware(handler: Handler) {
|
|
86
|
-
return async (...args: AppHandlerParams) => {
|
|
87
|
-
let attempts = 1;
|
|
88
|
-
const [req, res, next] = args;
|
|
89
|
-
// eslint-disable-next-line no-constant-condition
|
|
90
|
-
while (true) {
|
|
91
|
-
try {
|
|
92
|
-
await handler(req, res, next);
|
|
93
|
-
break;
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.log(error?.name, error?.message);
|
|
96
|
-
if (!getIsRetryableError(error) || attempts >= 3) {
|
|
97
|
-
return handlePlaywrightExecutionError(error, res);
|
|
98
|
-
}
|
|
99
|
-
attempts++;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function getTraceFilePath(runId: string, attemptNumber?: string) {
|
|
106
|
-
const fileName = `${runId}${attemptNumber ? `_${attemptNumber}` : ""}`;
|
|
107
|
-
return path.join(process.env.TRACES_DIRECTORY ?? "", `${fileName}.zip`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export interface ProxyConfig {
|
|
111
|
-
username: string;
|
|
112
|
-
server: string;
|
|
113
|
-
password: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function proxyToUrl(proxy: ProxyConfig) {
|
|
117
|
-
const url = new URL(proxy.server);
|
|
118
|
-
url.username = proxy.username;
|
|
119
|
-
url.password = proxy.password;
|
|
120
|
-
return url.toString();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export function isJobRunMachine() {
|
|
124
|
-
return process.env.JOB_ID && process.env.JOB_RUN_ID;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function isHeadless() {
|
|
128
|
-
return process.env.INTUNED_PLAYWRIGHT_HEADLESS !== "0";
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export abstract class AsyncRunEndpointController {
|
|
132
|
-
private static activeRequests: Set<string> = new Set();
|
|
133
|
-
|
|
134
|
-
static isRunning(taskToken: string) {
|
|
135
|
-
return this.activeRequests.has(taskToken);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
static addRequest(taskToken: string) {
|
|
139
|
-
this.activeRequests.add(taskToken);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
static removeRequest(taskToken: string) {
|
|
143
|
-
this.activeRequests.delete(taskToken);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
static get activeRequestsCount() {
|
|
147
|
-
return this.activeRequests.size;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export async function waitWithExtendableTimeout<T>({
|
|
152
|
-
initialTimeout,
|
|
153
|
-
promise,
|
|
154
|
-
abortController,
|
|
155
|
-
}: {
|
|
156
|
-
initialTimeout: number;
|
|
157
|
-
promise: Promise<T>;
|
|
158
|
-
abortController?: AbortController;
|
|
159
|
-
}): Promise<
|
|
160
|
-
| {
|
|
161
|
-
timedOut: true;
|
|
162
|
-
}
|
|
163
|
-
| {
|
|
164
|
-
timedOut: false;
|
|
165
|
-
result: T;
|
|
166
|
-
}
|
|
167
|
-
> {
|
|
168
|
-
const context = getExecutionContext()!;
|
|
169
|
-
if (context.timeoutInfo) {
|
|
170
|
-
context.timeoutInfo.timeoutTimestamp = Date.now() + initialTimeout;
|
|
171
|
-
}
|
|
172
|
-
const timerSymbol = Symbol("timer");
|
|
173
|
-
if (!context) {
|
|
174
|
-
const result = await Promise.race([
|
|
175
|
-
promise,
|
|
176
|
-
setTimeout(initialTimeout, timerSymbol),
|
|
177
|
-
]);
|
|
178
|
-
if (result === timerSymbol) {
|
|
179
|
-
abortController?.abort("Timed out");
|
|
180
|
-
return { timedOut: true };
|
|
181
|
-
}
|
|
182
|
-
return { timedOut: false, result };
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
let taskTimeout = initialTimeout;
|
|
186
|
-
while (true as boolean) {
|
|
187
|
-
const result = await Promise.race([
|
|
188
|
-
promise,
|
|
189
|
-
setTimeout(taskTimeout, timerSymbol),
|
|
190
|
-
]);
|
|
191
|
-
|
|
192
|
-
if (result !== timerSymbol) {
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const remainingTime =
|
|
197
|
-
(context.timeoutInfo?.timeoutTimestamp ?? 0) - Date.now();
|
|
198
|
-
if (remainingTime < 0) {
|
|
199
|
-
abortController?.abort("Timed out");
|
|
200
|
-
return { timedOut: true };
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
taskTimeout = remainingTime;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
timedOut: false,
|
|
208
|
-
result: await promise,
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
|
|
212
1
|
export async function importModule(path: string) {
|
|
213
2
|
const [folderName, ...functionNameParts] = path.split("/");
|
|
214
3
|
const functionNameDepth = functionNameParts.length;
|
|
@@ -216,42 +5,35 @@ export async function importModule(path: string) {
|
|
|
216
5
|
// string literals should be inline
|
|
217
6
|
// currently we support only 5 levels of depth
|
|
218
7
|
// rollup dynamic import does not support multiple levels of dynamic imports so we need to specify the possible paths explicitly
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
return imported;
|
|
251
|
-
} catch (error: any) {
|
|
252
|
-
if (error.message.includes("Unknown variable dynamic import")) {
|
|
253
|
-
throw new FunctionNotFoundError("", path);
|
|
254
|
-
}
|
|
255
|
-
throw error;
|
|
8
|
+
let imported: any = undefined;
|
|
9
|
+
switch (functionNameDepth) {
|
|
10
|
+
case 1:
|
|
11
|
+
imported = await import(`./${folderName}/${functionNameParts[0]}.ts`);
|
|
12
|
+
break;
|
|
13
|
+
case 2:
|
|
14
|
+
imported = await import(
|
|
15
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}.ts`
|
|
16
|
+
);
|
|
17
|
+
break;
|
|
18
|
+
case 3:
|
|
19
|
+
imported = await import(
|
|
20
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}.ts`
|
|
21
|
+
);
|
|
22
|
+
break;
|
|
23
|
+
case 4:
|
|
24
|
+
imported = await import(
|
|
25
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}.ts`
|
|
26
|
+
);
|
|
27
|
+
break;
|
|
28
|
+
case 5:
|
|
29
|
+
imported = await import(
|
|
30
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}/${functionNameParts[4]}.ts`
|
|
31
|
+
);
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
throw new Error(
|
|
35
|
+
"intuned supports maximum 5 levels of depth in the api folder"
|
|
36
|
+
);
|
|
256
37
|
}
|
|
38
|
+
return imported;
|
|
257
39
|
}
|
package/dist/commands/api/run.js
CHANGED
|
@@ -54,7 +54,7 @@ _dotenv.default.config({
|
|
|
54
54
|
function runAutomationCLI(importFunction) {
|
|
55
55
|
_commander.program.description("run user automation and communicate using unix socket").argument("<socket-path>", "path to unix socket").action(async socketPath => {
|
|
56
56
|
let context;
|
|
57
|
-
const throttleTime =
|
|
57
|
+
const throttleTime = 60 * 1000;
|
|
58
58
|
let timeoutTimestamp = Date.now();
|
|
59
59
|
const client = net.createConnection(socketPath);
|
|
60
60
|
let generator = null;
|
|
@@ -130,7 +130,7 @@ function runAutomationCLI(importFunction) {
|
|
|
130
130
|
});
|
|
131
131
|
context = {
|
|
132
132
|
extendedPayloads: [],
|
|
133
|
-
runEnvironment: input.parameters.runOptions.environment === "
|
|
133
|
+
runEnvironment: input.parameters.runOptions.environment === "standalone" ? _enums.RunEnvironment.DEPLOYED : _enums.RunEnvironment.IDE,
|
|
134
134
|
timeoutInfo: {
|
|
135
135
|
extendTimeoutCallback: async () => {
|
|
136
136
|
if (Date.now() - timeoutTimestamp < throttleTime) return;
|
|
@@ -172,7 +172,7 @@ function runAutomationCLI(importFunction) {
|
|
|
172
172
|
_commander.program.parse(process.argv);
|
|
173
173
|
}
|
|
174
174
|
function getProxyUrlFromRunOptions(runOptions) {
|
|
175
|
-
if ((runOptions === null || runOptions === void 0 ? void 0 : runOptions.environment) !== "
|
|
175
|
+
if ((runOptions === null || runOptions === void 0 ? void 0 : runOptions.environment) !== "standalone") return undefined;
|
|
176
176
|
const proxy = runOptions.proxy;
|
|
177
177
|
if (!proxy) return undefined;
|
|
178
178
|
const url = new URL(proxy.server);
|
|
@@ -67,7 +67,7 @@ async function* runApiGenerator({
|
|
|
67
67
|
let page;
|
|
68
68
|
let context;
|
|
69
69
|
let downloadsPath;
|
|
70
|
-
if (runOptions.environment === "
|
|
70
|
+
if (runOptions.environment === "standalone") {
|
|
71
71
|
downloadsPath = (0, _downloadDirectory.getDownloadDirectoryPath)();
|
|
72
72
|
const {
|
|
73
73
|
headless,
|
|
@@ -236,7 +236,7 @@ async function checkAuthSessionWithRetries(page, context, importFunction, retrie
|
|
|
236
236
|
}
|
|
237
237
|
async function importUsingImportFunction(path, importFunction) {
|
|
238
238
|
try {
|
|
239
|
-
const imported = importFunction ? await importFunction(path) : await (specifier => new Promise(r => r(specifier)).then(s => _interopRequireWildcard(require(s))))(
|
|
239
|
+
const imported = importFunction ? await importFunction(path) : await (specifier => new Promise(r => r(specifier)).then(s => _interopRequireWildcard(require(s))))(`../../../${path}.ts`);
|
|
240
240
|
if (!imported || !imported.default || !imported.default.constructor) {
|
|
241
241
|
return (0, _neverthrow.err)(new _errors.InvalidApiError("API file path does not have a default export"));
|
|
242
242
|
}
|
|
@@ -254,6 +254,7 @@ async function importUsingImportFunction(path, importFunction) {
|
|
|
254
254
|
}
|
|
255
255
|
return (0, _neverthrow.err)(new _errors.InvalidApiError("API file path does not have a default async function/generator export"));
|
|
256
256
|
} catch (error) {
|
|
257
|
+
console.error(error);
|
|
257
258
|
return (0, _neverthrow.err)(new _errors.ApiNotFoundError(path));
|
|
258
259
|
}
|
|
259
260
|
}
|
|
@@ -520,7 +520,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
520
520
|
runCheck?: boolean | undefined;
|
|
521
521
|
}>>;
|
|
522
522
|
runOptions: z.ZodDefault<z.ZodDiscriminatedUnion<"environment", [z.ZodObject<{
|
|
523
|
-
environment: z.ZodLiteral<"
|
|
523
|
+
environment: z.ZodLiteral<"standalone">;
|
|
524
524
|
headless: z.ZodDefault<z.ZodBoolean>;
|
|
525
525
|
proxy: z.ZodOptional<z.ZodObject<{
|
|
526
526
|
server: z.ZodString;
|
|
@@ -536,7 +536,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
536
536
|
password: string;
|
|
537
537
|
}>>;
|
|
538
538
|
}, "strip", z.ZodTypeAny, {
|
|
539
|
-
environment: "
|
|
539
|
+
environment: "standalone";
|
|
540
540
|
headless: boolean;
|
|
541
541
|
proxy?: {
|
|
542
542
|
server: string;
|
|
@@ -544,7 +544,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
544
544
|
password: string;
|
|
545
545
|
} | undefined;
|
|
546
546
|
}, {
|
|
547
|
-
environment: "
|
|
547
|
+
environment: "standalone";
|
|
548
548
|
headless?: boolean | undefined;
|
|
549
549
|
proxy?: {
|
|
550
550
|
server: string;
|
|
@@ -552,16 +552,16 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
552
552
|
password: string;
|
|
553
553
|
} | undefined;
|
|
554
554
|
}>, z.ZodObject<{
|
|
555
|
-
environment: z.ZodLiteral<"
|
|
555
|
+
environment: z.ZodLiteral<"cdp">;
|
|
556
556
|
cdpAddress: z.ZodString;
|
|
557
557
|
mode: z.ZodUnion<[z.ZodLiteral<"vanilla">, z.ZodLiteral<"playwright">, z.ZodLiteral<"playwright-standalone">, z.ZodLiteral<"playwright-headless">]>;
|
|
558
558
|
}, "strip", z.ZodTypeAny, {
|
|
559
559
|
mode: "vanilla" | "playwright" | "playwright-standalone" | "playwright-headless";
|
|
560
|
-
environment: "
|
|
560
|
+
environment: "cdp";
|
|
561
561
|
cdpAddress: string;
|
|
562
562
|
}, {
|
|
563
563
|
mode: "vanilla" | "playwright" | "playwright-standalone" | "playwright-headless";
|
|
564
|
-
environment: "
|
|
564
|
+
environment: "cdp";
|
|
565
565
|
cdpAddress: string;
|
|
566
566
|
}>]>>;
|
|
567
567
|
retrieveSession: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -577,7 +577,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
577
577
|
filePath: string;
|
|
578
578
|
};
|
|
579
579
|
runOptions: {
|
|
580
|
-
environment: "
|
|
580
|
+
environment: "standalone";
|
|
581
581
|
headless: boolean;
|
|
582
582
|
proxy?: {
|
|
583
583
|
server: string;
|
|
@@ -586,7 +586,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
586
586
|
} | undefined;
|
|
587
587
|
} | {
|
|
588
588
|
mode: "vanilla" | "playwright" | "playwright-standalone" | "playwright-headless";
|
|
589
|
-
environment: "
|
|
589
|
+
environment: "cdp";
|
|
590
590
|
cdpAddress: string;
|
|
591
591
|
};
|
|
592
592
|
retrieveSession: boolean;
|
|
@@ -672,7 +672,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
672
672
|
runCheck?: boolean | undefined;
|
|
673
673
|
} | undefined;
|
|
674
674
|
runOptions?: {
|
|
675
|
-
environment: "
|
|
675
|
+
environment: "standalone";
|
|
676
676
|
headless?: boolean | undefined;
|
|
677
677
|
proxy?: {
|
|
678
678
|
server: string;
|
|
@@ -681,7 +681,7 @@ export declare const runApiParametersSchema: z.ZodObject<{
|
|
|
681
681
|
} | undefined;
|
|
682
682
|
} | {
|
|
683
683
|
mode: "vanilla" | "playwright" | "playwright-standalone" | "playwright-headless";
|
|
684
|
-
environment: "
|
|
684
|
+
environment: "cdp";
|
|
685
685
|
cdpAddress: string;
|
|
686
686
|
} | undefined;
|
|
687
687
|
retrieveSession?: boolean | undefined;
|
|
@@ -56,7 +56,7 @@ const runApiParametersSchema = exports.runApiParametersSchema = _zod.default.obj
|
|
|
56
56
|
runCheck: _zod.default.boolean().default(false)
|
|
57
57
|
}).optional(),
|
|
58
58
|
runOptions: _zod.default.discriminatedUnion("environment", [_zod.default.object({
|
|
59
|
-
environment: _zod.default.literal("
|
|
59
|
+
environment: _zod.default.literal("standalone"),
|
|
60
60
|
headless: _zod.default.boolean().default(true),
|
|
61
61
|
proxy: _zod.default.object({
|
|
62
62
|
server: _zod.default.string(),
|
|
@@ -64,11 +64,11 @@ const runApiParametersSchema = exports.runApiParametersSchema = _zod.default.obj
|
|
|
64
64
|
password: _zod.default.string()
|
|
65
65
|
}).optional()
|
|
66
66
|
}), _zod.default.object({
|
|
67
|
-
environment: _zod.default.literal("
|
|
67
|
+
environment: _zod.default.literal("cdp"),
|
|
68
68
|
cdpAddress: _zod.default.string(),
|
|
69
69
|
mode: _zod.default.union([_zod.default.literal("vanilla"), _zod.default.literal("playwright"), _zod.default.literal("playwright-standalone"), _zod.default.literal("playwright-headless")])
|
|
70
70
|
})]).default({
|
|
71
|
-
environment: "
|
|
71
|
+
environment: "standalone"
|
|
72
72
|
}),
|
|
73
73
|
retrieveSession: _zod.default.boolean().default(false)
|
|
74
74
|
});
|