@intuned/runtime-dev 0.1.0-test.4 → 0.1.0-test.41
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/InterfaceTemplate/index.playwright.ts +5 -0
- package/InterfaceTemplate/utils.ts +257 -0
- package/Intuned.json +1 -1
- package/WebTemplate/api.ts +90 -92
- package/WebTemplate/controllers/async.ts +52 -48
- package/WebTemplate/controllers/authSessions/check.ts +3 -4
- package/WebTemplate/controllers/authSessions/create.ts +5 -7
- package/WebTemplate/controllers/authSessions/resumeOperation.ts +1 -1
- package/WebTemplate/controllers/runApi/helpers.ts +12 -7
- package/WebTemplate/index.playwright.ts +32 -42
- package/WebTemplate/jobs.ts +13 -2
- package/WebTemplate/utils.ts +48 -1
- package/api/test2.ts +7 -5
- package/auth-sessions/check.ts +3 -1
- package/auth-sessions/create.ts +10 -10
- package/bin/intuned-ts-check +1 -1
- package/dist/commands/api/run.js +6 -4
- package/dist/commands/auth-sessions/run-check.js +8 -2
- package/dist/commands/auth-sessions/run-create.js +10 -5
- package/dist/commands/build.js +16 -13
- package/dist/commands/common/tsNodeImport.d.ts +1 -0
- package/dist/commands/common/{getDefaultExportFromFile.js → tsNodeImport.js} +6 -5
- package/dist/commands/common/utils/settings.js +5 -5
- package/dist/commands/common/utils/template.d.ts +2 -0
- package/dist/commands/common/utils/{webTemplate.js → template.js} +7 -7
- package/dist/commands/interface/run.d.ts +1 -1
- package/dist/commands/interface/run.js +131 -106
- package/dist/commands/ts-check.js +9 -7
- package/dist/common/formatZodError.d.ts +2 -0
- package/dist/common/formatZodError.js +18 -0
- package/dist/common/getPlaywrightConstructs.js +5 -1
- package/dist/common/runApi/errors.d.ts +8 -3
- package/dist/common/runApi/errors.js +26 -3
- package/dist/common/runApi/index.d.ts +1 -1
- package/dist/common/runApi/index.js +33 -55
- package/dist/common/runApi/types.d.ts +277 -61
- package/dist/common/runApi/types.js +26 -2
- package/dist/runtime/executionHelpers.test.js +6 -6
- package/package.json +5 -3
- package/tsconfig.json +1 -2
- package/InterfaceTemplate/index.ts +0 -1
- package/dist/commands/common/getDefaultExportFromFile.d.ts +0 -1
- package/dist/commands/common/utils/webTemplate.d.ts +0 -1
- package/testing +0 -0
|
@@ -0,0 +1,257 @@
|
|
|
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
|
+
export async function importModule(path: string) {
|
|
213
|
+
const [folderName, ...functionNameParts] = path.split("/");
|
|
214
|
+
const functionNameDepth = functionNameParts.length;
|
|
215
|
+
|
|
216
|
+
// string literals should be inline
|
|
217
|
+
// currently we support only 5 levels of depth
|
|
218
|
+
// rollup dynamic import does not support multiple levels of dynamic imports so we need to specify the possible paths explicitly
|
|
219
|
+
try {
|
|
220
|
+
let imported: any = undefined;
|
|
221
|
+
switch (functionNameDepth) {
|
|
222
|
+
case 1:
|
|
223
|
+
imported = await import(`./${folderName}/${functionNameParts[0]}.ts`);
|
|
224
|
+
break;
|
|
225
|
+
case 2:
|
|
226
|
+
imported = await import(
|
|
227
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}.ts`
|
|
228
|
+
);
|
|
229
|
+
break;
|
|
230
|
+
case 3:
|
|
231
|
+
imported = await import(
|
|
232
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}.ts`
|
|
233
|
+
);
|
|
234
|
+
break;
|
|
235
|
+
case 4:
|
|
236
|
+
imported = await import(
|
|
237
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}.ts`
|
|
238
|
+
);
|
|
239
|
+
break;
|
|
240
|
+
case 5:
|
|
241
|
+
imported = await import(
|
|
242
|
+
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}/${functionNameParts[4]}.ts`
|
|
243
|
+
);
|
|
244
|
+
break;
|
|
245
|
+
default:
|
|
246
|
+
throw new Error(
|
|
247
|
+
"intuned supports maximum 5 levels of depth in the api folder"
|
|
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;
|
|
256
|
+
}
|
|
257
|
+
}
|
package/Intuned.json
CHANGED
package/WebTemplate/api.ts
CHANGED
|
@@ -33,109 +33,107 @@ import {
|
|
|
33
33
|
} from "./headers";
|
|
34
34
|
import { FEATURES } from "./features";
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
app.get(
|
|
58
|
-
"/api/protected/health",
|
|
59
|
-
accessKeyValidatorMiddleware,
|
|
60
|
-
async (req, res) => {
|
|
61
|
-
res.status(200).json({ status: "ok" });
|
|
62
|
-
}
|
|
63
|
-
);
|
|
36
|
+
if (!isJobRunMachine()) {
|
|
37
|
+
app.use((req, _, next) => {
|
|
38
|
+
const runId = req.headers[RUN_ID_HEADER] as string;
|
|
39
|
+
const jobId = req.headers[JOB_ID_HEADER] as string;
|
|
40
|
+
const jobRunId = req.headers[JOB_RUN_ID_HEADER] as string;
|
|
41
|
+
const queueId = req.headers[QUEUE_ID_HEADER] as string;
|
|
42
|
+
const proxy = req?.body?.proxy
|
|
43
|
+
? (proxyToUrl(req.body.proxy as ProxyConfig) as string)
|
|
44
|
+
: undefined;
|
|
45
|
+
const contextData = {
|
|
46
|
+
runId: runId ?? "",
|
|
47
|
+
jobId,
|
|
48
|
+
jobRunId,
|
|
49
|
+
queueId,
|
|
50
|
+
proxy,
|
|
51
|
+
...(req?.body?.executionContext ?? {}),
|
|
52
|
+
};
|
|
53
|
+
runWithContext(contextData, next);
|
|
54
|
+
});
|
|
64
55
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
app.get(
|
|
57
|
+
"/api/protected/health",
|
|
58
|
+
accessKeyValidatorMiddleware,
|
|
59
|
+
async (req, res) => {
|
|
60
|
+
res.status(200).json({ status: "ok" });
|
|
61
|
+
}
|
|
62
|
+
);
|
|
70
63
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
app.post(
|
|
65
|
+
"/api/auth-session/create",
|
|
66
|
+
accessKeyValidatorMiddleware,
|
|
67
|
+
errorRetryMiddleware(createAuthSessionController)
|
|
68
|
+
);
|
|
76
69
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
app.post(
|
|
71
|
+
"/api/auth-session-async/create",
|
|
72
|
+
accessKeyValidatorMiddleware,
|
|
73
|
+
errorRetryMiddleware(createAuthSessionAsyncController)
|
|
74
|
+
);
|
|
82
75
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
app.post(
|
|
77
|
+
"/api/auth-session/check",
|
|
78
|
+
accessKeyValidatorMiddleware,
|
|
79
|
+
errorRetryMiddleware(checkAuthSessionController)
|
|
80
|
+
);
|
|
88
81
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
82
|
+
app.post(
|
|
83
|
+
"/api/auth-session-async/check",
|
|
84
|
+
accessKeyValidatorMiddleware,
|
|
85
|
+
errorRetryMiddleware(checkAuthSessionAsyncController)
|
|
86
|
+
);
|
|
94
87
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
88
|
+
app.post(
|
|
89
|
+
"/api/auth-session/kill",
|
|
90
|
+
accessKeyValidatorMiddleware,
|
|
91
|
+
errorRetryMiddleware(killAuthSessionOperationController)
|
|
92
|
+
);
|
|
100
93
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
94
|
+
app.post(
|
|
95
|
+
"/api/auth-session/resume",
|
|
96
|
+
accessKeyValidatorMiddleware,
|
|
97
|
+
errorRetryMiddleware(resumeAuthSessionOperationController)
|
|
98
|
+
);
|
|
106
99
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
app.post(
|
|
101
|
+
"/api/auth-session-async/resume",
|
|
102
|
+
accessKeyValidatorMiddleware,
|
|
103
|
+
errorRetryMiddleware(resumeAuthSessionOperationAsyncController)
|
|
104
|
+
);
|
|
112
105
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
app.post(
|
|
107
|
+
"/api/run/*",
|
|
108
|
+
accessKeyValidatorMiddleware,
|
|
109
|
+
errorRetryMiddleware(runApiController)
|
|
110
|
+
);
|
|
118
111
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
112
|
+
app.post(
|
|
113
|
+
"/api/run-async/start/*",
|
|
114
|
+
accessKeyValidatorMiddleware,
|
|
115
|
+
errorRetryMiddleware(runApiAsyncController) // todo: this probably needs changing
|
|
116
|
+
);
|
|
124
117
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
app.get(
|
|
119
|
+
"/api/run-async/count",
|
|
120
|
+
accessKeyValidatorMiddleware,
|
|
121
|
+
getActiveAsyncEndpointController
|
|
122
|
+
);
|
|
130
123
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
124
|
+
app.post(
|
|
125
|
+
"/api/trace/upload/:runId",
|
|
126
|
+
accessKeyValidatorMiddleware,
|
|
127
|
+
uploadTraceController
|
|
128
|
+
);
|
|
137
129
|
|
|
138
|
-
app.
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
app.post(
|
|
131
|
+
"/api/trace/delete/:runId",
|
|
132
|
+
accessKeyValidatorMiddleware,
|
|
133
|
+
deleteTraceController
|
|
134
|
+
);
|
|
141
135
|
}
|
|
136
|
+
|
|
137
|
+
app.get("/api/features", accessKeyValidatorMiddleware, async (_, res) => {
|
|
138
|
+
res.status(200).json({ features: FEATURES });
|
|
139
|
+
});
|
|
@@ -40,59 +40,63 @@ export async function runEndpointAsync<_Parameters extends any[], _Result>(
|
|
|
40
40
|
} catch (e: any) {
|
|
41
41
|
console.error(`Error running ${requestId} in async mode:`, e);
|
|
42
42
|
({ status, body } = getErrorResponse(e));
|
|
43
|
-
} finally {
|
|
44
|
-
AsyncRunEndpointController.removeRequest(taskToken);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
// report result
|
|
48
|
-
console.log("Reporting result for", requestId);
|
|
49
45
|
try {
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
46
|
+
// report result
|
|
47
|
+
console.log("Reporting result for", requestId);
|
|
48
|
+
try {
|
|
49
|
+
// `retry` will keep retrying any errors unless they are thrown through calling `bail`
|
|
50
|
+
await retry(
|
|
51
|
+
async (bail: (e: Error) => void) => {
|
|
52
|
+
const response = await callBackendFunctionWithToken(
|
|
53
|
+
"run/reportResult",
|
|
54
|
+
{
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "application/json",
|
|
58
|
+
"fly-instance-id": process.env.FLY_ALLOC_ID ?? "",
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
status,
|
|
62
|
+
body,
|
|
63
|
+
startTime,
|
|
64
|
+
taskToken,
|
|
65
|
+
}),
|
|
66
|
+
}
|
|
67
|
+
).catch((e) => {
|
|
68
|
+
const message = `Reporting result failed for ${requestId}, error: ${e.message}`;
|
|
69
|
+
console.error(message);
|
|
70
|
+
throw e;
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
// Do not retry unauthenticated, forbidden, not found or too large responses
|
|
74
|
+
if ([401, 403, 404, 413].includes(response.status)) {
|
|
75
|
+
const message = `Reporting result failed for ${requestId} (non-retryable), status ${response.status}`;
|
|
76
|
+
console.error(message);
|
|
77
|
+
bail(new Error(message));
|
|
78
|
+
}
|
|
79
|
+
// retry other errors (such as 502)
|
|
80
|
+
const message = `Reporting result failed for ${requestId}, status ${response.status}`;
|
|
81
|
+
console.error(message);
|
|
82
|
+
throw new Error(message);
|
|
77
83
|
}
|
|
78
|
-
// retry other errors (such as 502)
|
|
79
|
-
throw new Error(
|
|
80
|
-
`Reporting result failed for ${requestId}, status ${response.status}`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
return response;
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
retries: 5,
|
|
89
|
+
factor: 2,
|
|
90
|
+
maxTimeout: 1000 * 60, // 1 minute
|
|
91
|
+
minTimeout: 1000 * 5, // 5 seconds
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
console.log("Reported result for", requestId);
|
|
95
|
+
} catch (e: any) {
|
|
96
|
+
// ignore
|
|
97
|
+
}
|
|
98
|
+
} finally {
|
|
99
|
+
AsyncRunEndpointController.removeRequest(taskToken);
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
await ShutdownController.instance.checkForShutdown();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readJSON } from "fs-extra";
|
|
2
2
|
import { isHeadless } from "../../utils";
|
|
3
3
|
import { runApi } from "@intuned/runtime/dist/common/runApi";
|
|
4
|
+
import { importModule } from "../../utils";
|
|
4
5
|
|
|
5
6
|
export async function checkAuthSession({
|
|
6
7
|
proxy,
|
|
@@ -46,12 +47,10 @@ export async function checkAuthSession({
|
|
|
46
47
|
},
|
|
47
48
|
runCheck: false,
|
|
48
49
|
},
|
|
50
|
+
importFunction: importModule,
|
|
49
51
|
});
|
|
50
52
|
if (result.isErr()) {
|
|
51
|
-
return
|
|
52
|
-
status: 500,
|
|
53
|
-
body: result.error,
|
|
54
|
-
};
|
|
53
|
+
return result.error.apiResponse;
|
|
55
54
|
}
|
|
56
55
|
return {
|
|
57
56
|
status: 200,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { authSessionsContextsStore } from "./store";
|
|
2
|
-
import { getTraceFilePath, isHeadless } from "../../utils";
|
|
2
|
+
import { getTraceFilePath, isHeadless, importModule } from "../../utils";
|
|
3
3
|
import * as fs from "fs-extra";
|
|
4
4
|
import { runApiGenerator } from "@intuned/runtime/dist/common/runApi";
|
|
5
5
|
import type { RequestMoreInfoDetails } from "@intuned/runtime/dist/runtime";
|
|
@@ -54,7 +54,7 @@ export async function createAuthSession({
|
|
|
54
54
|
>({
|
|
55
55
|
automationFunction: {
|
|
56
56
|
name: "auth-sessions/create",
|
|
57
|
-
params: parameters
|
|
57
|
+
params: parameters,
|
|
58
58
|
},
|
|
59
59
|
tracing: saveTrace
|
|
60
60
|
? {
|
|
@@ -69,18 +69,16 @@ export async function createAuthSession({
|
|
|
69
69
|
},
|
|
70
70
|
abortSignal: abortController.signal,
|
|
71
71
|
retrieveSession: true,
|
|
72
|
+
importFunction: importModule,
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
const result = await createGenerator.next();
|
|
75
76
|
|
|
76
|
-
if (result.done) {
|
|
77
|
+
if (result.done === true) {
|
|
77
78
|
const r = result.value;
|
|
78
79
|
|
|
79
80
|
if (r.isErr()) {
|
|
80
|
-
return
|
|
81
|
-
status: 500,
|
|
82
|
-
body: r.error,
|
|
83
|
-
};
|
|
81
|
+
return r.error.apiResponse;
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
return {
|
|
@@ -33,7 +33,7 @@ export async function resumeAuthSessionOperation({
|
|
|
33
33
|
|
|
34
34
|
const result = await operation.generator.next(input);
|
|
35
35
|
|
|
36
|
-
if (result.done) {
|
|
36
|
+
if (result.done === true) {
|
|
37
37
|
authSessionsContextsStore.delete(operationId);
|
|
38
38
|
if (result.value.isErr()) {
|
|
39
39
|
return result.value.error.apiResponse;
|