@intuned/runtime-dev 0.0.1-split.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/.babelrc +21 -0
  2. package/.eslintignore +10 -0
  3. package/.eslintrc.js +39 -0
  4. package/.vite/deps_temp_01af7156/package.json +3 -0
  5. package/.vscode/extensions.json +3 -0
  6. package/.vscode/launch.json +102 -0
  7. package/.vscode/settings.json +12 -0
  8. package/WebTemplate/accessKeyHelpers.ts +28 -0
  9. package/WebTemplate/api.ts +139 -0
  10. package/WebTemplate/app.ts +18 -0
  11. package/WebTemplate/controllers/async.ts +138 -0
  12. package/WebTemplate/controllers/authSessions/check.ts +68 -0
  13. package/WebTemplate/controllers/authSessions/create.ts +128 -0
  14. package/WebTemplate/controllers/authSessions/index.ts +41 -0
  15. package/WebTemplate/controllers/authSessions/killOperation.ts +35 -0
  16. package/WebTemplate/controllers/authSessions/resumeOperation.ts +80 -0
  17. package/WebTemplate/controllers/authSessions/store.ts +14 -0
  18. package/WebTemplate/controllers/controllers.ts +73 -0
  19. package/WebTemplate/controllers/runApi/helpers.ts +220 -0
  20. package/WebTemplate/controllers/runApi/index.ts +68 -0
  21. package/WebTemplate/controllers/runApi/types.ts +13 -0
  22. package/WebTemplate/controllers/traces.ts +151 -0
  23. package/WebTemplate/features.ts +8 -0
  24. package/WebTemplate/headers.ts +6 -0
  25. package/WebTemplate/index.playwright.ts +47 -0
  26. package/WebTemplate/index.vanilla.ts +44 -0
  27. package/WebTemplate/jobs.ts +356 -0
  28. package/WebTemplate/shutdown.ts +64 -0
  29. package/WebTemplate/utils.ts +294 -0
  30. package/bin/intuned-api-run +2 -0
  31. package/bin/intuned-auth-session-check +2 -0
  32. package/bin/intuned-auth-session-create +2 -0
  33. package/bin/intuned-auth-session-load +2 -0
  34. package/bin/intuned-auth-session-refresh +2 -0
  35. package/bin/intuned-browser-save-state +2 -0
  36. package/bin/intuned-browser-start +2 -0
  37. package/bin/intuned-build +2 -0
  38. package/bin/intuned-ts-check +2 -0
  39. package/package.json +133 -0
  40. package/playwright.config.ts +48 -0
  41. package/src/commands/api/run.ts +225 -0
  42. package/src/commands/auth-sessions/load.ts +42 -0
  43. package/src/commands/auth-sessions/run-check.ts +70 -0
  44. package/src/commands/auth-sessions/run-create.ts +124 -0
  45. package/src/commands/browser/save-state.ts +22 -0
  46. package/src/commands/browser/start-browser.ts +17 -0
  47. package/src/commands/build.ts +125 -0
  48. package/src/commands/common/browserUtils.ts +80 -0
  49. package/src/commands/common/getDefaultExportFromFile.ts +13 -0
  50. package/src/commands/common/getFirstLineNumber.test.ts +274 -0
  51. package/src/commands/common/getFirstLineNumber.ts +146 -0
  52. package/src/commands/common/sendMessageToClient.ts +8 -0
  53. package/src/commands/common/utils/fileUtils.ts +25 -0
  54. package/src/commands/common/utils/settings.ts +23 -0
  55. package/src/commands/common/utils/webTemplate.ts +46 -0
  56. package/src/commands/testing/saveVisibleHtml.ts +29 -0
  57. package/src/commands/ts-check.ts +88 -0
  58. package/src/common/Logger/Logger/index.ts +64 -0
  59. package/src/common/Logger/Logger/types.ts +9 -0
  60. package/src/common/Logger/index.ts +64 -0
  61. package/src/common/Logger/types.ts +9 -0
  62. package/src/common/assets/browser_scripts.js +2214 -0
  63. package/src/common/asyncLocalStorage/index.ts +29 -0
  64. package/src/common/cleanEnvironmentVariables.ts +13 -0
  65. package/src/common/constants.ts +1 -0
  66. package/src/common/contextStorageStateHelpers.ts +71 -0
  67. package/src/common/getPlaywrightConstructs.ts +283 -0
  68. package/src/common/jwtTokenManager.ts +111 -0
  69. package/src/common/settingsSchema.ts +16 -0
  70. package/src/common/telemetry.ts +49 -0
  71. package/src/index.ts +14 -0
  72. package/src/runtime/RunError.ts +16 -0
  73. package/src/runtime/downloadDirectory.ts +14 -0
  74. package/src/runtime/enums.d.ts +11 -0
  75. package/src/runtime/enums.ts +11 -0
  76. package/src/runtime/executionHelpers.test.ts +70 -0
  77. package/src/runtime/export.d.ts +202 -0
  78. package/src/runtime/extendPayload.ts +22 -0
  79. package/src/runtime/extendTimeout.ts +32 -0
  80. package/src/runtime/index.ts +8 -0
  81. package/src/runtime/requestMoreInfo.ts +40 -0
  82. package/src/runtime/runInfo.ts +19 -0
  83. package/template.tsconfig.json +14 -0
  84. package/tsconfig.eslint.json +5 -0
  85. package/tsconfig.json +24 -0
  86. package/typedoc.json +49 -0
  87. package/vite.config.ts +17 -0
