@intuned/runtime-dev 0.0.1 → 0.1.0-test.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.
- package/InterfaceTemplate/index.ts +1 -0
- package/Intuned.json +5 -0
- package/WebTemplate/api.ts +92 -90
- package/WebTemplate/controllers/authSessions/check.ts +23 -29
- package/WebTemplate/controllers/authSessions/create.ts +46 -71
- package/WebTemplate/controllers/authSessions/index.ts +4 -4
- package/WebTemplate/controllers/authSessions/killOperation.ts +1 -1
- package/WebTemplate/controllers/authSessions/resumeOperation.ts +28 -52
- package/WebTemplate/controllers/authSessions/store.ts +11 -6
- package/WebTemplate/controllers/runApi/helpers.ts +47 -146
- package/WebTemplate/index.playwright.ts +42 -32
- package/WebTemplate/index.vanilla.ts +2 -20
- package/WebTemplate/jobs.ts +2 -13
- package/WebTemplate/utils.ts +1 -85
- package/WebTemplate.zip +0 -0
- package/api/authed.ts +12 -0
- package/api/test.ts +3 -0
- package/api/test2.ts +25 -0
- package/auth-sessions/check.ts +9 -0
- package/auth-sessions/create.ts +32 -0
- package/authSessions +1 -0
- package/bin/intuned-api-run +2 -0
- package/bin/intuned-auth-session-check +2 -0
- package/bin/intuned-auth-session-create +2 -0
- package/bin/intuned-auth-session-load +2 -0
- package/bin/intuned-auth-session-refresh +2 -0
- package/bin/intuned-browser-save-state +2 -0
- package/bin/intuned-browser-start +2 -0
- package/bin/intuned-build +2 -0
- package/bin/intuned-ts-check +2 -0
- package/dist/commands/api/run.d.ts +6 -0
- package/dist/commands/api/run.js +113 -0
- package/dist/commands/auth-sessions/load.d.ts +2 -0
- package/dist/commands/auth-sessions/load.js +32 -0
- package/dist/commands/auth-sessions/run-check.d.ts +2 -0
- package/dist/commands/auth-sessions/run-check.js +56 -0
- package/dist/commands/auth-sessions/run-create.d.ts +2 -0
- package/dist/commands/auth-sessions/run-create.js +96 -0
- package/dist/commands/browser/save-state.d.ts +2 -0
- package/dist/commands/browser/save-state.js +17 -0
- package/dist/commands/browser/start-browser.d.ts +2 -0
- package/dist/commands/browser/start-browser.js +14 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.js +83 -0
- package/dist/commands/common/browserUtils.d.ts +14 -0
- package/dist/commands/common/browserUtils.js +58 -0
- package/dist/commands/common/getDefaultExportFromFile.d.ts +1 -0
- package/dist/commands/common/getDefaultExportFromFile.js +19 -0
- package/dist/commands/common/getFirstLineNumber.d.ts +9 -0
- package/dist/commands/common/getFirstLineNumber.js +103 -0
- package/{src/commands/common/getFirstLineNumber.test.ts → dist/commands/common/getFirstLineNumber.test.js} +75 -121
- package/dist/commands/common/sendMessageToClient.d.ts +1 -0
- package/dist/commands/common/sendMessageToClient.js +10 -0
- package/dist/commands/common/utils/fileUtils.d.ts +6 -0
- package/dist/commands/common/utils/fileUtils.js +33 -0
- package/dist/commands/common/utils/settings.d.ts +2 -0
- package/dist/commands/common/utils/settings.js +28 -0
- package/dist/commands/common/utils/unixSocket.d.ts +9 -0
- package/dist/commands/common/utils/unixSocket.js +45 -0
- package/dist/commands/common/utils/webTemplate.d.ts +1 -0
- package/dist/commands/common/utils/webTemplate.js +31 -0
- package/dist/commands/interface/run.d.ts +2 -0
- package/dist/commands/interface/run.js +161 -0
- package/dist/commands/ts-check.d.ts +2 -0
- package/dist/commands/ts-check.js +54 -0
- package/dist/common/Logger/Logger/index.d.ts +12 -0
- package/dist/common/Logger/Logger/index.js +60 -0
- package/{src/common/Logger/Logger/types.ts → dist/common/Logger/Logger/types.d.ts} +4 -5
- package/dist/common/Logger/Logger/types.js +5 -0
- package/dist/common/Logger/index.d.ts +12 -0
- package/dist/common/Logger/index.js +60 -0
- package/{src/common/Logger/types.ts → dist/common/Logger/types.d.ts} +4 -5
- package/dist/common/Logger/types.js +5 -0
- package/dist/common/asyncLocalStorage/index.d.ts +16 -0
- package/dist/common/asyncLocalStorage/index.js +17 -0
- package/dist/common/cleanEnvironmentVariables.d.ts +1 -0
- package/dist/common/cleanEnvironmentVariables.js +16 -0
- package/dist/common/constants.d.ts +1 -0
- package/dist/common/constants.js +7 -0
- package/dist/common/contextStorageStateHelpers.d.ts +14 -0
- package/dist/common/contextStorageStateHelpers.js +50 -0
- package/dist/common/getPlaywrightConstructs.d.ts +30 -0
- package/dist/common/getPlaywrightConstructs.js +192 -0
- package/dist/common/jwtTokenManager.d.ts +16 -0
- package/dist/common/jwtTokenManager.js +81 -0
- package/dist/common/runApi/errors.d.ts +71 -0
- package/dist/common/runApi/errors.js +172 -0
- package/dist/common/runApi/index.d.ts +12 -0
- package/dist/common/runApi/index.js +288 -0
- package/dist/common/runApi/types.d.ts +486 -0
- package/dist/common/runApi/types.js +50 -0
- package/dist/common/settingsSchema.d.ts +19 -0
- package/dist/common/settingsSchema.js +17 -0
- package/dist/common/telemetry.d.ts +3 -0
- package/dist/common/telemetry.js +32 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +69 -0
- package/dist/runtime/RunError.d.ts +5 -0
- package/dist/runtime/RunError.js +19 -0
- package/dist/runtime/downloadDirectory.d.ts +1 -0
- package/dist/runtime/downloadDirectory.js +19 -0
- package/dist/runtime/enums.d.js +5 -0
- package/dist/runtime/enums.js +18 -0
- package/dist/runtime/executionHelpers.test.js +53 -0
- package/dist/runtime/export.d.js +5 -0
- package/dist/runtime/extendPayload.d.ts +2 -0
- package/dist/runtime/extendPayload.js +21 -0
- package/dist/runtime/extendTimeout.d.ts +1 -0
- package/dist/runtime/extendTimeout.js +30 -0
- package/{src/runtime/index.ts → dist/runtime/index.d.ts} +2 -3
- package/dist/runtime/index.js +53 -0
- package/dist/runtime/requestMoreInfo.d.ts +18 -0
- package/dist/runtime/requestMoreInfo.js +25 -0
- package/dist/runtime/runInfo.d.ts +2 -0
- package/dist/runtime/runInfo.js +21 -0
- package/output.txt +39 -0
- package/package.json +9 -7
- package/testing +0 -0
- package/tsconfig.json +2 -1
- package/.vite/deps_temp_01af7156/package.json +0 -3
- package/.vscode/extensions.json +0 -3
- package/.vscode/launch.json +0 -102
- package/.vscode/settings.json +0 -12
- package/playwright.config.ts +0 -48
- package/src/commands/api/run.ts +0 -225
- package/src/commands/auth-sessions/load.ts +0 -42
- package/src/commands/auth-sessions/run-check.ts +0 -70
- package/src/commands/auth-sessions/run-create.ts +0 -124
- package/src/commands/browser/save-state.ts +0 -22
- package/src/commands/browser/start-browser.ts +0 -17
- package/src/commands/build.ts +0 -125
- package/src/commands/common/browserUtils.ts +0 -80
- package/src/commands/common/getDefaultExportFromFile.ts +0 -13
- package/src/commands/common/getFirstLineNumber.ts +0 -146
- package/src/commands/common/sendMessageToClient.ts +0 -8
- package/src/commands/common/utils/fileUtils.ts +0 -25
- package/src/commands/common/utils/settings.ts +0 -23
- package/src/commands/common/utils/webTemplate.ts +0 -46
- package/src/commands/testing/saveVisibleHtml.ts +0 -29
- package/src/commands/ts-check.ts +0 -88
- package/src/common/Logger/Logger/index.ts +0 -64
- package/src/common/Logger/index.ts +0 -64
- package/src/common/asyncLocalStorage/index.ts +0 -29
- package/src/common/cleanEnvironmentVariables.ts +0 -13
- package/src/common/constants.ts +0 -1
- package/src/common/contextStorageStateHelpers.ts +0 -71
- package/src/common/getPlaywrightConstructs.ts +0 -283
- package/src/common/jwtTokenManager.ts +0 -111
- package/src/common/settingsSchema.ts +0 -16
- package/src/common/telemetry.ts +0 -49
- package/src/index.ts +0 -14
- package/src/runtime/RunError.ts +0 -16
- package/src/runtime/downloadDirectory.ts +0 -14
- package/src/runtime/enums.ts +0 -11
- package/src/runtime/executionHelpers.test.ts +0 -70
- package/src/runtime/extendPayload.ts +0 -22
- package/src/runtime/extendTimeout.ts +0 -32
- package/src/runtime/requestMoreInfo.ts +0 -40
- package/src/runtime/runInfo.ts +0 -19
- package/vite.config.ts +0 -17
- /package/{src → dist}/common/assets/browser_scripts.js +0 -0
- /package/{src → dist}/runtime/enums.d.ts +0 -0
- /package/{src → dist}/runtime/export.d.ts +0 -0
|
@@ -1,27 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
callFunction,
|
|
3
|
-
getTraceFilePath,
|
|
4
|
-
checkAuthSessionWithRetries,
|
|
5
|
-
waitWithExtendableTimeout,
|
|
6
|
-
} from "../../utils";
|
|
7
|
-
import { IntunedSettings } from "@intuned/runtime/dist/common/settingsSchema";
|
|
8
|
-
import { getDownloadDirectoryPath } from "@intuned/runtime";
|
|
9
|
-
import { getProductionPlaywrightConstructs } from "@intuned/runtime";
|
|
1
|
+
import { getTraceFilePath, waitWithExtendableTimeout } from "../../utils";
|
|
10
2
|
import * as fs from "fs-extra";
|
|
11
|
-
// @ts-ignore
|
|
12
|
-
import { PayloadItem } from "../../../src/common/types";
|
|
13
|
-
import { getTelemetryClient } from "@intuned/runtime/dist/common/telemetry";
|
|
14
3
|
import { getExecutionContext } from "@intuned/runtime";
|
|
15
4
|
import { backendFunctionsTokenManager } from "@intuned/runtime/dist/common/jwtTokenManager";
|
|
16
|
-
import { setContextStorageState } from "@intuned/runtime/dist/common/contextStorageStateHelpers";
|
|
17
|
-
import { remove } from "fs-extra";
|
|
18
5
|
import { RunBody } from "./types";
|
|
6
|
+
import { runApi as runApiInternal } from "@intuned/runtime/dist/common/runApi";
|
|
19
7
|
|
|
20
8
|
export async function runApi({
|
|
21
9
|
session,
|
|
22
10
|
params,
|
|
23
11
|
proxy,
|
|
24
|
-
executionContext,
|
|
25
12
|
functionsToken,
|
|
26
13
|
runId,
|
|
27
14
|
attemptNumber,
|
|
@@ -38,9 +25,8 @@ export async function runApi({
|
|
|
38
25
|
status: number;
|
|
39
26
|
body: any;
|
|
40
27
|
}> {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const traceFilePath = getTraceFilePath(runId, attemptNumber);
|
|
28
|
+
const isAuthSessionEnabled = (await fs.readJSON("./Intuned.json"))
|
|
29
|
+
.authSessions?.enabled;
|
|
44
30
|
|
|
45
31
|
if (!runId) {
|
|
46
32
|
return {
|
|
@@ -52,15 +38,7 @@ export async function runApi({
|
|
|
52
38
|
};
|
|
53
39
|
}
|
|
54
40
|
|
|
55
|
-
let traceStarted = false;
|
|
56
|
-
|
|
57
41
|
backendFunctionsTokenManager.token = functionsToken;
|
|
58
|
-
const downloadsPath = getDownloadDirectoryPath();
|
|
59
|
-
const { page, context } = await getProductionPlaywrightConstructs({
|
|
60
|
-
headless,
|
|
61
|
-
proxy,
|
|
62
|
-
downloadsPath,
|
|
63
|
-
});
|
|
64
42
|
|
|
65
43
|
// handle timeout
|
|
66
44
|
const requestTimeout = +(process.env.REQUEST_TIMEOUT ?? 600) * 1000;
|
|
@@ -69,23 +47,8 @@ export async function runApi({
|
|
|
69
47
|
timeoutDuration: requestTimeout,
|
|
70
48
|
};
|
|
71
49
|
|
|
72
|
-
async function saveTraceIfNeeded(errorMessage: string) {
|
|
73
|
-
if (!shouldSaveTrace || !traceStarted) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
try {
|
|
77
|
-
await context.tracing.stop({ path: traceFilePath });
|
|
78
|
-
} catch (error: any) {
|
|
79
|
-
console.log(errorMessage, error?.message);
|
|
80
|
-
await remove(traceFilePath);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
50
|
async function handleTimeout() {
|
|
85
51
|
console.log("timeout triggered");
|
|
86
|
-
await saveTraceIfNeeded("failed to save script after timeout");
|
|
87
|
-
|
|
88
|
-
await context.close();
|
|
89
52
|
|
|
90
53
|
return {
|
|
91
54
|
status: 508,
|
|
@@ -96,113 +59,35 @@ export async function runApi({
|
|
|
96
59
|
};
|
|
97
60
|
}
|
|
98
61
|
|
|
99
|
-
if (shouldSaveTrace) {
|
|
100
|
-
await context.tracing.start({
|
|
101
|
-
screenshots: true,
|
|
102
|
-
snapshots: true,
|
|
103
|
-
sources: true,
|
|
104
|
-
});
|
|
105
|
-
traceStarted = true;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const isAuthSessionsEnabled = (
|
|
109
|
-
(await fs.readJSON("./Intuned.json", "utf-8")) as IntunedSettings
|
|
110
|
-
).authSessions?.enabled;
|
|
111
|
-
|
|
112
62
|
const abortController = new AbortController();
|
|
113
|
-
async function runFunction() {
|
|
114
|
-
try {
|
|
115
|
-
if (isAuthSessionsEnabled) {
|
|
116
|
-
if (!session) {
|
|
117
|
-
await context.close();
|
|
118
|
-
return {
|
|
119
|
-
status: 401,
|
|
120
|
-
message: "auth sessions is required",
|
|
121
|
-
error: "auth sessions is required",
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
await setContextStorageState(context, session);
|
|
126
|
-
const authSessionCheckResult = await checkAuthSessionWithRetries(
|
|
127
|
-
page,
|
|
128
|
-
context,
|
|
129
|
-
2
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
if (abortController.signal.aborted) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (!authSessionCheckResult) {
|
|
137
|
-
try {
|
|
138
|
-
telemetryClient?.trackEvent({
|
|
139
|
-
name: "AUTH_SESSION_RECOVER_FAILED",
|
|
140
|
-
properties: {
|
|
141
|
-
runId,
|
|
142
|
-
functionName,
|
|
143
|
-
integrationId,
|
|
144
|
-
message: "auth session check failed",
|
|
145
|
-
},
|
|
146
|
-
});
|
|
147
|
-
await saveTraceIfNeeded("failed to save trace after check failed");
|
|
148
|
-
} catch (error: any) {
|
|
149
|
-
console.log(
|
|
150
|
-
"failed to save script after check failed",
|
|
151
|
-
error?.message
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
await context.close();
|
|
156
|
-
return {
|
|
157
|
-
status: 401,
|
|
158
|
-
message: "auth session check failed",
|
|
159
|
-
error: "AUTH_SESSION_CHECK_FAILED",
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
console.log("Running function", functionName);
|
|
165
|
-
const result = await callFunction("api", functionName as string, [
|
|
166
|
-
params ?? {},
|
|
167
|
-
page,
|
|
168
|
-
context,
|
|
169
|
-
]);
|
|
170
|
-
|
|
171
|
-
await saveTraceIfNeeded("failed to save trace after run is done");
|
|
172
|
-
await context.close();
|
|
173
|
-
|
|
174
|
-
const response: {
|
|
175
|
-
result: any;
|
|
176
|
-
updatedSession?: object;
|
|
177
|
-
payloadToAppend: PayloadItem[] | null;
|
|
178
|
-
// TODO: remove
|
|
179
|
-
metadata?: {
|
|
180
|
-
startTime: number;
|
|
181
|
-
endTime: number;
|
|
182
|
-
};
|
|
183
|
-
status?: number;
|
|
184
|
-
} = {
|
|
185
|
-
result,
|
|
186
|
-
updatedSession: undefined,
|
|
187
|
-
payloadToAppend: getExecutionContext()!.extendedPayloads?.map((i) => ({
|
|
188
|
-
apiName: i.api,
|
|
189
|
-
parameters: i.parameters,
|
|
190
|
-
})),
|
|
191
|
-
status: 200,
|
|
192
|
-
};
|
|
193
|
-
return response;
|
|
194
|
-
} catch (error) {
|
|
195
|
-
console.log("run errored", error);
|
|
196
|
-
await saveTraceIfNeeded("failed to save trace after run errored");
|
|
197
|
-
await context.close();
|
|
198
|
-
throw error;
|
|
199
|
-
} finally {
|
|
200
|
-
await fs.remove(downloadsPath);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
63
|
|
|
204
64
|
const resultWithTimeout = await waitWithExtendableTimeout({
|
|
205
|
-
promise:
|
|
65
|
+
promise: runApiInternal({
|
|
66
|
+
automationFunction: {
|
|
67
|
+
name: `api/${functionName}`,
|
|
68
|
+
params: params ?? {},
|
|
69
|
+
},
|
|
70
|
+
auth: {
|
|
71
|
+
session: {
|
|
72
|
+
type: "state",
|
|
73
|
+
state: session,
|
|
74
|
+
},
|
|
75
|
+
runCheck: isAuthSessionEnabled,
|
|
76
|
+
},
|
|
77
|
+
runOptions: {
|
|
78
|
+
environment: "deployed",
|
|
79
|
+
headless,
|
|
80
|
+
proxy,
|
|
81
|
+
},
|
|
82
|
+
tracing: shouldSaveTrace
|
|
83
|
+
? {
|
|
84
|
+
enabled: true,
|
|
85
|
+
filePath: getTraceFilePath(runId, attemptNumber),
|
|
86
|
+
}
|
|
87
|
+
: { enabled: false },
|
|
88
|
+
functionsToken,
|
|
89
|
+
abortSignal: abortController.signal,
|
|
90
|
+
}),
|
|
206
91
|
initialTimeout: requestTimeout,
|
|
207
92
|
abortController,
|
|
208
93
|
});
|
|
@@ -213,8 +98,24 @@ export async function runApi({
|
|
|
213
98
|
|
|
214
99
|
const { result } = resultWithTimeout;
|
|
215
100
|
|
|
101
|
+
if (result.isErr()) {
|
|
102
|
+
if (result.error.code === "AbortedError") {
|
|
103
|
+
return await handleTimeout();
|
|
104
|
+
}
|
|
105
|
+
return result.error.apiResponse;
|
|
106
|
+
}
|
|
107
|
+
|
|
216
108
|
return {
|
|
217
109
|
status: 200,
|
|
218
|
-
body:
|
|
110
|
+
body: {
|
|
111
|
+
status: 200,
|
|
112
|
+
result: result.value.result,
|
|
113
|
+
payloadToAppend: result.value.extendedPayloads?.map(
|
|
114
|
+
({ api, parameters }) => ({
|
|
115
|
+
apiName: api,
|
|
116
|
+
parameters,
|
|
117
|
+
})
|
|
118
|
+
),
|
|
119
|
+
},
|
|
219
120
|
};
|
|
220
121
|
}
|
|
@@ -6,42 +6,52 @@ import { getExecutionContext } from "@intuned/runtime";
|
|
|
6
6
|
import { app } from "./app";
|
|
7
7
|
import { RUN_ID_HEADER } from "./headers";
|
|
8
8
|
import { ShutdownController } from "./shutdown";
|
|
9
|
+
import { registerApiEndpoints } from "./api";
|
|
10
|
+
import { runJobsLoop } from "./jobs";
|
|
11
|
+
import { isJobRunMachine } from "./utils";
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
void main();
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
async function main() {
|
|
16
|
+
const port = process.env.PORT ? parseInt(process.env.PORT) : 4000;
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
initializeAppInsights();
|
|
19
|
+
|
|
20
|
+
app.use((req, res, next) => {
|
|
21
|
+
// Cleanup after the response is sent
|
|
22
|
+
res.on("finish", () => {
|
|
23
|
+
console.log("finished", req.headers[RUN_ID_HEADER]);
|
|
24
|
+
void ShutdownController.instance.checkForShutdown();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
next();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
registerApiEndpoints();
|
|
31
|
+
if (isJobRunMachine()) {
|
|
32
|
+
console.log("Running in job v3 mode");
|
|
33
|
+
void runJobsLoop();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const server = app.listen(port, () => {
|
|
37
|
+
// when deployed on flyio, the server will be turned on and
|
|
38
|
+
// will shutdown after the specified time in TIME_TO_SHUTDOWN env variable
|
|
39
|
+
ShutdownController.initialize(server);
|
|
18
40
|
void ShutdownController.instance.checkForShutdown();
|
|
41
|
+
console.log(`Server is running on port ${port}`);
|
|
19
42
|
});
|
|
20
43
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
process.on("unhandledRejection", (reason, promise) => {
|
|
36
|
-
const telemetryClient = getTelemetryClient();
|
|
37
|
-
console.error("Unhandled Rejection at:", promise, "reason:", reason);
|
|
38
|
-
const context = getExecutionContext();
|
|
39
|
-
telemetryClient?.trackEvent({
|
|
40
|
-
name: "UNHANDLED_REJECTION",
|
|
41
|
-
properties: {
|
|
42
|
-
runId: context?.runId,
|
|
43
|
-
promise,
|
|
44
|
-
reason,
|
|
45
|
-
},
|
|
44
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
45
|
+
const telemetryClient = getTelemetryClient();
|
|
46
|
+
console.error("Unhandled Rejection at:", promise, "reason:", reason);
|
|
47
|
+
const context = getExecutionContext();
|
|
48
|
+
telemetryClient?.trackEvent({
|
|
49
|
+
name: "UNHANDLED_REJECTION",
|
|
50
|
+
properties: {
|
|
51
|
+
runId: context?.runId,
|
|
52
|
+
promise,
|
|
53
|
+
reason,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
46
56
|
});
|
|
47
|
-
}
|
|
57
|
+
}
|
|
@@ -1,32 +1,14 @@
|
|
|
1
1
|
import { App } from "@tinyhttp/app";
|
|
2
2
|
import { json as parser } from "milliparsec";
|
|
3
3
|
import { accessKeyValidatorMiddleware } from "./accessKeyHelpers";
|
|
4
|
-
import { callFunction } from "./utils";
|
|
5
4
|
|
|
6
5
|
const port = process.env.PORT ? parseInt(process.env.PORT) : 4000;
|
|
7
6
|
const app = new App();
|
|
8
7
|
|
|
9
8
|
app.use("/", parser());
|
|
10
9
|
|
|
11
|
-
app.post("/api/run/*", async (req, res
|
|
12
|
-
|
|
13
|
-
const functionName = req.path.split("/").filter(Boolean).pop();
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
const body = req.body;
|
|
17
|
-
const result = await callFunction("api", functionName as string, [body]);
|
|
18
|
-
|
|
19
|
-
res.status(200).json(result);
|
|
20
|
-
} catch (error) {
|
|
21
|
-
if (
|
|
22
|
-
error.message ===
|
|
23
|
-
`Unknown variable dynamic import: ./api/${functionName}.ts`
|
|
24
|
-
) {
|
|
25
|
-
return res.status(404).json({});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
next(error);
|
|
29
|
-
}
|
|
10
|
+
app.post("/api/run/*", async (req, res) => {
|
|
11
|
+
return res.status(502).json({ message: "Not implemented" });
|
|
30
12
|
});
|
|
31
13
|
|
|
32
14
|
app.get("/api/health", async (req, res) => {
|
package/WebTemplate/jobs.ts
CHANGED
|
@@ -6,13 +6,7 @@ import {
|
|
|
6
6
|
RUN_ID_HEADER,
|
|
7
7
|
SHOULD_SHUTDOWN_HEADER,
|
|
8
8
|
} from "./headers";
|
|
9
|
-
import {
|
|
10
|
-
getErrorResponse,
|
|
11
|
-
isHeadless,
|
|
12
|
-
isJobRunMachine,
|
|
13
|
-
ProxyConfig,
|
|
14
|
-
proxyToUrl,
|
|
15
|
-
} from "./utils";
|
|
9
|
+
import { getErrorResponse, isHeadless, ProxyConfig, proxyToUrl } from "./utils";
|
|
16
10
|
import {
|
|
17
11
|
callBackendFunctionWithToken,
|
|
18
12
|
backendFunctionsTokenManager,
|
|
@@ -32,11 +26,6 @@ type JobPayload = {
|
|
|
32
26
|
traceSignedUrl?: string;
|
|
33
27
|
};
|
|
34
28
|
|
|
35
|
-
if (isJobRunMachine()) {
|
|
36
|
-
console.log("Running in job v3 mode");
|
|
37
|
-
void jobsV3();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
29
|
async function runApiInContext(
|
|
41
30
|
jobPayload: JobPayload
|
|
42
31
|
): Promise<Awaited<ReturnType<typeof runApi>>> {
|
|
@@ -83,7 +72,7 @@ async function runApiInContext(
|
|
|
83
72
|
}
|
|
84
73
|
}
|
|
85
74
|
|
|
86
|
-
async function
|
|
75
|
+
export async function runJobsLoop() {
|
|
87
76
|
await reportReady();
|
|
88
77
|
const initialDelay = 1000;
|
|
89
78
|
let delay = initialDelay;
|
package/WebTemplate/utils.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import * as playwright from "@intuned/playwright-core";
|
|
2
2
|
import { Handler, Response } from "@tinyhttp/app";
|
|
3
|
-
import { cleanEnvironmentVariables } from "@intuned/runtime/dist/common/cleanEnvironmentVariables";
|
|
4
|
-
import { AUTH_SESSIONS_FOLDER_NAME } from "@intuned/runtime/dist/common/constants";
|
|
5
|
-
import { Page, BrowserContext } from "@intuned/playwright-core";
|
|
6
3
|
import * as path from "path";
|
|
7
|
-
import { getExecutionContext } from "@intuned/runtime";
|
|
4
|
+
import { getExecutionContext } from "@intuned/runtime/dist/common/asyncLocalStorage";
|
|
8
5
|
import { setTimeout } from "timers/promises";
|
|
9
6
|
|
|
10
7
|
export class FunctionNotFoundError extends Error {
|
|
@@ -20,62 +17,6 @@ export class FunctionNotFoundError extends Error {
|
|
|
20
17
|
}
|
|
21
18
|
}
|
|
22
19
|
|
|
23
|
-
export async function callFunction(
|
|
24
|
-
folderName: string,
|
|
25
|
-
functionName: string,
|
|
26
|
-
args: any[]
|
|
27
|
-
) {
|
|
28
|
-
// cleanup environment variables before running the user code
|
|
29
|
-
cleanEnvironmentVariables();
|
|
30
|
-
|
|
31
|
-
const path = `./${folderName}/${functionName}.ts`;
|
|
32
|
-
|
|
33
|
-
const functionNameParts = functionName.split("/");
|
|
34
|
-
const functionNameDepth = functionNameParts.length;
|
|
35
|
-
|
|
36
|
-
// string literals should be inline
|
|
37
|
-
// currently we support only 5 levels of depth
|
|
38
|
-
// rollup dynamic import does not support multiple levels of dynamic imports so we need to specify the possible paths explicitly
|
|
39
|
-
try {
|
|
40
|
-
let imported: any = undefined;
|
|
41
|
-
switch (functionNameDepth) {
|
|
42
|
-
case 1:
|
|
43
|
-
imported = await import(`./${folderName}/${functionNameParts[0]}.ts`);
|
|
44
|
-
break;
|
|
45
|
-
case 2:
|
|
46
|
-
imported = await import(
|
|
47
|
-
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}.ts`
|
|
48
|
-
);
|
|
49
|
-
break;
|
|
50
|
-
case 3:
|
|
51
|
-
imported = await import(
|
|
52
|
-
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}.ts`
|
|
53
|
-
);
|
|
54
|
-
break;
|
|
55
|
-
case 4:
|
|
56
|
-
imported = await import(
|
|
57
|
-
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}.ts`
|
|
58
|
-
);
|
|
59
|
-
break;
|
|
60
|
-
case 5:
|
|
61
|
-
imported = await import(
|
|
62
|
-
`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}/${functionNameParts[4]}.ts`
|
|
63
|
-
);
|
|
64
|
-
break;
|
|
65
|
-
default:
|
|
66
|
-
throw new Error(
|
|
67
|
-
"intuned supports maximum 5 levels of depth in the api folder"
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
return await imported?.default(...args);
|
|
71
|
-
} catch (error: any) {
|
|
72
|
-
if (error.message.includes("Unknown variable dynamic import")) {
|
|
73
|
-
throw new FunctionNotFoundError(functionName, path);
|
|
74
|
-
}
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
20
|
export function getIsRetryableError(error: any) {
|
|
80
21
|
if (error?.message) {
|
|
81
22
|
return error.message.includes("ERR_NETWORK_CHANGED");
|
|
@@ -161,31 +102,6 @@ export function errorRetryMiddleware(handler: Handler) {
|
|
|
161
102
|
};
|
|
162
103
|
}
|
|
163
104
|
|
|
164
|
-
export async function checkAuthSessionWithRetries(
|
|
165
|
-
page: Page,
|
|
166
|
-
context: BrowserContext,
|
|
167
|
-
retries = 3
|
|
168
|
-
): Promise<boolean> {
|
|
169
|
-
if (retries === 0) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
let tryNumber = 0;
|
|
174
|
-
|
|
175
|
-
while (retries > tryNumber) {
|
|
176
|
-
const result: boolean = await callFunction(
|
|
177
|
-
AUTH_SESSIONS_FOLDER_NAME,
|
|
178
|
-
"check" as string,
|
|
179
|
-
[page, context]
|
|
180
|
-
);
|
|
181
|
-
if (result) return true;
|
|
182
|
-
|
|
183
|
-
tryNumber++;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
105
|
export function getTraceFilePath(runId: string, attemptNumber?: string) {
|
|
190
106
|
const fileName = `${runId}${attemptNumber ? `_${attemptNumber}` : ""}`;
|
|
191
107
|
return path.join(process.env.TRACES_DIRECTORY ?? "", `${fileName}.zip`);
|
package/WebTemplate.zip
ADDED
|
Binary file
|
package/api/authed.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Page, BrowserContext } from "@intuned/playwright-core";
|
|
2
|
+
|
|
3
|
+
export default async function authed(
|
|
4
|
+
params: any,
|
|
5
|
+
page: Page,
|
|
6
|
+
context: BrowserContext
|
|
7
|
+
) {
|
|
8
|
+
await page.goto("https://setcookie.net");
|
|
9
|
+
return {
|
|
10
|
+
cookies: await page.locator("ul li code").allInnerTexts(),
|
|
11
|
+
};
|
|
12
|
+
}
|
package/api/test.ts
ADDED
package/api/test2.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Page, BrowserContext } from "@intuned/playwright-core";
|
|
2
|
+
import { extendTimeout } from "../src/runtime/extendTimeout";
|
|
3
|
+
import { requestOTP } from "../src/runtime/requestMoreInfo";
|
|
4
|
+
|
|
5
|
+
export default async function* test2(
|
|
6
|
+
{ n }: { n?: number },
|
|
7
|
+
page: Page,
|
|
8
|
+
context: BrowserContext
|
|
9
|
+
) {
|
|
10
|
+
await page.goto("https://wikipedia.org/");
|
|
11
|
+
await page.waitForTimeout(1000);
|
|
12
|
+
|
|
13
|
+
yield requestOTP("Please enter the OTP");
|
|
14
|
+
|
|
15
|
+
const titles: string[] = [];
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < (n ?? 2); i++) {
|
|
18
|
+
await page.goto(`https://wikipedia.org/wiki/Special:Random`);
|
|
19
|
+
await page.waitForTimeout(1000);
|
|
20
|
+
titles.push(await page.locator("h1").innerText());
|
|
21
|
+
extendTimeout();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return { titles };
|
|
25
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Page, BrowserContext } from "@intuned/playwright-core";
|
|
2
|
+
|
|
3
|
+
export default async function check(
|
|
4
|
+
page: Page,
|
|
5
|
+
_context: BrowserContext
|
|
6
|
+
): Promise<boolean> {
|
|
7
|
+
await page.goto("https://setcookie.net");
|
|
8
|
+
return (await page.locator("ul li code").all()).length > 0;
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Page, BrowserContext } from "@intuned/playwright-core";
|
|
2
|
+
import {
|
|
3
|
+
requestOTP,
|
|
4
|
+
requestMultipleChoice,
|
|
5
|
+
} from "../src/runtime/requestMoreInfo";
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line require-yield
|
|
8
|
+
export default async function* create(
|
|
9
|
+
params: any,
|
|
10
|
+
page: Page,
|
|
11
|
+
context: BrowserContext
|
|
12
|
+
) {
|
|
13
|
+
await page.goto("https://setcookie.net/");
|
|
14
|
+
await page.locator("#name").fill("intuned");
|
|
15
|
+
await page.locator("#value").fill("password");
|
|
16
|
+
await page.locator("input[type=submit]").click();
|
|
17
|
+
|
|
18
|
+
console.log("Received", yield requestOTP("Enter useless otp"));
|
|
19
|
+
console.log(
|
|
20
|
+
"Received",
|
|
21
|
+
yield requestMultipleChoice("Choose the correct answer", [
|
|
22
|
+
"A",
|
|
23
|
+
"B",
|
|
24
|
+
"C",
|
|
25
|
+
"D",
|
|
26
|
+
])
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
await page.goto("http://www.sharonminsuk.com/code/storage-test.html");
|
|
30
|
+
await page.locator("#local").fill("intuned");
|
|
31
|
+
await page.locator("#local + input[type=button]").click();
|
|
32
|
+
}
|
package/authSessions
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"cookies":[{"name":"intuned","value":"password","domain":"setcookie.net","path":"/","expires":-1,"httpOnly":true,"secure":false,"sameSite":"Lax"}],"origins":[{"origin":"http://www.sharonminsuk.com","localStorage":[{"name":"theirValue","value":"intuned"}]}],"sessionStorage":[{"origin":"http://www.sharonminsuk.com","sessionStorage":[]}]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export declare function executeCLI(apiName: string, mode: "vanilla" | "playwright" | "playwright-standalone" | "playwright-headless", inputData: object | null | undefined, options: {
|
|
3
|
+
cdpAddress: string;
|
|
4
|
+
authSessionPath: undefined | string;
|
|
5
|
+
outputFileId: string | undefined;
|
|
6
|
+
}): Promise<void>;
|