@@ -0,0 +1,29 @@
1
+ import { AsyncLocalStorage } from "async_hooks";
2
+ import { Payload, RunInfo } from "../../runtime/export";
3
+
4
+ export const asyncLocalStorage = new AsyncLocalStorage<InternalRunInfo>();
5
+
6
+ export function runWithContext<R, TArgs extends any[]>(
7
+ contextData: InternalRunInfo,
8
+ callback: (...args: TArgs) => R,
9
+ ...args: TArgs
10
+ ): R {
11
+ return asyncLocalStorage.run(contextData, callback, ...args);
12
+ }
13
+
14
+ interface TimeoutInfo {
15
+ extendTimeoutCallback?: () => Promise<void>;
16
+ timeoutDuration?: number;
17
+ timeoutTimestamp?: number;
18
+ }
19
+
20
+ interface InternalRunInfo extends RunInfo {
21
+ extendedPayloads: Payload[];
22
+ timeoutInfo?: TimeoutInfo;
23
+ }
24
+
25
+ export function getExecutionContext() {
26
+ const contextData = asyncLocalStorage.getStore();
27
+
28
+ return contextData as InternalRunInfo | undefined;
29
+ }
@@ -0,0 +1,13 @@
1
+ export function cleanEnvironmentVariables() {
2
+ Object.keys(process.env)
3
+ .filter((i) => {
4
+ if (i.toLocaleLowerCase().startsWith("npm")) {
5
+ return true;
6
+ }
7
+
8
+ if (i.toLocaleLowerCase().startsWith("fly") && i !== "FLY_ALLOC_ID") {
9
+ return true;
10
+ }
11
+ })
12
+ .forEach((i) => delete process.env[i]);
13
+ }
@@ -0,0 +1 @@
1
+ export const AUTH_SESSIONS_FOLDER_NAME = "auth-sessions";
@@ -0,0 +1,71 @@
1
+ import { BrowserContext } from "@intuned/playwright";
2
+ import * as playwright from "@intuned/playwright-core";
3
+
4
+ function sessionStorageToArray(
5
+ storage: Record<string, string>
6
+ ): { name: string; value: string }[] {
7
+ const result: { name: string; value: string }[] = [];
8
+
9
+ for (const key in storage) {
10
+ result.push({ name: key, value: storage[key] });
11
+ }
12
+
13
+ return result;
14
+ }
15
+
16
+ interface OriginSessionStorage {
17
+ origin: string;
18
+ sessionStorage: Array<{
19
+ name: string;
20
+ value: string;
21
+ }>;
22
+ }
23
+
24
+ export type IntunedStorageState = Exclude<
25
+ playwright.BrowserContextOptions["storageState"],
26
+ string
27
+ > & {
28
+ sessionStorage?: OriginSessionStorage[];
29
+ };
30
+
31
+ export async function getContextStorageState(
32
+ context: BrowserContext
33
+ ): Promise<IntunedStorageState> {
34
+ const cookiesAndLocalStorage = await context.storageState();
35
+ const pages = await context.pages();
36
+
37
+ const pagesSessions: OriginSessionStorage[] = [];
38
+ for (const page of pages) {
39
+ const [origin, session] = await page.evaluate(() => [
40
+ location.origin,
41
+ sessionStorage as Record<string, string>,
42
+ ]);
43
+
44
+ const transformed = sessionStorageToArray(session);
45
+
46
+ pagesSessions.push({ origin, sessionStorage: transformed });
47
+ }
48
+
49
+ return {
50
+ ...cookiesAndLocalStorage,
51
+ sessionStorage: pagesSessions,
52
+ };
53
+ }
54
+
55
+ export async function setContextStorageState(
56
+ context: BrowserContext,
57
+ storage: IntunedStorageState
58
+ ) {
59
+ await (context as any).intunedSetStorageState(storage);
60
+
61
+ const sessionStorage = storage.sessionStorage;
62
+
63
+ await context.addInitScript((storage) => {
64
+ for (const { origin, sessionStorage } of storage) {
65
+ if (window.location.origin === origin) {
66
+ for (const item of sessionStorage)
67
+ window.sessionStorage.setItem(item.name, item.value);
68
+ }
69
+ }
70
+ }, sessionStorage);
71
+ }
@@ -0,0 +1,283 @@
1
+ import * as playwright from "@intuned/playwright-core";
2
+ import { existsSync, mkdir, mkdtemp, rm, writeFile, readFile } from "fs-extra";
3
+ import {
4
+ IntunedStorageState,
5
+ setContextStorageState,
6
+ } from "./contextStorageStateHelpers";
7
+ import { join } from "path";
8
+ import path from "path";
9
+ import type { Browser, Page } from "@intuned/playwright-core";
10
+ import * as fs from "fs-extra";
11
+ import { getFullPathInProject } from "../commands/common/utils/fileUtils";
12
+ import waitOn from "wait-on";
13
+ import { getDownloadDirectoryPath } from "../runtime";
14
+
15
+ interface Proxy {
16
+ server: string;
17
+ username: string;
18
+ password: string;
19
+ }
20
+
21
+ interface GetPlaywrightConstructsOptions {
22
+ proxy?: Proxy;
23
+ headless?: boolean;
24
+ storageState?: IntunedStorageState;
25
+ downloadsPath: string;
26
+ userDataDir?: string;
27
+ }
28
+
29
+ async function createUserDirWithPreferences() {
30
+ const playwrightTempDir = await mkdtemp("/tmp/pw-");
31
+ const userDir = join(playwrightTempDir, "userdir");
32
+ const defaultDir = join(userDir, "Default");
33
+ await mkdir(defaultDir, {
34
+ recursive: true,
35
+ });
36
+ const preferences = {
37
+ plugins: {
38
+ always_open_pdf_externally: true,
39
+ },
40
+ };
41
+ await writeFile(join(defaultDir, "Preferences"), JSON.stringify(preferences));
42
+
43
+ return userDir;
44
+ }
45
+
46
+ export async function getProductionPlaywrightConstructs({
47
+ proxy,
48
+ headless = true,
49
+ storageState,
50
+ downloadsPath,
51
+ }: GetPlaywrightConstructsOptions): Promise<{
52
+ page: playwright.Page;
53
+ context: playwright.BrowserContext;
54
+ }> {
55
+ const extraArgs = [
56
+ "--no-first-run",
57
+ "--disable-sync",
58
+ "--disable-translate",
59
+ "--disable-features=TranslateUI",
60
+ "--disable-features=NetworkService",
61
+ "--lang=en",
62
+ ];
63
+
64
+ if (headless) {
65
+ extraArgs.push("--headless=new");
66
+ }
67
+
68
+ const executablePath = playwright.chromium.executablePath();
69
+ // use chromium 127 instead of 125, this depends on the docker image playwright version.
70
+ const chromium127Path = executablePath.replace(
71
+ "chromium-1117",
72
+ "chromium-1124"
73
+ );
74
+
75
+ const isChrome127There = existsSync(chromium127Path);
76
+
77
+ const userAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${
78
+ isChrome127There ? 127 : 125
79
+ }.0.0.0 Safari/537.36`;
80
+
81
+ const userDataDir = await createUserDirWithPreferences();
82
+
83
+ const context = await playwright.chromium.launchPersistentContext(
84
+ userDataDir,
85
+ {
86
+ headless,
87
+ ignoreDefaultArgs: [...getChromiumLaunchArgsToIgnore(), "--headless"],
88
+ proxy,
89
+ executablePath: isChrome127There ? chromium127Path : executablePath,
90
+ args: extraArgs,
91
+ downloadsPath,
92
+ userAgent,
93
+ }
94
+ );
95
+
96
+ context.once("close", async () => {
97
+ try {
98
+ await rm(userDataDir, {
99
+ recursive: true,
100
+ force: true,
101
+ retryDelay: 1000,
102
+ maxRetries: 5,
103
+ });
104
+ } catch (error) {
105
+ console.error("Failed to remove user data dir", error);
106
+ }
107
+ });
108
+
109
+ if (storageState) {
110
+ await setContextStorageState(context, storageState);
111
+ }
112
+
113
+ const assetsFile = path.join(__dirname, "./assets/browser_scripts.js");
114
+ await context.addInitScript({
115
+ path: assetsFile,
116
+ });
117
+
118
+ let page = context.pages().at(0);
119
+
120
+ if (page) {
121
+ const scriptString = await readFile(assetsFile, "utf8");
122
+ await page.evaluate(scriptString);
123
+ } else {
124
+ page = await context.newPage();
125
+ }
126
+
127
+ return {
128
+ page,
129
+ context,
130
+ };
131
+ }
132
+
133
+ const getChromiumLaunchArgsToIgnore = () => [
134
+ "--disable-field-trial-config",
135
+ "--disable-background-networking",
136
+ "--enable-features=NetworkService,NetworkServiceInProcess",
137
+ "--disable-background-timer-throttling",
138
+ "--disable-backgrounding-occluded-windows",
139
+ "--disable-back-forward-cache",
140
+ "--disable-breakpad",
141
+ "--disable-client-side-phishing-detection",
142
+ "--disable-component-extensions-with-background-pages",
143
+ "--disable-component-update",
144
+ "--no-default-browser-check",
145
+ "--disable-default-apps",
146
+ "--disable-dev-shm-usage",
147
+ "--disable-extensions",
148
+ "--disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate,TranslateUI",
149
+ "--allow-pre-commit-input",
150
+ "--disable-hang-monitor",
151
+ "--disable-ipc-flooding-protection",
152
+ "--disable-prompt-on-repost",
153
+ "--disable-renderer-backgrounding",
154
+ "--force-color-profile=srgb",
155
+ "--metrics-recording-only",
156
+ "--no-first-run",
157
+ "--enable-automation",
158
+ "--password-store=basic",
159
+ "--use-mock-keychain",
160
+ "--no-service-autorun",
161
+ "--export-tagged-pdf",
162
+ "--enable-use-zoom-for-dsf=false",
163
+ ];
164
+
165
+ export async function getPlaywrightConstructsForMode(
166
+ mode:
167
+ | "vanilla"
168
+ | "playwright"
169
+ | "playwright-standalone"
170
+ | "playwright-headless",
171
+ cdpAddress: string | undefined,
172
+ authSessionPath?: string
173
+ ): Promise<{
174
+ page: playwright.Page;
175
+ context: playwright.BrowserContext;
176
+ }> {
177
+ if (mode == "playwright-standalone") {
178
+ if (!cdpAddress) {
179
+ throw new Error("cdpAddress is required");
180
+ }
181
+
182
+ const { context } = await getRemotePlaywrightContext(cdpAddress);
183
+ if (!context) {
184
+ throw new Error("no context found");
185
+ }
186
+
187
+ const assetsFile = path.join(__dirname, "./assets/browser_scripts.js");
188
+ await context.addInitScript({
189
+ path: assetsFile,
190
+ });
191
+
192
+ const pages = await context.pages();
193
+ let page: Page | null = null;
194
+ if (pages.length > 0) {
195
+ page = pages[0];
196
+ const scriptString = await fs.readFile(assetsFile, "utf8");
197
+ await page.evaluate(scriptString);
198
+ } else {
199
+ page = await context.newPage();
200
+ }
201
+
202
+ if (authSessionPath) {
203
+ await loadAuthSessionToContext(context, authSessionPath);
204
+ }
205
+
206
+ return {
207
+ page,
208
+ context,
209
+ };
210
+ }
211
+
212
+ const downloadsPath = getDownloadDirectoryPath();
213
+ if (mode === "playwright" || mode === "playwright-headless") {
214
+ const productionConstructs = await getProductionPlaywrightConstructs({
215
+ headless: mode === "playwright-headless",
216
+ downloadsPath,
217
+ });
218
+
219
+ if (authSessionPath) {
220
+ await loadAuthSessionToContext(
221
+ productionConstructs.context,
222
+ authSessionPath
223
+ );
224
+ }
225
+
226
+ return {
227
+ ...productionConstructs,
228
+ };
229
+ }
230
+
231
+ throw "invalid mode";
232
+ }
233
+
234
+ export async function loadAuthSessionToContext(
235
+ context: playwright.BrowserContext,
236
+ authSessionPath: string
237
+ ) {
238
+ const fullPath = getFullPathInProject(authSessionPath);
239
+ const data = await fs.readJson(fullPath);
240
+
241
+ await setContextStorageState(context, data);
242
+ }
243
+
244
+ export async function getRemotePlaywrightContext(cdpAddress: string) {
245
+ const playwright = await import("@intuned/playwright-core");
246
+ let browser: Browser | null = null;
247
+
248
+ if (!cdpAddress) {
249
+ throw new Error("cdpAddress is required");
250
+ }
251
+
252
+ const cdpAddressWithoutProtocol = cdpAddress
253
+ .replace("http://", "")
254
+ .replace("https://", "")
255
+ .replace("localhost", "127.0.0.1");
256
+
257
+ try {
258
+ await waitOn({
259
+ resources: [`http-get://${cdpAddressWithoutProtocol}/json/version`],
260
+ delay: 100,
261
+ interval: 100,
262
+ timeout: 5000,
263
+ tcpTimeout: 1000,
264
+ window: 1000,
265
+ });
266
+ } catch (error) {
267
+ console.error("Failed to connect to the browser");
268
+ // 128 is the exit code for SIGINT https://tldp.org/LDP/abs/html/exitcodes.html
269
+ // 9 is the SIGKILL signal
270
+ process.exit(128 + 9);
271
+ }
272
+
273
+ try {
274
+ browser = await playwright.chromium.connectOverCDP(cdpAddress);
275
+ } catch (e) {
276
+ console.log(e);
277
+ throw new Error("failed to connect to the browser");
278
+ }
279
+
280
+ const context = browser.contexts()[0];
281
+
282
+ return { browser, context };
283
+ }
@@ -0,0 +1,111 @@
1
+ import fetch from "cross-fetch";
2
+ import * as jwt from "jsonwebtoken";
3
+ import { err, ResultAsync } from "neverthrow";
4
+
5
+ // Manages JWT token with renewal
6
+ class JwtTokenManager {
7
+ private _token: string | undefined;
8
+ private tokenRefreshTimeout: NodeJS.Timeout | undefined;
9
+ private refreshTokenPath: string;
10
+
11
+ constructor(refreshTokenPath: string) {
12
+ this.refreshTokenPath = refreshTokenPath;
13
+ this._token = undefined;
14
+ }
15
+
16
+ public get token() {
17
+ return this._token;
18
+ }
19
+
20
+ // When the token is set, the schedule for renewal is issued automatically
21
+ // This is currently being set it two places:
22
+ // 1. Whenever the runner starts, initializes it from the environment variable (set whenever the api is run from the authoring IDE)
23
+ // 2. Whenever a published api is called to run (/api/run/*), it is set to the token received in the run request.
24
+ public set token(newToken: string | undefined) {
25
+ if (this._token != newToken) {
26
+ this._token = newToken;
27
+ void this.scheduleTokenRefresh();
28
+ }
29
+ }
30
+
31
+ private get timeToRefresh() {
32
+ if (!this._token) return;
33
+
34
+ const payload = jwt.decode(this._token);
35
+
36
+ if (!payload || typeof payload == "string") return;
37
+
38
+ const expiry = payload.expiry;
39
+ if (!expiry || typeof expiry !== "number") return;
40
+
41
+ const timeWindow = 60 * 1000; // 1 minute
42
+
43
+ const timeToRefresh = expiry - Date.now() - timeWindow;
44
+ return Math.max(timeToRefresh, timeWindow);
45
+ }
46
+
47
+ private async scheduleTokenRefresh() {
48
+ if (process.env.RUN_ENVIRONMENT?.toLowerCase() !== "authoring") return;
49
+ const timeToRefresh = this.timeToRefresh;
50
+ if (timeToRefresh === undefined) return;
51
+
52
+ if (this.tokenRefreshTimeout) clearTimeout(this.tokenRefreshTimeout);
53
+
54
+ this.tokenRefreshTimeout = setTimeout(async () => {
55
+ const result = await this.refreshToken();
56
+ if (result && result.isErr()) {
57
+ console.error(`[Internal Error] ${result.error}`);
58
+ return;
59
+ }
60
+ await this.scheduleTokenRefresh();
61
+ }, timeToRefresh);
62
+ }
63
+
64
+ private async refreshToken() {
65
+ if (process.env.RUN_ENVIRONMENT?.toLowerCase() !== "authoring") return;
66
+ const res = await this.fetchWithToken(this.refreshTokenPath, {
67
+ method: "GET",
68
+ });
69
+
70
+ if (res.status === 401) {
71
+ return err("Unauthorized");
72
+ }
73
+
74
+ const jsonResult = await ResultAsync.fromPromise(
75
+ res.json(),
76
+ () => "not json"
77
+ );
78
+
79
+ if (jsonResult.isErr()) return;
80
+
81
+ const newToken = jsonResult.value.token;
82
+ if (newToken) this._token = newToken;
83
+ }
84
+
85
+ public fetchWithToken(...[input, init]: Parameters<typeof fetch>) {
86
+ const headers = new Headers(init?.headers);
87
+ headers.set("Authorization", `Bearer ${this.token}`);
88
+ return fetch(input, {
89
+ ...init,
90
+ headers,
91
+ });
92
+ }
93
+ }
94
+
95
+ const backendFunctionsPath = `${process.env.FUNCTIONS_DOMAIN}/api/${process.env.INTUNED_WORKSPACE_ID}/functions/${process.env.INTUNED_INTEGRATION_ID}`;
96
+
97
+ export const backendFunctionsTokenManager = new JwtTokenManager(
98
+ `${backendFunctionsPath}/refreshBackendFunctionsToken`
99
+ );
100
+ backendFunctionsTokenManager.token =
101
+ process.env.INTUNED_AUTHORING_SESSION_BACKEND_FUNCTIONS_TOKEN;
102
+
103
+ export function callBackendFunctionWithToken(
104
+ path: string,
105
+ init?: Parameters<typeof fetch>[1]
106
+ ) {
107
+ return backendFunctionsTokenManager.fetchWithToken(
108
+ `${backendFunctionsPath}/${path}`,
109
+ init
110
+ );
111
+ }
@@ -0,0 +1,16 @@
1
+ import * as z from "zod";
2
+
3
+ const authSessionsSchema = z
4
+ .object({
5
+ enabled: z.boolean(),
6
+ })
7
+ .optional()
8
+ .default({
9
+ enabled: false,
10
+ });
11
+
12
+ export const settingsSchema = z.object({
13
+ authSessions: authSessionsSchema,
14
+ });
15
+
16
+ export type IntunedSettings = z.infer<typeof settingsSchema>;
@@ -0,0 +1,49 @@
1
+ import * as appInsights from "applicationinsights";
2
+
3
+ function gracefulShutdown() {
4
+ console.log("Shutting down, so flushing app insights.");
5
+
6
+ appInsights.defaultClient.flush();
7
+
8
+ process.exit();
9
+ }
10
+
11
+ export function initializeAppInsights() {
12
+ const appInsightsConnectionString = process.env.APPINSIGHTS_CONNECTION_STRING;
13
+
14
+ if (appInsightsConnectionString) {
15
+ console.log("Initializing app insights.");
16
+
17
+ appInsights
18
+ .setup(appInsightsConnectionString)
19
+ .setAutoCollectConsole(true, true)
20
+ .setAutoCollectDependencies(true)
21
+ .setAutoCollectExceptions(true)
22
+ .setAutoCollectHeartbeat(true)
23
+ .setAutoCollectPerformance(true, true)
24
+ .setAutoCollectRequests(true)
25
+ .setAutoDependencyCorrelation(true)
26
+ .setDistributedTracingMode(appInsights.DistributedTracingModes.AI_AND_W3C)
27
+ .setSendLiveMetrics(true)
28
+ .setUseDiskRetryCaching(true);
29
+
30
+ appInsights.defaultClient.context.tags[
31
+ appInsights.defaultClient.context.keys.cloudRole
32
+ ] = "@intuned/sdk";
33
+
34
+ if (process.env.FLY_APP_NAME) {
35
+ appInsights.defaultClient.context.tags[
36
+ appInsights.defaultClient.context.keys.cloudRoleInstance
37
+ ] = process.env.FLY_APP_NAME;
38
+ }
39
+
40
+ process.on("SIGTERM", gracefulShutdown);
41
+ process.on("SIGINT", gracefulShutdown);
42
+
43
+ appInsights.start();
44
+ }
45
+ }
46
+
47
+ export function getTelemetryClient(): appInsights.TelemetryClient | undefined {
48
+ return appInsights.defaultClient;
49
+ }
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ export {
2
+ extendPayload,
3
+ extendTimeout,
4
+ runInfo,
5
+ RunError,
6
+ requestMultipleChoice,
7
+ requestOTP,
8
+ } from "./runtime";
9
+ export {
10
+ runWithContext,
11
+ getExecutionContext,
12
+ } from "./common/asyncLocalStorage";
13
+ export { getDownloadDirectoryPath } from "./runtime/downloadDirectory";
14
+ export { getProductionPlaywrightConstructs } from "./common/getPlaywrightConstructs";
@@ -0,0 +1,16 @@
1
+ import { RunErrorOptions } from "./export";
2
+
3
+ export class RunError extends Error {
4
+ options: RunErrorOptions;
5
+ constructor(message: string, options?: RunErrorOptions) {
6
+ super(message);
7
+ this.message = message;
8
+ this.name = "USER_GENERATED_ERROR";
9
+ this.options = options ?? {
10
+ retryable: false,
11
+ };
12
+ Object.setPrototypeOf(this, RunError.prototype);
13
+ }
14
+ }
15
+
16
+ new RunError("", {});
@@ -0,0 +1,14 @@
1
+ import { getExecutionContext } from "..";
2
+ import { ensureDirSync } from "fs-extra";
3
+
4
+ export function getDownloadDirectoryPath() {
5
+ const context = getExecutionContext();
6
+ if (!context) {
7
+ throw new Error("ExecutionContext not found");
8
+ }
9
+ const path = `/tmp/downloads/${context.runId}`;
10
+ ensureDirSync(path, {
11
+ mode: 0o2775,
12
+ });
13
+ return path;
14
+ }
@@ -0,0 +1,11 @@
1
+ export declare enum RunEnvironment {
2
+ IDE = "IDE",
3
+ DEPLOYED = "DEPLOYED",
4
+ }
5
+
6
+ export declare enum RunType {
7
+ SYNC = "SYNC",
8
+ ASYNC = "ASYNC",
9
+ JOB = "JOB",
10
+ QUEUE = "QUEUE",
11
+ }
@@ -0,0 +1,11 @@
1
+ export enum RunEnvironment {
2
+ IDE = "IDE",
3
+ DEPLOYED = "DEPLOYED",
4
+ }
5
+
6
+ export enum RunType {
7
+ SYNC = "SYNC",
8
+ ASYNC = "ASYNC",
9
+ JOB = "JOB",
10
+ QUEUE = "QUEUE",
11
+ }