@qawolf/ci-sdk 2.5.0 → 2.7.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/README.md +24 -5
- package/dist/index.cjs +15 -10
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +15 -10
- package/dist/index.js.map +2 -2
- package/dist/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-team-storage.d.ts +2 -0
- package/dist/lib/sdk/domain/generateSignedUrls/types.d.ts +4 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/logging.d.ts +3 -1
- package/dist/lib/sdk/domain/pollCiGreenlight/types.d.ts +12 -1
- package/dist/lib/sdk/index.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -304,6 +304,11 @@ The iterator yields a discriminated union that can be either a status update or
|
|
|
304
304
|
- `httpStatus`: HTTP status code if applicable, otherwise `undefined`
|
|
305
305
|
- `elapsedMs`: Milliseconds elapsed since polling started
|
|
306
306
|
|
|
307
|
+
When `abortReason` is `"run-canceled"`, the iteration also carries:
|
|
308
|
+
|
|
309
|
+
- `message`: Human-readable copy explaining the cancellation, or `undefined` when QA Wolf sent none
|
|
310
|
+
- `reason`: A stable code for the cancellation, or `undefined` when QA Wolf sent none. Treat this as an open set of strings, since new codes appear without an SDK release
|
|
311
|
+
|
|
307
312
|
**Important**: Always check `iteration.isAborted` to determine which type of result you received. When `isAborted === true`, you should handle the abort reason and exit appropriately.
|
|
308
313
|
|
|
309
314
|
<a id="notify-terminated-ephemeral-environment"></a>
|
|
@@ -368,9 +373,9 @@ const { generateSignedUrlForTempTeamStorage, attemptNotifyDeploy } =
|
|
|
368
373
|
});
|
|
369
374
|
|
|
370
375
|
(async () => {
|
|
371
|
-
const
|
|
376
|
+
const interactiveRunFileLocation = await uploadRunArtifact("");
|
|
372
377
|
|
|
373
|
-
if (
|
|
378
|
+
if (interactiveRunFileLocation) {
|
|
374
379
|
const deployConfig: DeployConfig = {
|
|
375
380
|
branch: undefined,
|
|
376
381
|
commitUrl: undefined,
|
|
@@ -380,7 +385,7 @@ const { generateSignedUrlForTempTeamStorage, attemptNotifyDeploy } =
|
|
|
380
385
|
hostingService: undefined,
|
|
381
386
|
sha: undefined,
|
|
382
387
|
variables: {
|
|
383
|
-
RUN_INPUT_PATH:
|
|
388
|
+
RUN_INPUT_PATH: interactiveRunFileLocation,
|
|
384
389
|
},
|
|
385
390
|
};
|
|
386
391
|
|
|
@@ -402,7 +407,7 @@ async function uploadRunArtifact(filePath: string): Promise<string> {
|
|
|
402
407
|
|
|
403
408
|
if (
|
|
404
409
|
signedUrlResponse?.success &&
|
|
405
|
-
signedUrlResponse.
|
|
410
|
+
signedUrlResponse.interactiveRunFileLocation &&
|
|
406
411
|
signedUrlResponse.uploadUrl
|
|
407
412
|
) {
|
|
408
413
|
const fileBuffer = await fs.readFile(filePath);
|
|
@@ -423,12 +428,16 @@ async function uploadRunArtifact(filePath: string): Promise<string> {
|
|
|
423
428
|
} catch (error) {
|
|
424
429
|
return "";
|
|
425
430
|
}
|
|
426
|
-
return signedUrlResponse.
|
|
431
|
+
return signedUrlResponse.interactiveRunFileLocation;
|
|
427
432
|
}
|
|
428
433
|
return "";
|
|
429
434
|
}
|
|
430
435
|
```
|
|
431
436
|
|
|
437
|
+
`generateSignedUrlForTempTeamStorage` and `generateSignedUrlForRunInputsExecutablesStorage` also return a
|
|
438
|
+
`playgroundFileLocation` field with the same value as `interactiveRunFileLocation`. It is deprecated and
|
|
439
|
+
will be removed in a future major version — use `interactiveRunFileLocation` instead.
|
|
440
|
+
|
|
432
441
|
<a name="requirements"></a>
|
|
433
442
|
|
|
434
443
|
## Requirements
|
|
@@ -469,6 +478,16 @@ This package follows the [SemVer](https://semver.org/) versioning scheme. Additi
|
|
|
469
478
|
|
|
470
479
|
# Changelog
|
|
471
480
|
|
|
481
|
+
## v2.7.0
|
|
482
|
+
|
|
483
|
+
- `generateSignedUrlForTempTeamStorage` and `generateSignedUrlForRunInputsExecutablesStorage`: the response now also includes `interactiveRunFileLocation`, carrying the same value as `playgroundFileLocation`. `playgroundFileLocation` is deprecated and will be removed in a future major version; switch to `interactiveRunFileLocation` now, since both fields are populated identically until then.
|
|
484
|
+
|
|
485
|
+
## v2.6.0
|
|
486
|
+
|
|
487
|
+
- `pollCiGreenlightStatus`: when QA Wolf explains why a run was canceled, the SDK now prints that explanation instead of asking you to contact support. Previously the `message` on a `canceled` status was readable only through `onRunStageChanged` or the iterator, so a default caller saw the run stop with no cause. A backend that sends no `message`, and cancellations that carry none, keep the previous copy. `makePollCiGreenlightStatusIterator` now carries `message` and `reason` on the `run-canceled` abort as well. `reason` is an open set of string codes; new ones appear without an SDK release.
|
|
488
|
+
- `makePollCiGreenlightStatusIterator`: a `run-canceled` abort now carries optional `message` and `reason` fields, holding whatever QA Wolf sent on the canceled status. Both are added to the existing `PollCiGreenlightIteratorNonHttpAborted`, so no existing type or declaration changes. Both are `undefined` on a `poll-timed-out` or `network-error` abort, which never carry an explanation, and against a backend that predates the fields.
|
|
489
|
+
- `pollCiGreenlightStatus`: QA Wolf now gives up on a run it never managed to create, so a poll that used to continue until your own timeout ends within about five minutes. The run reaches the `canceled` stage with `reason: "run-not-created"` and an explanation, which the SDK now prints for you as described above, and the top-level result is `outcome: "aborted"` with `abortReason: "run-canceled"`, exactly as for any other cancellation. Treat `reason` as an open set, as before. Nothing changes for a run that is created normally, and a backend that predates this keeps reporting the run as `initializing`.
|
|
490
|
+
|
|
472
491
|
## v2.5.0
|
|
473
492
|
|
|
474
493
|
- `attemptNotifyDeploy`: QA Wolf no longer sends `skipped_triggers` on the `deploy_success` response, so against a current backend `skippedTriggers` is absent and `failReason: "trigger-skipped"` does not occur. A trigger that matched the deployment but could not run now reaches you as `outcome: "skipped"` rather than `outcome: "failed"`, so a deploy step that used to fail in that case passes instead. This most often happens when the environment has no enabled tests, where there is nothing to run and nothing to retry. Both `skippedTriggers` and the `trigger-skipped` reason stay in the types and are still parsed, so no caller has to change and a self-hosted backend that predates the change keeps working. Note that this response no longer distinguishes a matched-but-unrunnable trigger from a deployment that matched nothing, and its log line reads as though nothing matched.
|
package/dist/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ var defaultServiceBase = "https://app.qawolf.com/";
|
|
|
62
62
|
// package.json
|
|
63
63
|
var package_default = {
|
|
64
64
|
name: "@qawolf/ci-sdk",
|
|
65
|
-
version: "2.
|
|
65
|
+
version: "2.7.0",
|
|
66
66
|
private: false,
|
|
67
67
|
description: "A simple SDK for interacting with QAWolf in CI scripts.",
|
|
68
68
|
keywords: [],
|
|
@@ -483,6 +483,7 @@ async function callGenerateSignedUrlForRunInputsExecutablesStorage({ apiKey, ser
|
|
|
483
483
|
return {
|
|
484
484
|
fileLocation: json.fileLocation,
|
|
485
485
|
httpStatus: response.status,
|
|
486
|
+
interactiveRunFileLocation: json.interactiveRunFileLocation,
|
|
486
487
|
playgroundFileLocation: json.playgroundFileLocation,
|
|
487
488
|
signedUrl: json.signedUrl,
|
|
488
489
|
success: true
|
|
@@ -550,6 +551,7 @@ async function generateSignedUrlForRunInputsExecutablesStorage(deps, apiConfig,
|
|
|
550
551
|
log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);
|
|
551
552
|
return {
|
|
552
553
|
fileLocation: responseState.fileLocation,
|
|
554
|
+
interactiveRunFileLocation: responseState.interactiveRunFileLocation,
|
|
553
555
|
playgroundFileLocation: responseState.playgroundFileLocation,
|
|
554
556
|
success: true,
|
|
555
557
|
uploadUrl: responseState.signedUrl
|
|
@@ -581,6 +583,7 @@ async function callGenerateSignedUrlForTempTeamStorage({ apiKey, serviceBase, us
|
|
|
581
583
|
return {
|
|
582
584
|
fileLocation: json.fileLocation,
|
|
583
585
|
httpStatus: response.status,
|
|
586
|
+
interactiveRunFileLocation: json.interactiveRunFileLocation,
|
|
584
587
|
playgroundFileLocation: json.playgroundFileLocation,
|
|
585
588
|
signedUrl: json.signedUrl,
|
|
586
589
|
success: true
|
|
@@ -648,6 +651,7 @@ async function generateSignedUrlForTempTeamStorage(deps, apiConfig, config) {
|
|
|
648
651
|
log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);
|
|
649
652
|
return {
|
|
650
653
|
fileLocation: responseState.fileLocation,
|
|
654
|
+
interactiveRunFileLocation: responseState.interactiveRunFileLocation,
|
|
651
655
|
playgroundFileLocation: responseState.playgroundFileLocation,
|
|
652
656
|
success: true,
|
|
653
657
|
uploadUrl: responseState.signedUrl
|
|
@@ -880,7 +884,9 @@ async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...
|
|
|
880
884
|
abortReason: "run-canceled",
|
|
881
885
|
elapsedMs,
|
|
882
886
|
httpStatus: void 0,
|
|
883
|
-
isAborted: true
|
|
887
|
+
isAborted: true,
|
|
888
|
+
message: greenlightStatus.message,
|
|
889
|
+
reason: greenlightStatus.reason
|
|
884
890
|
};
|
|
885
891
|
return;
|
|
886
892
|
}
|
|
@@ -958,20 +964,17 @@ function buildSupersededContinueLogMessage(rootRunUrl, relevantRunUrl) {
|
|
|
958
964
|
return `Root run was superseded:${supersedingDetails}`;
|
|
959
965
|
}
|
|
960
966
|
__name(buildSupersededContinueLogMessage, "buildSupersededContinueLogMessage");
|
|
961
|
-
function buildRunStageLogMessage(
|
|
967
|
+
function buildRunStageLogMessage(status) {
|
|
968
|
+
const { relevantRunUrl, runStage } = status;
|
|
962
969
|
const urlInfo = `See ${relevantRunUrl}`;
|
|
963
970
|
switch (runStage) {
|
|
964
971
|
case "canceled":
|
|
965
|
-
return `\u{1F6AB} Run was canceled. Aborting... Please contact support.
|
|
972
|
+
return `\u{1F6AB} Run was canceled. ${status.message || "Aborting... Please contact support."}
|
|
966
973
|
${urlInfo}`;
|
|
967
974
|
case "initializing":
|
|
968
975
|
return `\u23F3 Run is in progress... ${urlInfo}`;
|
|
969
976
|
case "underReview":
|
|
970
977
|
return `\u{1F575}\uFE0F Run is under review... ${urlInfo}`;
|
|
971
|
-
case "completed":
|
|
972
|
-
throw Error(
|
|
973
|
-
"buildRunStageLogMessage should not be called for completed stage"
|
|
974
|
-
);
|
|
975
978
|
default:
|
|
976
979
|
throw Error(`Unexpected run stage: ${runStage}`);
|
|
977
980
|
}
|
|
@@ -1025,7 +1028,9 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
1025
1028
|
outcome: "aborted"
|
|
1026
1029
|
};
|
|
1027
1030
|
case "run-canceled":
|
|
1028
|
-
log.info(
|
|
1031
|
+
log.info(
|
|
1032
|
+
iteration.message ? `Run was canceled. ${iteration.message}` : `Run was canceled`
|
|
1033
|
+
);
|
|
1029
1034
|
return {
|
|
1030
1035
|
abortReason,
|
|
1031
1036
|
httpStatus: void 0,
|
|
@@ -1098,7 +1103,7 @@ async function pollCiGreenlightStatus(deps, apiConfig, {
|
|
|
1098
1103
|
case "canceled":
|
|
1099
1104
|
case "initializing":
|
|
1100
1105
|
case "underReview": {
|
|
1101
|
-
log.info(buildRunStageLogMessage(
|
|
1106
|
+
log.info(buildRunStageLogMessage(status));
|
|
1102
1107
|
break;
|
|
1103
1108
|
}
|
|
1104
1109
|
case "completed": {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/lib/other.ts", "../src/lib/sdk/defaults/fetch.ts", "../src/lib/sdk/defaults/log.ts", "../src/lib/sdk/defaults/serviceBase.ts", "../package.json", "../src/lib/sdk/defaults/userAgent.ts", "../src/lib/api/log.ts", "../src/lib/sdk/domain/attemptDeploy/handleSuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/mapDeploySuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/parseDeploySuccessWireResponse.ts", "../src/lib/sdk/domain/attemptDeploy/index.ts", "../src/lib/api/signed-url.ts", "../src/lib/api/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/api/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/notifyTerminatedEphemeralEnvironment/index.ts", "../src/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.ts", "../src/lib/sdk/domain/pollCiGreenlight/consts.ts", "../src/lib/api/ci-greenlight.ts", "../src/lib/sdk/domain/pollCiGreenlight/iterator.ts", "../src/lib/sdk/domain/pollCiGreenlight/logging.ts", "../src/lib/sdk/domain/pollCiGreenlight/mapIteratorAbortToGreenlightStatus.ts", "../src/lib/sdk/domain/pollCiGreenlight/index.ts", "../src/lib/sdk/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type {\n CiGreenlightStatus,\n CiGreenlightStatusBase,\n} from \"./lib/api/index.js\";\nexport * from \"./lib/sdk/dependencies.js\";\nexport * from \"./lib/sdk/domain/attemptDeploy/types.js\";\nexport * from \"./lib/sdk/index.js\";\n", "import type { FetchDriver } from \"./sdk/dependencies.js\";\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function pluralize(count: number) {\n return count === 1 ? \"\" : \"s\";\n}\n\nexport function getBackoffMs(\n attemptNumber: number,\n minWaitMs = 1000,\n maxWaitMs = 10000,\n): number {\n return Math.min(maxWaitMs, minWaitMs * 1.2 ** attemptNumber);\n}\n\nexport const buildFetchWithTimeout =\n (fetch: FetchDriver, defaultTimeoutMs: number) =>\n async (...args: Parameters<FetchDriver>) => {\n // Allow signal to be overridden by the caller\n const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);\n\n return fetch(args[0], { ...args[1], signal });\n };\n", "export const defaultFetch = globalThis.fetch;\n", "import type { LogDriver } from \"../dependencies.js\";\n\nexport const defaultLogDriver: LogDriver = {\n error(message, error) {\n console.error(message, error);\n },\n info(message) {\n console.log(message);\n },\n warn(message) {\n console.warn(message);\n },\n};\n", "export const defaultServiceBase = \"https://app.qawolf.com/\";\n", "{\n \"name\": \"@qawolf/ci-sdk\",\n \"version\": \"2.5.0\",\n \"private\": false,\n \"description\": \"A simple SDK for interacting with QAWolf in CI scripts.\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"author\": \"Jules Sam. Randolph<jules@qawolf.com>\",\n \"files\": [\n \"/dist\",\n \"/README.md\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"platform-builder --config platformBuilder.config.ts --config platformBuilder.cjs.config.ts\",\n \"lint:ci\": \"npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT\",\n \"lint:dev\": \"npm run lint:first-half\",\n \"lint:first-half\": \"eslint . --fix --quiet && oxfmt --write .\",\n \"lint:second-half\": \"dpdm --exit-code circular:1 --no-tree --no-warning --transform --include='.*' --exclude='/(dist|node_modules)/' '**/*'\",\n \"prepublishOnly\": \"nx run ci-sdk:build\",\n \"test\": \"NODE_OPTIONS=\\\"--experimental-vm-modules\\\" NODE_NO_WARNINGS=1 jest\",\n \"tsc:check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@qawolf/ci-utils\": \"^1.1.2\",\n \"@sinonjs/fake-timers\": \"^10.3.0\",\n \"tslib\": \"^2.6.2\"\n },\n \"devDependencies\": {\n \"@qawolf/platform-builder\": \"^1.2.2\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=20\"\n }\n}\n", "import packageJson from \"../../../../package.json\" with { type: \"json\" };\n\nexport const defaultUserAgent = `ci-sdk/${packageJson.version}`;\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nexport async function logFetchError({\n log,\n methodName,\n response,\n}: {\n log: LogDriver;\n methodName: string;\n response: Response;\n}) {\n if (response.ok) return;\n\n const { eventId, failureMessage } = await (async () => {\n try {\n const body = (await response.json().catch(() => response.text())) as\n | Record<string, unknown>\n | string;\n if (typeof body === \"object\" && body !== null) {\n return {\n eventId: body.eventId,\n failureMessage: body.failureMessage,\n };\n }\n // If body is not an object (i.e., it's the text from catch)\n return {\n eventId: undefined,\n failureMessage: body,\n };\n } catch {\n // If both parsing attempts somehow fail\n return {\n eventId: undefined,\n failureMessage: undefined,\n };\n }\n })();\n\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = failureMessage ? `: ${failureMessage}` : \"\";\n\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n\n log.error(\n `\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n}\n", "import type { LogDriver } from \"../../dependencies.js\";\n\nimport type { DeployStatus, NotifyDeployStatus } from \"./types.js\";\n\nexport async function handleSuccessResponse(\n data: DeployStatus,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const { environment, results } = data;\n const skippedTriggers = data.skippedTriggers ?? [];\n const skippedDeployment = data.skippedDeployment;\n const isPreviewDeployment = environment && !environment.isStatic;\n\n if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);\n\n if (environment) {\n const logPrefix = environment.isStatic\n ? \"Static environment\"\n : \"Preview environment\";\n log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);\n }\n\n // No suites were created for this deployment.\n if (results.length === 0) {\n const skipMessages = [\n ...skippedTriggers.map((trigger) => trigger.message),\n ...(skippedDeployment ? [skippedDeployment.message] : []),\n ];\n const skipDetail =\n skipMessages.length > 0 ? ` ${skipMessages.join(\" \")}` : \"\";\n\n // Preview deployments legitimately often produce no run; keep the success\n // outcome but surface any skip reason so it is not silently dropped.\n if (isPreviewDeployment) {\n log.info(\n `\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: undefined,\n };\n }\n\n // A trigger matched but could not run (e.g. environment still syncing).\n // Only a backend that still sends skipped_triggers reaches this arm. Current\n // backends omit the field, so those responses bypass it and fall to the\n // generic \"no trigger matched\" warning below even when a trigger did match.\n if (skippedTriggers.length > 0) {\n log.error(`\uD83D\uDEAB No run was created for this deployment.${skipDetail}`);\n return {\n failReason: \"trigger-skipped\",\n outcome: \"failed\",\n skippedTriggers,\n };\n }\n\n log.warn(\n skippedDeployment\n ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}`\n : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`,\n );\n return {\n outcome: \"skipped\",\n skippedDeployment,\n };\n }\n\n // If there are results, environment must be defined\n if (!environment) {\n log.error(`\uD83D\uDEAB No environment matched the request. Please contact support.`);\n return { failReason: \"no-environment\", outcome: \"failed\" };\n }\n\n // A result arm this SDK version does not recognize (newer backend). We cannot\n // classify the outcome, so surface it as a failure rather than guessing.\n const unrecognizedResult = results.find((result) => \"unrecognized\" in result);\n if (unrecognizedResult) {\n log.error(\n `\uD83D\uDEAB The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`,\n );\n return { failReason: \"unknown-result\", outcome: \"failed\" };\n }\n\n const failedTrigger = results.find((result) => \"failureReason\" in result);\n if (failedTrigger) {\n // Prefer the customer-facing message; older backends send only the internal\n // reason, which is all we can show in that case.\n log.error(\n `\uD83D\uDEAB Run could not be created. Reason: \"${failedTrigger.failureMessage ?? failedTrigger.failureReason}\". Please contact support.`,\n );\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n\n const duplicateSuite = results.find((result) => \"duplicateSuiteId\" in result);\n if (duplicateSuite) {\n log.info(\n `\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: duplicateSuite.duplicateSuiteId,\n };\n }\n\n const successfulTrigger = results.find(\n (result) => \"createdSuiteId\" in result,\n );\n if (!successfulTrigger) {\n // results is non-empty here, so triggers did match \u2014 this is not the\n // deterministic no-trigger-match skip. Reaching this point means the\n // response carried results we could not turn into a run, so it is an\n // unexpected failure rather than a skip.\n log.error(`\uD83D\uDEAB Run could not be created. Please contact support.`);\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n log.info(\n `\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: successfulTrigger.createdSuiteId,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\nimport type { DeployStatus, DeploySuccessSuiteResult } from \"./types.js\";\n\n// An arm is classified by the outcome the backend declared, not by which keys\n// happen to be present.\nfunction mapSuiteResult(\n result: DeploySuccessWireResponse[\"results\"][number],\n): DeploySuccessSuiteResult {\n switch (result.outcome) {\n case \"created\":\n return {\n createdSuiteId: result.created_suite_id,\n triggerId: result.trigger_id,\n };\n case \"failed\":\n return {\n failureCode: result.failure_code,\n failureMessage: result.failure_message,\n failureReason: result.failure_reason,\n triggerId: result.trigger_id,\n };\n case \"skipped\":\n return {\n duplicateSuiteId: result.duplicate_suite_id,\n skipReason: result.skip_reason,\n triggerId: result.trigger_id,\n };\n default:\n // An outcome added by a newer backend: surface it explicitly rather than\n // forcing it into one of the known shapes.\n return { triggerId: result.trigger_id, unrecognized: true };\n }\n}\n\n// The deploy_success success body is the SDK's only snake_case wire shape; this\n// is the single place that renames it to the camelCase `DeployStatus` used\n// everywhere downstream.\nexport function mapDeploySuccessResponse(\n wire: DeploySuccessWireResponse,\n): DeployStatus {\n return {\n environment: wire.environment,\n results: wire.results.map(mapSuiteResult),\n skippedDeployment: wire.skipped_deployment && {\n message: wire.skipped_deployment.message,\n reason: wire.skipped_deployment.reason,\n },\n skippedTriggers: wire.skipped_triggers?.map((trigger) => ({\n environmentId: trigger.environment_id,\n message: trigger.message,\n reason: trigger.reason,\n triggerId: trigger.trigger_id,\n })),\n warning: wire.warning,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n // Arrays are objects too; a deploy_success body or any of its parts must be a\n // plain object, never an array. (JSON cannot produce other non-plain objects\n // such as Date or Map, so excluding arrays is sufficient here.)\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === \"string\";\n}\n\n// Validates each arm against the `outcome` the backend declared, matching how\n// mapSuiteResult discriminates. Keying both off the same field is what keeps an\n// outcome-based mapper from reading a missing payload field as undefined. It\n// also tightens `{ outcome: \"failed\" }` with no `failure_reason`: key-presence\n// classified that as unrecognized, and it is now an invalid body.\nfunction isWireSuiteResult(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.trigger_id !== \"string\") return false;\n if (!isOptionalString(value.outcome)) return false;\n switch (value.outcome) {\n case \"created\":\n return typeof value.created_suite_id === \"string\";\n case \"failed\":\n return (\n typeof value.failure_reason === \"string\" &&\n isOptionalString(value.failure_code) &&\n isOptionalString(value.failure_message)\n );\n case \"skipped\":\n return (\n typeof value.duplicate_suite_id === \"string\" &&\n typeof value.skip_reason === \"string\"\n );\n default:\n // An outcome this SDK version does not know, or none at all. Accept it so\n // an older SDK does not reject the whole response; mapSuiteResult maps it\n // to an explicit unrecognized outcome.\n return true;\n }\n}\n\nfunction isEnvironment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.isStatic !== \"boolean\") return false;\n if (value.alias !== undefined && typeof value.alias !== \"string\")\n return false;\n return true;\n}\n\nfunction isSkippedDeployment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return typeof value.message === \"string\" && typeof value.reason === \"string\";\n}\n\nfunction isSkippedTrigger(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return (\n typeof value.environment_id === \"string\" &&\n typeof value.message === \"string\" &&\n typeof value.reason === \"string\" &&\n typeof value.trigger_id === \"string\"\n );\n}\n\nfunction isDeploySuccessWireResponse(\n value: unknown,\n): value is DeploySuccessWireResponse {\n if (!isRecord(value)) return false;\n if (value.environment !== undefined && !isEnvironment(value.environment))\n return false;\n\n if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))\n return false;\n\n if (\n value.skipped_deployment !== undefined &&\n !isSkippedDeployment(value.skipped_deployment)\n )\n return false;\n\n if (\n value.skipped_triggers !== undefined &&\n (!Array.isArray(value.skipped_triggers) ||\n !value.skipped_triggers.every(isSkippedTrigger))\n )\n return false;\n\n if (!isOptionalString(value.warning)) return false;\n\n return true;\n}\n\n// Validate the deploy_success success body at runtime instead of trusting a\n// cast. `environment` is required to be present-or-explicitly-undefined; the\n// two skip fields are optional (older servers omit them).\nexport function parseDeploySuccessWireResponse(\n value: unknown,\n): DeploySuccessWireResponse | \"invalid\" {\n return isDeploySuccessWireResponse(value) ? value : \"invalid\";\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport { handleSuccessResponse } from \"./handleSuccessResponse.js\";\nimport { mapDeploySuccessResponse } from \"./mapDeploySuccessResponse.js\";\nimport { parseDeploySuccessWireResponse } from \"./parseDeploySuccessWireResponse.js\";\nimport type {\n AttemptDeployHttpAbortReason,\n DeployConfig,\n NotifyDeployStatus,\n} from \"./types.js\";\n\nexport async function attemptNotifyDeploy(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: Partial<DeployConfig>,\n): Promise<NotifyDeployStatus> {\n const { fetch: localFetch, log } = deps;\n\n let response: Response;\n let bodyText: string;\n try {\n response = await localFetch(\n new URL(\"/api/webhooks/deploy_success\", apiConfig.serviceBase),\n {\n body: JSON.stringify({\n branch: config.branch,\n commit_url: config.commitUrl,\n deduplication_key: config.deduplicationKey,\n deployment_type: config.deploymentType,\n deployment_url: config.deploymentUrl,\n ...(\"ephemeralEnvironment\" in config\n ? {\n ephemeral_environment: config.ephemeralEnvironment,\n }\n : \"hostingService\" in config && {\n hosting_service: config.hostingService,\n merge_request_number:\n config.hostingService === \"GitLab\"\n ? config.mergeRequestNumber\n : undefined,\n pull_request_number:\n config.hostingService === \"GitHub\"\n ? config.pullRequestNumber\n : undefined,\n repository: config.repository,\n }),\n sha: config.sha,\n variables: config.variables,\n workspaceId: config.workspaceId,\n }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n // Override default timeout to 5 minutes. This gives extra room\n // for both (1) waiting for reconciliation (2) creating the run.\n signal: AbortSignal.timeout(5 * 60 * 1000),\n },\n );\n\n if (!response.ok) return handleErrorResponse(response, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from deploy_success, aborting.`);\n return {\n abortReason: \"network-error\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n\n let rawBody: unknown;\n try {\n rawBody = JSON.parse(bodyText);\n } catch {\n return abortInvalidResponseBody(log, \"the response body was not JSON\");\n }\n\n const wire = parseDeploySuccessWireResponse(rawBody);\n if (wire === \"invalid\") {\n return abortInvalidResponseBody(\n log,\n \"the response body did not match the expected shape\",\n );\n }\n\n const data = mapDeploySuccessResponse(wire);\n return handleSuccessResponse(data, log);\n}\n\nfunction abortInvalidResponseBody(\n log: LogDriver,\n detail: string,\n): NotifyDeployStatus {\n log.error(`\uD83D\uDEAB Invalid response from deploy_success (${detail}), aborting.`);\n return {\n abortReason: \"invalid-response-body\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n}\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const status = response.status;\n let abortReason: AttemptDeployHttpAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"attemptNotifyDeploy\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "const signedUrlPaths = {\n runInputsExecutables: \"/api/v0/run-inputs-executables-signed-urls\",\n teamStorage: \"/api/v0/team-storage-signed-url\",\n} as const;\n\nexport function buildSignedUrl({\n destinationFilePath,\n endpoint,\n serviceBase,\n workspaceId,\n}: {\n destinationFilePath: string | undefined;\n endpoint: keyof typeof signedUrlPaths;\n serviceBase: string;\n workspaceId: string | undefined;\n}): URL {\n const url = new URL(signedUrlPaths[endpoint], serviceBase);\n if (destinationFilePath !== undefined)\n url.searchParams.set(\"file\", destinationFilePath);\n if (workspaceId !== undefined)\n url.searchParams.set(\"workspaceId\", workspaceId);\n return url;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForRunInputsExecutablesStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: GenerateSignedUrlConfig,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"runInputsExecutables\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForRunInputsExecutablesStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForRunInputsExecutablesStorage } from \"../../../api/generate-signed-url-for-run-inputs-executables.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n GenerateSignedUrlAbortReason,\n GenerateSignedUrlConfig,\n GenerateSignedUrlStatus,\n} from \"./types.js\";\n\nexport async function generateSignedUrlForRunInputsExecutablesStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState =\n await callGenerateSignedUrlForRunInputsExecutablesStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForTempTeamStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: Partial<GenerateSignedUrlConfig>,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"teamStorage\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForTempTeamStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForTempTeamStorage } from \"../../../api/generate-signed-url-for-team-storage.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type { GenerateSignedUrlConfig } from \"./types.js\";\n\ntype GenerateSignedUrlStatus =\n | {\n fileLocation?: string;\n playgroundFileLocation?: string;\n success: true;\n uploadUrl?: string;\n }\n | {\n abortReason: GenerateSignedUrlAbortReason;\n httpStatus?: number;\n success: false;\n };\n\nexport type GenerateSignedUrlAbortReason =\n | \"client-network-error\"\n | \"sdk-argument-validation-failed\"\n | \"400-invalid-request\"\n | \"401-invalid-credentials\"\n | \"403-forbidden\"\n | \"5XX-server-error\"\n | \"XXX-other-http-code\";\n\nexport async function generateSignedUrlForTempTeamStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState = await callGenerateSignedUrlForTempTeamStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n NotifyTerminatedEphemeralEnvironmentAbortReason,\n NotifyTerminatedEphemeralEnvironmentInput,\n NotifyTerminatedEphemeralEnvironmentResult,\n TerminatedEphemeralEnvironmentSuccessResult,\n} from \"./types.js\";\n\nexport const notifyTerminatedEphemeralEnvironment = async (\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: NotifyTerminatedEphemeralEnvironmentInput,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> => {\n const { fetch: localFetch, log } = deps;\n try {\n const response = await localFetch(\n new URL(\"/api/webhooks/environment_terminated\", apiConfig.serviceBase),\n {\n body: JSON.stringify(config),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n if (!response.ok) return handleErrorResponse(response, log);\n const { environmentId, warning } =\n (await response.json()) as TerminatedEphemeralEnvironmentSuccessResult;\n if (warning) log.warn(`\u26A0\uFE0F ${warning}`);\n return { environmentId, outcome: \"success\" };\n } catch {\n log.error(`\uD83D\uDEAB Network error from terminate_preview_environment, aborting.`);\n return {\n abortReason: \"network-error\",\n outcome: \"aborted\",\n };\n }\n};\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> {\n const status = response.status;\n let abortReason: NotifyTerminatedEphemeralEnvironmentAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status === 409) abortReason = \"409-conflict\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"notifyTerminatedEphemeralEnvironment\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\n\nimport type { PollCiGreenlightStatus } from \"./types.js\";\n\n/**\n * Build the result for a completed run\n */\nexport function buildCompletedRunResult(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): PollCiGreenlightStatus {\n if (status.greenlight)\n return { greenlightStatus: status, outcome: \"success\" };\n else return { greenlightStatus: status, outcome: \"failed\" };\n}\n", "import type { PollCiGreenlightPollConfig } from \"./types.js\";\n\n/**\n * Safe default values for polling configuration.\n * If you change these values, make sure you update the JSDoc\n * comments in the PollCiGreenlightPollConfig type.\n */\nexport const pollCiGreenlightDefaults: PollCiGreenlightPollConfig = {\n abortOnSuperseded: false,\n maxRetries: 10,\n pollTimeout: 120 * 60 * 1000, // 2 hours\n retryInterval: 10 * 1000, // 10 seconds\n runInProgressInterval: 30 * 1000, // 30 seconds\n runUnderReviewInterval: 60 * 1000, // 60 seconds\n};\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\n\nimport type { CiGreenlightBugData } from \"./ci-greenlight-bug-data.js\";\nimport { logFetchError } from \"./log.js\";\n\nexport type {\n CiGreenlightBugData,\n CiGreenlightBugDetails,\n} from \"./ci-greenlight-bug-data.js\";\n\nexport type CiGreenlightStatusBase = {\n relevantRunId: string;\n relevantRunUrl: string;\n rootRunId: string;\n rootRunUrl: string;\n};\n\nexport type CiGreenlightStatusExtended = {\n relevantRunWithBugsUrl: string;\n workflowsDisabledAfterRunCount: number;\n workflowsInRunCount: number;\n workflowsUnderInvestigationCount: number;\n};\n\n/**\n * The status of a CI greenlight run. See the API documentation here for\n * more details: https://qawolf.notion.site/1b170576efea411fa785842a71e7c99e\n */\nexport type CiGreenlightStatus = CiGreenlightStatusBase &\n (\n | ({\n greenlight: boolean;\n runStage: \"completed\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"underReview\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"initializing\";\n } & Partial<CiGreenlightStatusExtended>)\n | ({\n greenlight: false;\n /**\n * Human-readable copy explaining why the run was canceled, when the\n * server provides it.\n */\n message?: string;\n /**\n * Stable, machine-readable code for why the run was canceled, when the\n * server provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"canceled\";\n } & Partial<CiGreenlightStatusExtended>)\n );\n\nexport async function fetchCiGreenlightStatus(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n {\n runId,\n }: {\n runId: string;\n },\n { fetch: localFetch, log }: SdkDependencies,\n) {\n try {\n const resp = await localFetch(\n new URL(\n `/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,\n serviceBase,\n ),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent,\n },\n },\n );\n\n if (resp.ok) {\n const greenlightStatus = (await resp.json()) as CiGreenlightStatus;\n return {\n greenlightStatus,\n httpStatus: resp.status,\n ok: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"fetchCiGreenlightStatus\",\n response: resp,\n });\n if (resp.status === 404) {\n return {\n canRetry: true,\n errorType: \"not-found\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n if (resp.status >= 500) {\n return {\n canRetry: true,\n errorType: \"server\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n return {\n canRetry: false,\n errorType: \"client\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n } catch {\n return {\n canRetry: true,\n errorType: \"network\",\n httpStatus: 0,\n ok: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { fetchCiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { sleep } from \"../../../other.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport type {\n MakePollCiGreenlightStatusIteratorParams,\n PollCiGreenlightIteration,\n} from \"./types.js\";\n\n/**\n * Creates an async generator that yields CI greenlight status updates or abort notifications.\n *\n * This low-level API gives you full control over the polling loop, allowing you to:\n * - Inspect status after each fetch\n * - Break out of the loop based on custom criteria\n * - Add custom logging or side effects\n * - Handle abort conditions without exceptions\n *\n * The iterator yields a discriminated union with `isAborted` property:\n * - `isAborted: false` - Normal status update with run information\n * - `isAborted: true` - Terminal condition (timeout, error, canceled, etc.)\n *\n * Note: This function does not throw errors. All error conditions are yielded as\n * abort results that you must check and handle.\n *\n * @example\n * ```typescript\n * const greenlightIterator = makePollCiGreenlightStatusIterator({ runId: \"my-run-id\" });\n *\n * for await (const lastPoll of greenlightIterator) {\n * // Check for abort conditions first\n * if (lastPoll.isAborted) {\n * console.error(`Aborted: ${lastPoll.abortReason}`);\n * process.exit(1);\n * }\n *\n * // Handle normal status updates\n * const { status } = lastPoll;\n * console.log(`Current stage: ${status.runStage}`);\n *\n * // Exit with error if run reached a terminal stage without greenlight\n * if (lastPoll.isFailedTerminalStage) {\n * process.exit(1);\n * }\n * }\n * ```\n *\n */\nexport async function* makePollCiGreenlightStatusIterator(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n { runId, ...pollConfig }: MakePollCiGreenlightStatusIteratorParams,\n): AsyncGenerator<PollCiGreenlightIteration, void, unknown> {\n const { log } = deps;\n\n const {\n maxRetries = pollCiGreenlightDefaults.maxRetries,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n retryInterval = pollCiGreenlightDefaults.retryInterval,\n runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,\n runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval,\n } = pollConfig;\n\n let retries = 0;\n let previousStatus: CiGreenlightStatus | undefined = undefined;\n const startedAt = Date.now();\n\n while (Date.now() - startedAt <= pollTimeout) {\n const responseState = await fetchCiGreenlightStatus(\n apiConfig,\n { runId },\n deps,\n );\n\n const elapsedMs = Date.now() - startedAt;\n\n if (!responseState.ok && !responseState.canRetry) {\n yield {\n abortReason: \"4XX-client-error\",\n elapsedMs,\n httpStatus: responseState.httpStatus,\n isAborted: true,\n };\n return;\n }\n\n if (!responseState.ok) {\n retries += 1;\n const { errorType, httpStatus } = responseState;\n if (retries > maxRetries) {\n switch (errorType) {\n case \"network\":\n yield {\n abortReason: \"network-error\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n break;\n case \"not-found\":\n yield {\n abortReason: \"404-run-not-found\",\n elapsedMs,\n httpStatus: httpStatus ?? 404,\n isAborted: true,\n };\n break;\n case \"server\":\n yield {\n abortReason: \"5XX-server-error\",\n elapsedMs,\n httpStatus: httpStatus ?? 500,\n isAborted: true,\n };\n break;\n default:\n throw Error(`Unexpected error type: ${errorType satisfies never}`);\n }\n return;\n }\n\n const retryLabel = `${\n httpStatus ? ` (status ${httpStatus})` : \"\"\n }, will try again... (${retries}/${maxRetries})`;\n\n if (errorType === \"network\") log.warn(`\u274C Network error${retryLabel}`);\n else if (errorType === \"not-found\")\n log.info(`\u23F3 Run not found${retryLabel}`);\n else if (errorType === \"server\") log.warn(`\u274C Server error${retryLabel}`);\n\n await sleep(retryInterval);\n continue;\n }\n\n // Success - reset retry counter\n retries = 0;\n const { greenlightStatus } = responseState;\n const stageChanged =\n !previousStatus || previousStatus.runStage !== greenlightStatus.runStage;\n\n // Determine if this is a failed terminal stage\n const isFailedTerminalStage =\n greenlightStatus.runStage === \"canceled\" ||\n (greenlightStatus.runStage === \"completed\" &&\n greenlightStatus.greenlight === false);\n\n yield {\n elapsedMs,\n isAborted: false,\n isFailedTerminalStage,\n previousStatus,\n stageChanged,\n status: greenlightStatus,\n };\n\n // Update previous status for next iteration\n previousStatus = greenlightStatus;\n\n switch (greenlightStatus.runStage) {\n case \"canceled\": {\n yield {\n abortReason: \"run-canceled\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n }\n case \"completed\":\n return;\n case \"initializing\":\n await sleep(runInProgressInterval);\n break;\n case \"underReview\":\n await sleep(runUnderReviewInterval);\n break;\n default:\n throw Error(\n `Unexpected run stage: ${greenlightStatus satisfies never}`,\n );\n }\n }\n\n // Timeout\n yield {\n abortReason: \"poll-timed-out\",\n elapsedMs: Date.now() - startedAt,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { pluralize } from \"../../../other.js\";\n\n/**\n * Build log message for successful completed run\n */\nexport function buildSuccessLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { nonBlockingBugsCount, relevantRunUrl } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n return `\u2705 Run passed and no blocking bugs found${\n nonBlockingBugsCount > 0\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )} found`\n : \"\"\n }.\\n${urlInfo}`;\n}\n\n/**\n * Build log message for failed completed run\n */\nexport function buildFailedLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const {\n blockingBugsCount,\n nonBlockingBugsCount,\n relevantRunWithBugsUrl,\n reproducedBugs,\n } = status;\n\n const blockingBugUrls = reproducedBugs\n .filter((bug) => bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n const nonBlockingBugUrls = reproducedBugs\n .filter((bug) => !bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n\n const blockingBugList = blockingBugUrls.map((url) => `\\n\u2022 ${url}`).join(\"\");\n const nonBlockingBugList = nonBlockingBugUrls\n .map((url) => `\\n\u2022 ${url}`)\n .join(\"\");\n const bugsListInText = `${\n blockingBugUrls.length > 0 ? `\\nBLOCKING BUGS:${blockingBugList}` : \"\"\n }${\n nonBlockingBugUrls.length > 0\n ? `\\nNON BLOCKING BUGS:${nonBlockingBugList}`\n : \"\"\n }`;\n\n return (\n `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(\n blockingBugsCount,\n )} found${\n nonBlockingBugsCount\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )}`\n : \"\"\n }.\\nSee ${relevantRunWithBugsUrl}\\n` +\n \"You may review the priority of certain bugs to mark these non-blocking and retry the job.\\n\" +\n bugsListInText\n );\n}\n\n/**\n * Build log message for superseded run (aborting)\n */\nexport function buildSupersededAbortLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `\u274C Aborting due to superseded run (option 'abortOnSuperseded' is enabled).${supersedingDetails}`;\n}\n\n/**\n * Build log message for superseded run (continuing)\n */\nexport function buildSupersededContinueLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `Root run was superseded:${supersedingDetails}`;\n}\n\n/**\n * Build log messages for different run stages\n */\nexport function buildRunStageLogMessage(\n runStage: CiGreenlightStatus[\"runStage\"],\n relevantRunUrl: string,\n): string {\n const urlInfo = `See ${relevantRunUrl}`;\n\n switch (runStage) {\n case \"canceled\":\n return `\uD83D\uDEAB Run was canceled. Aborting... Please contact support.\\n${urlInfo}`;\n case \"initializing\":\n return `\u23F3 Run is in progress... ${urlInfo}`;\n case \"underReview\":\n return `\uD83D\uDD75\uFE0F Run is under review... ${urlInfo}`;\n case \"completed\":\n // Completed is handled separately by buildSuccessLogMessage/buildFailedLogMessage\n throw Error(\n \"buildRunStageLogMessage should not be called for completed stage\",\n );\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n}\n", "import type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n PollCiGreenlightIteratorHttpAborted,\n PollCiGreenlightIteratorNonHttpAborted,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * Handles aborted iterations from the CI greenlight poll iterator\n * and converts them to appropriate result objects with logging\n */\nexport function mapIteratorAbortToGreenlightStatus(\n iteration:\n | PollCiGreenlightIteratorHttpAborted\n | PollCiGreenlightIteratorNonHttpAborted,\n pollTimeout: number,\n deps: SdkDependencies,\n): PollCiGreenlightStatus {\n const { log } = deps;\n const { abortReason, httpStatus } = iteration;\n\n switch (abortReason) {\n case \"4XX-client-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"5XX-server-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"404-run-not-found\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"network-error\":\n log.error(`\uD83D\uDEAB Unrecoverable network error from CI greenlight, aborting.`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"poll-timed-out\":\n log.warn(`\u274C Poll timed out after ${pollTimeout / 1000}s`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"run-canceled\":\n log.info(`Run was canceled`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"XXX-other-http-code\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n default:\n throw Error(`Unexpected abort reason: ${abortReason satisfies never}`);\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { buildCompletedRunResult } from \"./buildCompletedRunResult.js\";\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./iterator.js\";\nimport {\n buildFailedLogMessage,\n buildRunStageLogMessage,\n buildSuccessLogMessage,\n buildSupersededAbortLogMessage,\n buildSupersededContinueLogMessage,\n} from \"./logging.js\";\nimport { mapIteratorAbortToGreenlightStatus } from \"./mapIteratorAbortToGreenlightStatus.js\";\nimport type {\n PollCiGreenlightParams,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\nexport async function pollCiGreenlightStatus(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n onRunStageChanged = () => undefined,\n runId,\n ...pollConfig\n }: PollCiGreenlightParams,\n): Promise<PollCiGreenlightStatus> {\n const { log } = deps;\n const {\n abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n } = pollConfig;\n\n const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {\n runId,\n ...pollConfig,\n });\n\n for await (const lastPoll of iterator) {\n if (lastPoll.isAborted)\n return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);\n\n // Handle status iterations\n const { previousStatus, stageChanged, status } = lastPoll;\n\n // Call onRunStageChanged callback when stage changes\n if (stageChanged) {\n try {\n await onRunStageChanged(status, previousStatus);\n } catch (e) {\n log.error(`Error in onRunStageChanged callback`, e);\n }\n }\n\n const { relevantRunId, relevantRunUrl, rootRunId, rootRunUrl, runStage } =\n status;\n\n // Superseded run handling\n const isSuperseded = rootRunId !== relevantRunId;\n const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;\n if (shouldAbortOnSuperseded) {\n const message = buildSupersededAbortLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.warn(message);\n return {\n abortReason: \"superseded-run\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n if (isSuperseded) {\n const message = buildSupersededContinueLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.info(message);\n }\n\n switch (runStage) {\n case \"canceled\":\n case \"initializing\":\n case \"underReview\": {\n log.info(buildRunStageLogMessage(runStage, relevantRunUrl));\n break;\n }\n case \"completed\": {\n const result = buildCompletedRunResult(status);\n switch (result.outcome) {\n case \"aborted\": {\n break;\n }\n case \"failed\": {\n const message = buildFailedLogMessage(status);\n log.warn(message);\n break;\n }\n case \"success\": {\n const message = buildSuccessLogMessage(status);\n log.info(message);\n break;\n }\n default:\n throw Error(`Unexpected outcome: ${result satisfies never}`);\n }\n return result;\n }\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n }\n\n // This should never be reached as the iterator handles timeout\n throw Error(\"Iterator ended unexpectedly\");\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport { buildFetchWithTimeout } from \"../other.js\";\n\nimport { defaultFetch } from \"./defaults/fetch.js\";\nimport { defaultLogDriver } from \"./defaults/log.js\";\nimport { defaultServiceBase } from \"./defaults/serviceBase.js\";\nimport { defaultUserAgent } from \"./defaults/userAgent.js\";\nimport type { SdkDependencies } from \"./dependencies.js\";\nimport { attemptNotifyDeploy } from \"./domain/attemptDeploy/index.js\";\nimport { generateSignedUrlForRunInputsExecutablesStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.js\";\nimport { generateSignedUrlForTempTeamStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-team-storage.js\";\nimport { notifyTerminatedEphemeralEnvironment } from \"./domain/notifyTerminatedEphemeralEnvironment/index.js\";\nimport { pollCiGreenlightStatus } from \"./domain/pollCiGreenlight/index.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./domain/pollCiGreenlight/iterator.js\";\n\nexport function makeQaWolfSdk(\n {\n apiKey,\n serviceBase = defaultServiceBase,\n userAgent = defaultUserAgent,\n }: {\n apiKey: string;\n serviceBase?: string;\n userAgent?: string;\n },\n {\n fetch = defaultFetch,\n log = defaultLogDriver,\n }: Partial<SdkDependencies> = {},\n) {\n if (typeof fetch !== \"function\") {\n throw Error(\n `QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.\nWe recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`,\n );\n }\n\n const deps: SdkDependencies = {\n // Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.\n // The increased timeout helps avoid edge cases where we need to search for a commit against multiple\n // code hosting service repositories as a fallback when not finding the repository based on organization/name.\n fetch: buildFetchWithTimeout(fetch, 120000),\n log,\n };\n const apiConfig: ApiConfig = { apiKey, serviceBase, userAgent };\n return {\n attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),\n generateSignedUrlForRunInputsExecutablesStorage:\n generateSignedUrlForRunInputsExecutablesStorage.bind(\n null,\n deps,\n apiConfig,\n ),\n generateSignedUrlForTempTeamStorage:\n generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),\n makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(\n null,\n deps,\n apiConfig,\n ),\n notifyTerminatedEphemeralEnvironment:\n notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),\n pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig),\n };\n}\n\nexport type * from \"./domain/attemptDeploy/index.js\";\nexport type * from \"./domain/generateSignedUrls/types.js\";\nexport type * from \"./domain/notifyTerminatedEphemeralEnvironment/types.js\";\nexport type * from \"./domain/pollCiGreenlight/types.js\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["export type {\n CiGreenlightStatus,\n CiGreenlightStatusBase,\n} from \"./lib/api/index.js\";\nexport * from \"./lib/sdk/dependencies.js\";\nexport * from \"./lib/sdk/domain/attemptDeploy/types.js\";\nexport * from \"./lib/sdk/index.js\";\n", "import type { FetchDriver } from \"./sdk/dependencies.js\";\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function pluralize(count: number) {\n return count === 1 ? \"\" : \"s\";\n}\n\nexport function getBackoffMs(\n attemptNumber: number,\n minWaitMs = 1000,\n maxWaitMs = 10000,\n): number {\n return Math.min(maxWaitMs, minWaitMs * 1.2 ** attemptNumber);\n}\n\nexport const buildFetchWithTimeout =\n (fetch: FetchDriver, defaultTimeoutMs: number) =>\n async (...args: Parameters<FetchDriver>) => {\n // Allow signal to be overridden by the caller\n const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);\n\n return fetch(args[0], { ...args[1], signal });\n };\n", "export const defaultFetch = globalThis.fetch;\n", "import type { LogDriver } from \"../dependencies.js\";\n\nexport const defaultLogDriver: LogDriver = {\n error(message, error) {\n console.error(message, error);\n },\n info(message) {\n console.log(message);\n },\n warn(message) {\n console.warn(message);\n },\n};\n", "export const defaultServiceBase = \"https://app.qawolf.com/\";\n", "{\n \"name\": \"@qawolf/ci-sdk\",\n \"version\": \"2.7.0\",\n \"private\": false,\n \"description\": \"A simple SDK for interacting with QAWolf in CI scripts.\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"author\": \"Jules Sam. Randolph<jules@qawolf.com>\",\n \"files\": [\n \"/dist\",\n \"/README.md\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"platform-builder --config platformBuilder.config.ts --config platformBuilder.cjs.config.ts\",\n \"lint:ci\": \"npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT\",\n \"lint:dev\": \"npm run lint:first-half\",\n \"lint:first-half\": \"eslint . --fix --quiet && oxfmt --write .\",\n \"lint:second-half\": \"dpdm --exit-code circular:1 --no-tree --no-warning --transform --include='.*' --exclude='/(dist|node_modules)/' '**/*'\",\n \"prepublishOnly\": \"nx run ci-sdk:build\",\n \"test\": \"NODE_OPTIONS=\\\"--experimental-vm-modules\\\" NODE_NO_WARNINGS=1 jest\",\n \"tsc:check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@qawolf/ci-utils\": \"^1.1.2\",\n \"@sinonjs/fake-timers\": \"^10.3.0\",\n \"tslib\": \"^2.6.2\"\n },\n \"devDependencies\": {\n \"@qawolf/platform-builder\": \"^1.2.2\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=20\"\n }\n}\n", "import packageJson from \"../../../../package.json\" with { type: \"json\" };\n\nexport const defaultUserAgent = `ci-sdk/${packageJson.version}`;\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nexport async function logFetchError({\n log,\n methodName,\n response,\n}: {\n log: LogDriver;\n methodName: string;\n response: Response;\n}) {\n if (response.ok) return;\n\n const { eventId, failureMessage } = await (async () => {\n try {\n const body = (await response.json().catch(() => response.text())) as\n | Record<string, unknown>\n | string;\n if (typeof body === \"object\" && body !== null) {\n return {\n eventId: body.eventId,\n failureMessage: body.failureMessage,\n };\n }\n // If body is not an object (i.e., it's the text from catch)\n return {\n eventId: undefined,\n failureMessage: body,\n };\n } catch {\n // If both parsing attempts somehow fail\n return {\n eventId: undefined,\n failureMessage: undefined,\n };\n }\n })();\n\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = failureMessage ? `: ${failureMessage}` : \"\";\n\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n\n log.error(\n `\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n}\n", "import type { LogDriver } from \"../../dependencies.js\";\n\nimport type { DeployStatus, NotifyDeployStatus } from \"./types.js\";\n\nexport async function handleSuccessResponse(\n data: DeployStatus,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const { environment, results } = data;\n const skippedTriggers = data.skippedTriggers ?? [];\n const skippedDeployment = data.skippedDeployment;\n const isPreviewDeployment = environment && !environment.isStatic;\n\n if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);\n\n if (environment) {\n const logPrefix = environment.isStatic\n ? \"Static environment\"\n : \"Preview environment\";\n log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);\n }\n\n // No suites were created for this deployment.\n if (results.length === 0) {\n const skipMessages = [\n ...skippedTriggers.map((trigger) => trigger.message),\n ...(skippedDeployment ? [skippedDeployment.message] : []),\n ];\n const skipDetail =\n skipMessages.length > 0 ? ` ${skipMessages.join(\" \")}` : \"\";\n\n // Preview deployments legitimately often produce no run; keep the success\n // outcome but surface any skip reason so it is not silently dropped.\n if (isPreviewDeployment) {\n log.info(\n `\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: undefined,\n };\n }\n\n // A trigger matched but could not run (e.g. environment still syncing).\n // Only a backend that still sends skipped_triggers reaches this arm. Current\n // backends omit the field, so those responses bypass it and fall to the\n // generic \"no trigger matched\" warning below even when a trigger did match.\n if (skippedTriggers.length > 0) {\n log.error(`\uD83D\uDEAB No run was created for this deployment.${skipDetail}`);\n return {\n failReason: \"trigger-skipped\",\n outcome: \"failed\",\n skippedTriggers,\n };\n }\n\n log.warn(\n skippedDeployment\n ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}`\n : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`,\n );\n return {\n outcome: \"skipped\",\n skippedDeployment,\n };\n }\n\n // If there are results, environment must be defined\n if (!environment) {\n log.error(`\uD83D\uDEAB No environment matched the request. Please contact support.`);\n return { failReason: \"no-environment\", outcome: \"failed\" };\n }\n\n // A result arm this SDK version does not recognize (newer backend). We cannot\n // classify the outcome, so surface it as a failure rather than guessing.\n const unrecognizedResult = results.find((result) => \"unrecognized\" in result);\n if (unrecognizedResult) {\n log.error(\n `\uD83D\uDEAB The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`,\n );\n return { failReason: \"unknown-result\", outcome: \"failed\" };\n }\n\n const failedTrigger = results.find((result) => \"failureReason\" in result);\n if (failedTrigger) {\n // Prefer the customer-facing message; older backends send only the internal\n // reason, which is all we can show in that case.\n log.error(\n `\uD83D\uDEAB Run could not be created. Reason: \"${failedTrigger.failureMessage ?? failedTrigger.failureReason}\". Please contact support.`,\n );\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n\n const duplicateSuite = results.find((result) => \"duplicateSuiteId\" in result);\n if (duplicateSuite) {\n log.info(\n `\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: duplicateSuite.duplicateSuiteId,\n };\n }\n\n const successfulTrigger = results.find(\n (result) => \"createdSuiteId\" in result,\n );\n if (!successfulTrigger) {\n // results is non-empty here, so triggers did match \u2014 this is not the\n // deterministic no-trigger-match skip. Reaching this point means the\n // response carried results we could not turn into a run, so it is an\n // unexpected failure rather than a skip.\n log.error(`\uD83D\uDEAB Run could not be created. Please contact support.`);\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n log.info(\n `\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: successfulTrigger.createdSuiteId,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\nimport type { DeployStatus, DeploySuccessSuiteResult } from \"./types.js\";\n\n// An arm is classified by the outcome the backend declared, not by which keys\n// happen to be present.\nfunction mapSuiteResult(\n result: DeploySuccessWireResponse[\"results\"][number],\n): DeploySuccessSuiteResult {\n switch (result.outcome) {\n case \"created\":\n return {\n createdSuiteId: result.created_suite_id,\n triggerId: result.trigger_id,\n };\n case \"failed\":\n return {\n failureCode: result.failure_code,\n failureMessage: result.failure_message,\n failureReason: result.failure_reason,\n triggerId: result.trigger_id,\n };\n case \"skipped\":\n return {\n duplicateSuiteId: result.duplicate_suite_id,\n skipReason: result.skip_reason,\n triggerId: result.trigger_id,\n };\n default:\n // An outcome added by a newer backend: surface it explicitly rather than\n // forcing it into one of the known shapes.\n return { triggerId: result.trigger_id, unrecognized: true };\n }\n}\n\n// The deploy_success success body is the SDK's only snake_case wire shape; this\n// is the single place that renames it to the camelCase `DeployStatus` used\n// everywhere downstream.\nexport function mapDeploySuccessResponse(\n wire: DeploySuccessWireResponse,\n): DeployStatus {\n return {\n environment: wire.environment,\n results: wire.results.map(mapSuiteResult),\n skippedDeployment: wire.skipped_deployment && {\n message: wire.skipped_deployment.message,\n reason: wire.skipped_deployment.reason,\n },\n skippedTriggers: wire.skipped_triggers?.map((trigger) => ({\n environmentId: trigger.environment_id,\n message: trigger.message,\n reason: trigger.reason,\n triggerId: trigger.trigger_id,\n })),\n warning: wire.warning,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n // Arrays are objects too; a deploy_success body or any of its parts must be a\n // plain object, never an array. (JSON cannot produce other non-plain objects\n // such as Date or Map, so excluding arrays is sufficient here.)\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === \"string\";\n}\n\n// Validates each arm against the `outcome` the backend declared, matching how\n// mapSuiteResult discriminates. Keying both off the same field is what keeps an\n// outcome-based mapper from reading a missing payload field as undefined. It\n// also tightens `{ outcome: \"failed\" }` with no `failure_reason`: key-presence\n// classified that as unrecognized, and it is now an invalid body.\nfunction isWireSuiteResult(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.trigger_id !== \"string\") return false;\n if (!isOptionalString(value.outcome)) return false;\n switch (value.outcome) {\n case \"created\":\n return typeof value.created_suite_id === \"string\";\n case \"failed\":\n return (\n typeof value.failure_reason === \"string\" &&\n isOptionalString(value.failure_code) &&\n isOptionalString(value.failure_message)\n );\n case \"skipped\":\n return (\n typeof value.duplicate_suite_id === \"string\" &&\n typeof value.skip_reason === \"string\"\n );\n default:\n // An outcome this SDK version does not know, or none at all. Accept it so\n // an older SDK does not reject the whole response; mapSuiteResult maps it\n // to an explicit unrecognized outcome.\n return true;\n }\n}\n\nfunction isEnvironment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.isStatic !== \"boolean\") return false;\n if (value.alias !== undefined && typeof value.alias !== \"string\")\n return false;\n return true;\n}\n\nfunction isSkippedDeployment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return typeof value.message === \"string\" && typeof value.reason === \"string\";\n}\n\nfunction isSkippedTrigger(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return (\n typeof value.environment_id === \"string\" &&\n typeof value.message === \"string\" &&\n typeof value.reason === \"string\" &&\n typeof value.trigger_id === \"string\"\n );\n}\n\nfunction isDeploySuccessWireResponse(\n value: unknown,\n): value is DeploySuccessWireResponse {\n if (!isRecord(value)) return false;\n if (value.environment !== undefined && !isEnvironment(value.environment))\n return false;\n\n if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))\n return false;\n\n if (\n value.skipped_deployment !== undefined &&\n !isSkippedDeployment(value.skipped_deployment)\n )\n return false;\n\n if (\n value.skipped_triggers !== undefined &&\n (!Array.isArray(value.skipped_triggers) ||\n !value.skipped_triggers.every(isSkippedTrigger))\n )\n return false;\n\n if (!isOptionalString(value.warning)) return false;\n\n return true;\n}\n\n// Validate the deploy_success success body at runtime instead of trusting a\n// cast. `environment` is required to be present-or-explicitly-undefined; the\n// two skip fields are optional (older servers omit them).\nexport function parseDeploySuccessWireResponse(\n value: unknown,\n): DeploySuccessWireResponse | \"invalid\" {\n return isDeploySuccessWireResponse(value) ? value : \"invalid\";\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport { handleSuccessResponse } from \"./handleSuccessResponse.js\";\nimport { mapDeploySuccessResponse } from \"./mapDeploySuccessResponse.js\";\nimport { parseDeploySuccessWireResponse } from \"./parseDeploySuccessWireResponse.js\";\nimport type {\n AttemptDeployHttpAbortReason,\n DeployConfig,\n NotifyDeployStatus,\n} from \"./types.js\";\n\nexport async function attemptNotifyDeploy(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: Partial<DeployConfig>,\n): Promise<NotifyDeployStatus> {\n const { fetch: localFetch, log } = deps;\n\n let response: Response;\n let bodyText: string;\n try {\n response = await localFetch(\n new URL(\"/api/webhooks/deploy_success\", apiConfig.serviceBase),\n {\n body: JSON.stringify({\n branch: config.branch,\n commit_url: config.commitUrl,\n deduplication_key: config.deduplicationKey,\n deployment_type: config.deploymentType,\n deployment_url: config.deploymentUrl,\n ...(\"ephemeralEnvironment\" in config\n ? {\n ephemeral_environment: config.ephemeralEnvironment,\n }\n : \"hostingService\" in config && {\n hosting_service: config.hostingService,\n merge_request_number:\n config.hostingService === \"GitLab\"\n ? config.mergeRequestNumber\n : undefined,\n pull_request_number:\n config.hostingService === \"GitHub\"\n ? config.pullRequestNumber\n : undefined,\n repository: config.repository,\n }),\n sha: config.sha,\n variables: config.variables,\n workspaceId: config.workspaceId,\n }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n // Override default timeout to 5 minutes. This gives extra room\n // for both (1) waiting for reconciliation (2) creating the run.\n signal: AbortSignal.timeout(5 * 60 * 1000),\n },\n );\n\n if (!response.ok) return handleErrorResponse(response, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from deploy_success, aborting.`);\n return {\n abortReason: \"network-error\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n\n let rawBody: unknown;\n try {\n rawBody = JSON.parse(bodyText);\n } catch {\n return abortInvalidResponseBody(log, \"the response body was not JSON\");\n }\n\n const wire = parseDeploySuccessWireResponse(rawBody);\n if (wire === \"invalid\") {\n return abortInvalidResponseBody(\n log,\n \"the response body did not match the expected shape\",\n );\n }\n\n const data = mapDeploySuccessResponse(wire);\n return handleSuccessResponse(data, log);\n}\n\nfunction abortInvalidResponseBody(\n log: LogDriver,\n detail: string,\n): NotifyDeployStatus {\n log.error(`\uD83D\uDEAB Invalid response from deploy_success (${detail}), aborting.`);\n return {\n abortReason: \"invalid-response-body\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n}\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const status = response.status;\n let abortReason: AttemptDeployHttpAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"attemptNotifyDeploy\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "const signedUrlPaths = {\n runInputsExecutables: \"/api/v0/run-inputs-executables-signed-urls\",\n teamStorage: \"/api/v0/team-storage-signed-url\",\n} as const;\n\nexport function buildSignedUrl({\n destinationFilePath,\n endpoint,\n serviceBase,\n workspaceId,\n}: {\n destinationFilePath: string | undefined;\n endpoint: keyof typeof signedUrlPaths;\n serviceBase: string;\n workspaceId: string | undefined;\n}): URL {\n const url = new URL(signedUrlPaths[endpoint], serviceBase);\n if (destinationFilePath !== undefined)\n url.searchParams.set(\"file\", destinationFilePath);\n if (workspaceId !== undefined)\n url.searchParams.set(\"workspaceId\", workspaceId);\n return url;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForRunInputsExecutablesStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: GenerateSignedUrlConfig,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"runInputsExecutables\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForRunInputsExecutablesStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForRunInputsExecutablesStorage } from \"../../../api/generate-signed-url-for-run-inputs-executables.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n GenerateSignedUrlAbortReason,\n GenerateSignedUrlConfig,\n GenerateSignedUrlStatus,\n} from \"./types.js\";\n\nexport async function generateSignedUrlForRunInputsExecutablesStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState =\n await callGenerateSignedUrlForRunInputsExecutablesStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForTempTeamStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: Partial<GenerateSignedUrlConfig>,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"teamStorage\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForTempTeamStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForTempTeamStorage } from \"../../../api/generate-signed-url-for-team-storage.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type { GenerateSignedUrlConfig } from \"./types.js\";\n\ntype GenerateSignedUrlStatus =\n | {\n fileLocation?: string;\n interactiveRunFileLocation?: string;\n /** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */\n playgroundFileLocation?: string;\n success: true;\n uploadUrl?: string;\n }\n | {\n abortReason: GenerateSignedUrlAbortReason;\n httpStatus?: number;\n success: false;\n };\n\nexport type GenerateSignedUrlAbortReason =\n | \"client-network-error\"\n | \"sdk-argument-validation-failed\"\n | \"400-invalid-request\"\n | \"401-invalid-credentials\"\n | \"403-forbidden\"\n | \"5XX-server-error\"\n | \"XXX-other-http-code\";\n\nexport async function generateSignedUrlForTempTeamStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState = await callGenerateSignedUrlForTempTeamStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n NotifyTerminatedEphemeralEnvironmentAbortReason,\n NotifyTerminatedEphemeralEnvironmentInput,\n NotifyTerminatedEphemeralEnvironmentResult,\n TerminatedEphemeralEnvironmentSuccessResult,\n} from \"./types.js\";\n\nexport const notifyTerminatedEphemeralEnvironment = async (\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: NotifyTerminatedEphemeralEnvironmentInput,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> => {\n const { fetch: localFetch, log } = deps;\n try {\n const response = await localFetch(\n new URL(\"/api/webhooks/environment_terminated\", apiConfig.serviceBase),\n {\n body: JSON.stringify(config),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n if (!response.ok) return handleErrorResponse(response, log);\n const { environmentId, warning } =\n (await response.json()) as TerminatedEphemeralEnvironmentSuccessResult;\n if (warning) log.warn(`\u26A0\uFE0F ${warning}`);\n return { environmentId, outcome: \"success\" };\n } catch {\n log.error(`\uD83D\uDEAB Network error from terminate_preview_environment, aborting.`);\n return {\n abortReason: \"network-error\",\n outcome: \"aborted\",\n };\n }\n};\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> {\n const status = response.status;\n let abortReason: NotifyTerminatedEphemeralEnvironmentAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status === 409) abortReason = \"409-conflict\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"notifyTerminatedEphemeralEnvironment\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\n\nimport type { PollCiGreenlightStatus } from \"./types.js\";\n\n/**\n * Build the result for a completed run\n */\nexport function buildCompletedRunResult(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): PollCiGreenlightStatus {\n if (status.greenlight)\n return { greenlightStatus: status, outcome: \"success\" };\n else return { greenlightStatus: status, outcome: \"failed\" };\n}\n", "import type { PollCiGreenlightPollConfig } from \"./types.js\";\n\n/**\n * Safe default values for polling configuration.\n * If you change these values, make sure you update the JSDoc\n * comments in the PollCiGreenlightPollConfig type.\n */\nexport const pollCiGreenlightDefaults: PollCiGreenlightPollConfig = {\n abortOnSuperseded: false,\n maxRetries: 10,\n pollTimeout: 120 * 60 * 1000, // 2 hours\n retryInterval: 10 * 1000, // 10 seconds\n runInProgressInterval: 30 * 1000, // 30 seconds\n runUnderReviewInterval: 60 * 1000, // 60 seconds\n};\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\n\nimport type { CiGreenlightBugData } from \"./ci-greenlight-bug-data.js\";\nimport { logFetchError } from \"./log.js\";\n\nexport type {\n CiGreenlightBugData,\n CiGreenlightBugDetails,\n} from \"./ci-greenlight-bug-data.js\";\n\nexport type CiGreenlightStatusBase = {\n relevantRunId: string;\n relevantRunUrl: string;\n rootRunId: string;\n rootRunUrl: string;\n};\n\nexport type CiGreenlightStatusExtended = {\n relevantRunWithBugsUrl: string;\n workflowsDisabledAfterRunCount: number;\n workflowsInRunCount: number;\n workflowsUnderInvestigationCount: number;\n};\n\n/**\n * The status of a CI greenlight run. See the API documentation here for\n * more details: https://qawolf.notion.site/1b170576efea411fa785842a71e7c99e\n */\nexport type CiGreenlightStatus = CiGreenlightStatusBase &\n (\n | ({\n greenlight: boolean;\n runStage: \"completed\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"underReview\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"initializing\";\n } & Partial<CiGreenlightStatusExtended>)\n | ({\n greenlight: false;\n /**\n * Human-readable copy explaining why the run was canceled, when the\n * server provides it.\n */\n message?: string;\n /**\n * Stable, machine-readable code for why the run was canceled, when the\n * server provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"canceled\";\n } & Partial<CiGreenlightStatusExtended>)\n );\n\nexport async function fetchCiGreenlightStatus(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n {\n runId,\n }: {\n runId: string;\n },\n { fetch: localFetch, log }: SdkDependencies,\n) {\n try {\n const resp = await localFetch(\n new URL(\n `/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,\n serviceBase,\n ),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent,\n },\n },\n );\n\n if (resp.ok) {\n const greenlightStatus = (await resp.json()) as CiGreenlightStatus;\n return {\n greenlightStatus,\n httpStatus: resp.status,\n ok: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"fetchCiGreenlightStatus\",\n response: resp,\n });\n if (resp.status === 404) {\n return {\n canRetry: true,\n errorType: \"not-found\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n if (resp.status >= 500) {\n return {\n canRetry: true,\n errorType: \"server\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n return {\n canRetry: false,\n errorType: \"client\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n } catch {\n return {\n canRetry: true,\n errorType: \"network\",\n httpStatus: 0,\n ok: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { fetchCiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { sleep } from \"../../../other.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport type {\n MakePollCiGreenlightStatusIteratorParams,\n PollCiGreenlightIteration,\n} from \"./types.js\";\n\n/**\n * Creates an async generator that yields CI greenlight status updates or abort notifications.\n *\n * This low-level API gives you full control over the polling loop, allowing you to:\n * - Inspect status after each fetch\n * - Break out of the loop based on custom criteria\n * - Add custom logging or side effects\n * - Handle abort conditions without exceptions\n *\n * The iterator yields a discriminated union with `isAborted` property:\n * - `isAborted: false` - Normal status update with run information\n * - `isAborted: true` - Terminal condition (timeout, error, canceled, etc.)\n *\n * Note: This function does not throw errors. All error conditions are yielded as\n * abort results that you must check and handle.\n *\n * @example\n * ```typescript\n * const greenlightIterator = makePollCiGreenlightStatusIterator({ runId: \"my-run-id\" });\n *\n * for await (const lastPoll of greenlightIterator) {\n * // Check for abort conditions first\n * if (lastPoll.isAborted) {\n * console.error(`Aborted: ${lastPoll.abortReason}`);\n * process.exit(1);\n * }\n *\n * // Handle normal status updates\n * const { status } = lastPoll;\n * console.log(`Current stage: ${status.runStage}`);\n *\n * // Exit with error if run reached a terminal stage without greenlight\n * if (lastPoll.isFailedTerminalStage) {\n * process.exit(1);\n * }\n * }\n * ```\n *\n */\nexport async function* makePollCiGreenlightStatusIterator(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n { runId, ...pollConfig }: MakePollCiGreenlightStatusIteratorParams,\n): AsyncGenerator<PollCiGreenlightIteration, void, unknown> {\n const { log } = deps;\n\n const {\n maxRetries = pollCiGreenlightDefaults.maxRetries,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n retryInterval = pollCiGreenlightDefaults.retryInterval,\n runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,\n runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval,\n } = pollConfig;\n\n let retries = 0;\n let previousStatus: CiGreenlightStatus | undefined = undefined;\n const startedAt = Date.now();\n\n while (Date.now() - startedAt <= pollTimeout) {\n const responseState = await fetchCiGreenlightStatus(\n apiConfig,\n { runId },\n deps,\n );\n\n const elapsedMs = Date.now() - startedAt;\n\n if (!responseState.ok && !responseState.canRetry) {\n yield {\n abortReason: \"4XX-client-error\",\n elapsedMs,\n httpStatus: responseState.httpStatus,\n isAborted: true,\n };\n return;\n }\n\n if (!responseState.ok) {\n retries += 1;\n const { errorType, httpStatus } = responseState;\n if (retries > maxRetries) {\n switch (errorType) {\n case \"network\":\n yield {\n abortReason: \"network-error\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n break;\n case \"not-found\":\n yield {\n abortReason: \"404-run-not-found\",\n elapsedMs,\n httpStatus: httpStatus ?? 404,\n isAborted: true,\n };\n break;\n case \"server\":\n yield {\n abortReason: \"5XX-server-error\",\n elapsedMs,\n httpStatus: httpStatus ?? 500,\n isAborted: true,\n };\n break;\n default:\n throw Error(`Unexpected error type: ${errorType satisfies never}`);\n }\n return;\n }\n\n const retryLabel = `${\n httpStatus ? ` (status ${httpStatus})` : \"\"\n }, will try again... (${retries}/${maxRetries})`;\n\n if (errorType === \"network\") log.warn(`\u274C Network error${retryLabel}`);\n else if (errorType === \"not-found\")\n log.info(`\u23F3 Run not found${retryLabel}`);\n else if (errorType === \"server\") log.warn(`\u274C Server error${retryLabel}`);\n\n await sleep(retryInterval);\n continue;\n }\n\n // Success - reset retry counter\n retries = 0;\n const { greenlightStatus } = responseState;\n const stageChanged =\n !previousStatus || previousStatus.runStage !== greenlightStatus.runStage;\n\n // Determine if this is a failed terminal stage\n const isFailedTerminalStage =\n greenlightStatus.runStage === \"canceled\" ||\n (greenlightStatus.runStage === \"completed\" &&\n greenlightStatus.greenlight === false);\n\n yield {\n elapsedMs,\n isAborted: false,\n isFailedTerminalStage,\n previousStatus,\n stageChanged,\n status: greenlightStatus,\n };\n\n // Update previous status for next iteration\n previousStatus = greenlightStatus;\n\n switch (greenlightStatus.runStage) {\n case \"canceled\": {\n yield {\n abortReason: \"run-canceled\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n message: greenlightStatus.message,\n reason: greenlightStatus.reason,\n };\n return;\n }\n case \"completed\":\n return;\n case \"initializing\":\n await sleep(runInProgressInterval);\n break;\n case \"underReview\":\n await sleep(runUnderReviewInterval);\n break;\n default:\n throw Error(\n `Unexpected run stage: ${greenlightStatus satisfies never}`,\n );\n }\n }\n\n // Timeout\n yield {\n abortReason: \"poll-timed-out\",\n elapsedMs: Date.now() - startedAt,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { pluralize } from \"../../../other.js\";\n\n/**\n * Build log message for successful completed run\n */\nexport function buildSuccessLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { nonBlockingBugsCount, relevantRunUrl } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n return `\u2705 Run passed and no blocking bugs found${\n nonBlockingBugsCount > 0\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )} found`\n : \"\"\n }.\\n${urlInfo}`;\n}\n\n/**\n * Build log message for failed completed run\n */\nexport function buildFailedLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const {\n blockingBugsCount,\n nonBlockingBugsCount,\n relevantRunWithBugsUrl,\n reproducedBugs,\n } = status;\n\n const blockingBugUrls = reproducedBugs\n .filter((bug) => bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n const nonBlockingBugUrls = reproducedBugs\n .filter((bug) => !bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n\n const blockingBugList = blockingBugUrls.map((url) => `\\n\u2022 ${url}`).join(\"\");\n const nonBlockingBugList = nonBlockingBugUrls\n .map((url) => `\\n\u2022 ${url}`)\n .join(\"\");\n const bugsListInText = `${\n blockingBugUrls.length > 0 ? `\\nBLOCKING BUGS:${blockingBugList}` : \"\"\n }${\n nonBlockingBugUrls.length > 0\n ? `\\nNON BLOCKING BUGS:${nonBlockingBugList}`\n : \"\"\n }`;\n\n return (\n `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(\n blockingBugsCount,\n )} found${\n nonBlockingBugsCount\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )}`\n : \"\"\n }.\\nSee ${relevantRunWithBugsUrl}\\n` +\n \"You may review the priority of certain bugs to mark these non-blocking and retry the job.\\n\" +\n bugsListInText\n );\n}\n\n/**\n * Build log message for superseded run (aborting)\n */\nexport function buildSupersededAbortLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `\u274C Aborting due to superseded run (option 'abortOnSuperseded' is enabled).${supersedingDetails}`;\n}\n\n/**\n * Build log message for superseded run (continuing)\n */\nexport function buildSupersededContinueLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `Root run was superseded:${supersedingDetails}`;\n}\n\n/**\n * Build log messages for different run stages\n */\nexport function buildRunStageLogMessage(\n status: Exclude<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { relevantRunUrl, runStage } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n switch (runStage) {\n case \"canceled\":\n return `\uD83D\uDEAB Run was canceled. ${\n status.message || \"Aborting... Please contact support.\"\n }\\n${urlInfo}`;\n case \"initializing\":\n return `\u23F3 Run is in progress... ${urlInfo}`;\n case \"underReview\":\n return `\uD83D\uDD75\uFE0F Run is under review... ${urlInfo}`;\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n}\n", "import type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n PollCiGreenlightIteratorHttpAborted,\n PollCiGreenlightIteratorNonHttpAborted,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * Handles aborted iterations from the CI greenlight poll iterator\n * and converts them to appropriate result objects with logging\n */\nexport function mapIteratorAbortToGreenlightStatus(\n iteration:\n | PollCiGreenlightIteratorHttpAborted\n | PollCiGreenlightIteratorNonHttpAborted,\n pollTimeout: number,\n deps: SdkDependencies,\n): PollCiGreenlightStatus {\n const { log } = deps;\n const { abortReason, httpStatus } = iteration;\n\n switch (abortReason) {\n case \"4XX-client-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"5XX-server-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"404-run-not-found\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"network-error\":\n log.error(`\uD83D\uDEAB Unrecoverable network error from CI greenlight, aborting.`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"poll-timed-out\":\n log.warn(`\u274C Poll timed out after ${pollTimeout / 1000}s`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"run-canceled\":\n log.info(\n iteration.message\n ? `Run was canceled. ${iteration.message}`\n : `Run was canceled`,\n );\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"XXX-other-http-code\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n default:\n throw Error(`Unexpected abort reason: ${abortReason satisfies never}`);\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { buildCompletedRunResult } from \"./buildCompletedRunResult.js\";\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./iterator.js\";\nimport {\n buildFailedLogMessage,\n buildRunStageLogMessage,\n buildSuccessLogMessage,\n buildSupersededAbortLogMessage,\n buildSupersededContinueLogMessage,\n} from \"./logging.js\";\nimport { mapIteratorAbortToGreenlightStatus } from \"./mapIteratorAbortToGreenlightStatus.js\";\nimport type {\n PollCiGreenlightParams,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\nexport async function pollCiGreenlightStatus(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n onRunStageChanged = () => undefined,\n runId,\n ...pollConfig\n }: PollCiGreenlightParams,\n): Promise<PollCiGreenlightStatus> {\n const { log } = deps;\n const {\n abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n } = pollConfig;\n\n const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {\n runId,\n ...pollConfig,\n });\n\n for await (const lastPoll of iterator) {\n if (lastPoll.isAborted)\n return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);\n\n // Handle status iterations\n const { previousStatus, stageChanged, status } = lastPoll;\n\n // Call onRunStageChanged callback when stage changes\n if (stageChanged) {\n try {\n await onRunStageChanged(status, previousStatus);\n } catch (e) {\n log.error(`Error in onRunStageChanged callback`, e);\n }\n }\n\n const { relevantRunId, relevantRunUrl, rootRunId, rootRunUrl, runStage } =\n status;\n\n // Superseded run handling\n const isSuperseded = rootRunId !== relevantRunId;\n const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;\n if (shouldAbortOnSuperseded) {\n const message = buildSupersededAbortLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.warn(message);\n return {\n abortReason: \"superseded-run\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n if (isSuperseded) {\n const message = buildSupersededContinueLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.info(message);\n }\n\n switch (runStage) {\n case \"canceled\":\n case \"initializing\":\n case \"underReview\": {\n log.info(buildRunStageLogMessage(status));\n break;\n }\n case \"completed\": {\n const result = buildCompletedRunResult(status);\n switch (result.outcome) {\n case \"aborted\": {\n break;\n }\n case \"failed\": {\n const message = buildFailedLogMessage(status);\n log.warn(message);\n break;\n }\n case \"success\": {\n const message = buildSuccessLogMessage(status);\n log.info(message);\n break;\n }\n default:\n throw Error(`Unexpected outcome: ${result satisfies never}`);\n }\n return result;\n }\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n }\n\n // This should never be reached as the iterator handles timeout\n throw Error(\"Iterator ended unexpectedly\");\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport { buildFetchWithTimeout } from \"../other.js\";\n\nimport { defaultFetch } from \"./defaults/fetch.js\";\nimport { defaultLogDriver } from \"./defaults/log.js\";\nimport { defaultServiceBase } from \"./defaults/serviceBase.js\";\nimport { defaultUserAgent } from \"./defaults/userAgent.js\";\nimport type { SdkDependencies } from \"./dependencies.js\";\nimport { attemptNotifyDeploy } from \"./domain/attemptDeploy/index.js\";\nimport { generateSignedUrlForRunInputsExecutablesStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.js\";\nimport { generateSignedUrlForTempTeamStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-team-storage.js\";\nimport { notifyTerminatedEphemeralEnvironment } from \"./domain/notifyTerminatedEphemeralEnvironment/index.js\";\nimport { pollCiGreenlightStatus } from \"./domain/pollCiGreenlight/index.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./domain/pollCiGreenlight/iterator.js\";\n\nexport function makeQaWolfSdk(\n {\n apiKey,\n serviceBase = defaultServiceBase,\n userAgent = defaultUserAgent,\n }: {\n apiKey: string;\n serviceBase?: string;\n userAgent?: string;\n },\n {\n fetch = defaultFetch,\n log = defaultLogDriver,\n }: Partial<SdkDependencies> = {},\n) {\n if (typeof fetch !== \"function\") {\n throw Error(\n `QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.\nWe recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`,\n );\n }\n\n const deps: SdkDependencies = {\n // Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.\n // The increased timeout helps avoid edge cases where we need to search for a commit against multiple\n // code hosting service repositories as a fallback when not finding the repository based on organization/name.\n fetch: buildFetchWithTimeout(fetch, 120000),\n log,\n };\n const apiConfig: ApiConfig = { apiKey, serviceBase, userAgent };\n return {\n attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),\n generateSignedUrlForRunInputsExecutablesStorage:\n generateSignedUrlForRunInputsExecutablesStorage.bind(\n null,\n deps,\n apiConfig,\n ),\n generateSignedUrlForTempTeamStorage:\n generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),\n makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(\n null,\n deps,\n apiConfig,\n ),\n notifyTerminatedEphemeralEnvironment:\n notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),\n pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig),\n };\n}\n\nexport type * from \"./domain/attemptDeploy/index.js\";\nexport type * from \"./domain/generateSignedUrls/types.js\";\nexport type * from \"./domain/notifyTerminatedEphemeralEnvironment/types.js\";\nexport type * from \"./domain/pollCiGreenlight/types.js\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["handleErrorResponse"]
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,7 @@ var defaultServiceBase = "https://app.qawolf.com/";
|
|
|
38
38
|
// package.json
|
|
39
39
|
var package_default = {
|
|
40
40
|
name: "@qawolf/ci-sdk",
|
|
41
|
-
version: "2.
|
|
41
|
+
version: "2.7.0",
|
|
42
42
|
private: false,
|
|
43
43
|
description: "A simple SDK for interacting with QAWolf in CI scripts.",
|
|
44
44
|
keywords: [],
|
|
@@ -459,6 +459,7 @@ async function callGenerateSignedUrlForRunInputsExecutablesStorage({ apiKey, ser
|
|
|
459
459
|
return {
|
|
460
460
|
fileLocation: json.fileLocation,
|
|
461
461
|
httpStatus: response.status,
|
|
462
|
+
interactiveRunFileLocation: json.interactiveRunFileLocation,
|
|
462
463
|
playgroundFileLocation: json.playgroundFileLocation,
|
|
463
464
|
signedUrl: json.signedUrl,
|
|
464
465
|
success: true
|
|
@@ -526,6 +527,7 @@ async function generateSignedUrlForRunInputsExecutablesStorage(deps, apiConfig,
|
|
|
526
527
|
log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);
|
|
527
528
|
return {
|
|
528
529
|
fileLocation: responseState.fileLocation,
|
|
530
|
+
interactiveRunFileLocation: responseState.interactiveRunFileLocation,
|
|
529
531
|
playgroundFileLocation: responseState.playgroundFileLocation,
|
|
530
532
|
success: true,
|
|
531
533
|
uploadUrl: responseState.signedUrl
|
|
@@ -557,6 +559,7 @@ async function callGenerateSignedUrlForTempTeamStorage({ apiKey, serviceBase, us
|
|
|
557
559
|
return {
|
|
558
560
|
fileLocation: json.fileLocation,
|
|
559
561
|
httpStatus: response.status,
|
|
562
|
+
interactiveRunFileLocation: json.interactiveRunFileLocation,
|
|
560
563
|
playgroundFileLocation: json.playgroundFileLocation,
|
|
561
564
|
signedUrl: json.signedUrl,
|
|
562
565
|
success: true
|
|
@@ -624,6 +627,7 @@ async function generateSignedUrlForTempTeamStorage(deps, apiConfig, config) {
|
|
|
624
627
|
log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);
|
|
625
628
|
return {
|
|
626
629
|
fileLocation: responseState.fileLocation,
|
|
630
|
+
interactiveRunFileLocation: responseState.interactiveRunFileLocation,
|
|
627
631
|
playgroundFileLocation: responseState.playgroundFileLocation,
|
|
628
632
|
success: true,
|
|
629
633
|
uploadUrl: responseState.signedUrl
|
|
@@ -856,7 +860,9 @@ async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...
|
|
|
856
860
|
abortReason: "run-canceled",
|
|
857
861
|
elapsedMs,
|
|
858
862
|
httpStatus: void 0,
|
|
859
|
-
isAborted: true
|
|
863
|
+
isAborted: true,
|
|
864
|
+
message: greenlightStatus.message,
|
|
865
|
+
reason: greenlightStatus.reason
|
|
860
866
|
};
|
|
861
867
|
return;
|
|
862
868
|
}
|
|
@@ -934,20 +940,17 @@ function buildSupersededContinueLogMessage(rootRunUrl, relevantRunUrl) {
|
|
|
934
940
|
return `Root run was superseded:${supersedingDetails}`;
|
|
935
941
|
}
|
|
936
942
|
__name(buildSupersededContinueLogMessage, "buildSupersededContinueLogMessage");
|
|
937
|
-
function buildRunStageLogMessage(
|
|
943
|
+
function buildRunStageLogMessage(status) {
|
|
944
|
+
const { relevantRunUrl, runStage } = status;
|
|
938
945
|
const urlInfo = `See ${relevantRunUrl}`;
|
|
939
946
|
switch (runStage) {
|
|
940
947
|
case "canceled":
|
|
941
|
-
return `\u{1F6AB} Run was canceled. Aborting... Please contact support.
|
|
948
|
+
return `\u{1F6AB} Run was canceled. ${status.message || "Aborting... Please contact support."}
|
|
942
949
|
${urlInfo}`;
|
|
943
950
|
case "initializing":
|
|
944
951
|
return `\u23F3 Run is in progress... ${urlInfo}`;
|
|
945
952
|
case "underReview":
|
|
946
953
|
return `\u{1F575}\uFE0F Run is under review... ${urlInfo}`;
|
|
947
|
-
case "completed":
|
|
948
|
-
throw Error(
|
|
949
|
-
"buildRunStageLogMessage should not be called for completed stage"
|
|
950
|
-
);
|
|
951
954
|
default:
|
|
952
955
|
throw Error(`Unexpected run stage: ${runStage}`);
|
|
953
956
|
}
|
|
@@ -1001,7 +1004,9 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
1001
1004
|
outcome: "aborted"
|
|
1002
1005
|
};
|
|
1003
1006
|
case "run-canceled":
|
|
1004
|
-
log.info(
|
|
1007
|
+
log.info(
|
|
1008
|
+
iteration.message ? `Run was canceled. ${iteration.message}` : `Run was canceled`
|
|
1009
|
+
);
|
|
1005
1010
|
return {
|
|
1006
1011
|
abortReason,
|
|
1007
1012
|
httpStatus: void 0,
|
|
@@ -1074,7 +1079,7 @@ async function pollCiGreenlightStatus(deps, apiConfig, {
|
|
|
1074
1079
|
case "canceled":
|
|
1075
1080
|
case "initializing":
|
|
1076
1081
|
case "underReview": {
|
|
1077
|
-
log.info(buildRunStageLogMessage(
|
|
1082
|
+
log.info(buildRunStageLogMessage(status));
|
|
1078
1083
|
break;
|
|
1079
1084
|
}
|
|
1080
1085
|
case "completed": {
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/lib/other.ts", "../src/lib/sdk/defaults/fetch.ts", "../src/lib/sdk/defaults/log.ts", "../src/lib/sdk/defaults/serviceBase.ts", "../package.json", "../src/lib/sdk/defaults/userAgent.ts", "../src/lib/api/log.ts", "../src/lib/sdk/domain/attemptDeploy/handleSuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/mapDeploySuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/parseDeploySuccessWireResponse.ts", "../src/lib/sdk/domain/attemptDeploy/index.ts", "../src/lib/api/signed-url.ts", "../src/lib/api/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/api/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/notifyTerminatedEphemeralEnvironment/index.ts", "../src/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.ts", "../src/lib/sdk/domain/pollCiGreenlight/consts.ts", "../src/lib/api/ci-greenlight.ts", "../src/lib/sdk/domain/pollCiGreenlight/iterator.ts", "../src/lib/sdk/domain/pollCiGreenlight/logging.ts", "../src/lib/sdk/domain/pollCiGreenlight/mapIteratorAbortToGreenlightStatus.ts", "../src/lib/sdk/domain/pollCiGreenlight/index.ts", "../src/lib/sdk/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { FetchDriver } from \"./sdk/dependencies.js\";\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function pluralize(count: number) {\n return count === 1 ? \"\" : \"s\";\n}\n\nexport function getBackoffMs(\n attemptNumber: number,\n minWaitMs = 1000,\n maxWaitMs = 10000,\n): number {\n return Math.min(maxWaitMs, minWaitMs * 1.2 ** attemptNumber);\n}\n\nexport const buildFetchWithTimeout =\n (fetch: FetchDriver, defaultTimeoutMs: number) =>\n async (...args: Parameters<FetchDriver>) => {\n // Allow signal to be overridden by the caller\n const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);\n\n return fetch(args[0], { ...args[1], signal });\n };\n", "export const defaultFetch = globalThis.fetch;\n", "import type { LogDriver } from \"../dependencies.js\";\n\nexport const defaultLogDriver: LogDriver = {\n error(message, error) {\n console.error(message, error);\n },\n info(message) {\n console.log(message);\n },\n warn(message) {\n console.warn(message);\n },\n};\n", "export const defaultServiceBase = \"https://app.qawolf.com/\";\n", "{\n \"name\": \"@qawolf/ci-sdk\",\n \"version\": \"2.5.0\",\n \"private\": false,\n \"description\": \"A simple SDK for interacting with QAWolf in CI scripts.\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"author\": \"Jules Sam. Randolph<jules@qawolf.com>\",\n \"files\": [\n \"/dist\",\n \"/README.md\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"platform-builder --config platformBuilder.config.ts --config platformBuilder.cjs.config.ts\",\n \"lint:ci\": \"npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT\",\n \"lint:dev\": \"npm run lint:first-half\",\n \"lint:first-half\": \"eslint . --fix --quiet && oxfmt --write .\",\n \"lint:second-half\": \"dpdm --exit-code circular:1 --no-tree --no-warning --transform --include='.*' --exclude='/(dist|node_modules)/' '**/*'\",\n \"prepublishOnly\": \"nx run ci-sdk:build\",\n \"test\": \"NODE_OPTIONS=\\\"--experimental-vm-modules\\\" NODE_NO_WARNINGS=1 jest\",\n \"tsc:check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@qawolf/ci-utils\": \"^1.1.2\",\n \"@sinonjs/fake-timers\": \"^10.3.0\",\n \"tslib\": \"^2.6.2\"\n },\n \"devDependencies\": {\n \"@qawolf/platform-builder\": \"^1.2.2\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=20\"\n }\n}\n", "import packageJson from \"../../../../package.json\" with { type: \"json\" };\n\nexport const defaultUserAgent = `ci-sdk/${packageJson.version}`;\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nexport async function logFetchError({\n log,\n methodName,\n response,\n}: {\n log: LogDriver;\n methodName: string;\n response: Response;\n}) {\n if (response.ok) return;\n\n const { eventId, failureMessage } = await (async () => {\n try {\n const body = (await response.json().catch(() => response.text())) as\n | Record<string, unknown>\n | string;\n if (typeof body === \"object\" && body !== null) {\n return {\n eventId: body.eventId,\n failureMessage: body.failureMessage,\n };\n }\n // If body is not an object (i.e., it's the text from catch)\n return {\n eventId: undefined,\n failureMessage: body,\n };\n } catch {\n // If both parsing attempts somehow fail\n return {\n eventId: undefined,\n failureMessage: undefined,\n };\n }\n })();\n\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = failureMessage ? `: ${failureMessage}` : \"\";\n\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n\n log.error(\n `\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n}\n", "import type { LogDriver } from \"../../dependencies.js\";\n\nimport type { DeployStatus, NotifyDeployStatus } from \"./types.js\";\n\nexport async function handleSuccessResponse(\n data: DeployStatus,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const { environment, results } = data;\n const skippedTriggers = data.skippedTriggers ?? [];\n const skippedDeployment = data.skippedDeployment;\n const isPreviewDeployment = environment && !environment.isStatic;\n\n if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);\n\n if (environment) {\n const logPrefix = environment.isStatic\n ? \"Static environment\"\n : \"Preview environment\";\n log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);\n }\n\n // No suites were created for this deployment.\n if (results.length === 0) {\n const skipMessages = [\n ...skippedTriggers.map((trigger) => trigger.message),\n ...(skippedDeployment ? [skippedDeployment.message] : []),\n ];\n const skipDetail =\n skipMessages.length > 0 ? ` ${skipMessages.join(\" \")}` : \"\";\n\n // Preview deployments legitimately often produce no run; keep the success\n // outcome but surface any skip reason so it is not silently dropped.\n if (isPreviewDeployment) {\n log.info(\n `\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: undefined,\n };\n }\n\n // A trigger matched but could not run (e.g. environment still syncing).\n // Only a backend that still sends skipped_triggers reaches this arm. Current\n // backends omit the field, so those responses bypass it and fall to the\n // generic \"no trigger matched\" warning below even when a trigger did match.\n if (skippedTriggers.length > 0) {\n log.error(`\uD83D\uDEAB No run was created for this deployment.${skipDetail}`);\n return {\n failReason: \"trigger-skipped\",\n outcome: \"failed\",\n skippedTriggers,\n };\n }\n\n log.warn(\n skippedDeployment\n ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}`\n : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`,\n );\n return {\n outcome: \"skipped\",\n skippedDeployment,\n };\n }\n\n // If there are results, environment must be defined\n if (!environment) {\n log.error(`\uD83D\uDEAB No environment matched the request. Please contact support.`);\n return { failReason: \"no-environment\", outcome: \"failed\" };\n }\n\n // A result arm this SDK version does not recognize (newer backend). We cannot\n // classify the outcome, so surface it as a failure rather than guessing.\n const unrecognizedResult = results.find((result) => \"unrecognized\" in result);\n if (unrecognizedResult) {\n log.error(\n `\uD83D\uDEAB The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`,\n );\n return { failReason: \"unknown-result\", outcome: \"failed\" };\n }\n\n const failedTrigger = results.find((result) => \"failureReason\" in result);\n if (failedTrigger) {\n // Prefer the customer-facing message; older backends send only the internal\n // reason, which is all we can show in that case.\n log.error(\n `\uD83D\uDEAB Run could not be created. Reason: \"${failedTrigger.failureMessage ?? failedTrigger.failureReason}\". Please contact support.`,\n );\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n\n const duplicateSuite = results.find((result) => \"duplicateSuiteId\" in result);\n if (duplicateSuite) {\n log.info(\n `\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: duplicateSuite.duplicateSuiteId,\n };\n }\n\n const successfulTrigger = results.find(\n (result) => \"createdSuiteId\" in result,\n );\n if (!successfulTrigger) {\n // results is non-empty here, so triggers did match \u2014 this is not the\n // deterministic no-trigger-match skip. Reaching this point means the\n // response carried results we could not turn into a run, so it is an\n // unexpected failure rather than a skip.\n log.error(`\uD83D\uDEAB Run could not be created. Please contact support.`);\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n log.info(\n `\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: successfulTrigger.createdSuiteId,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\nimport type { DeployStatus, DeploySuccessSuiteResult } from \"./types.js\";\n\n// An arm is classified by the outcome the backend declared, not by which keys\n// happen to be present.\nfunction mapSuiteResult(\n result: DeploySuccessWireResponse[\"results\"][number],\n): DeploySuccessSuiteResult {\n switch (result.outcome) {\n case \"created\":\n return {\n createdSuiteId: result.created_suite_id,\n triggerId: result.trigger_id,\n };\n case \"failed\":\n return {\n failureCode: result.failure_code,\n failureMessage: result.failure_message,\n failureReason: result.failure_reason,\n triggerId: result.trigger_id,\n };\n case \"skipped\":\n return {\n duplicateSuiteId: result.duplicate_suite_id,\n skipReason: result.skip_reason,\n triggerId: result.trigger_id,\n };\n default:\n // An outcome added by a newer backend: surface it explicitly rather than\n // forcing it into one of the known shapes.\n return { triggerId: result.trigger_id, unrecognized: true };\n }\n}\n\n// The deploy_success success body is the SDK's only snake_case wire shape; this\n// is the single place that renames it to the camelCase `DeployStatus` used\n// everywhere downstream.\nexport function mapDeploySuccessResponse(\n wire: DeploySuccessWireResponse,\n): DeployStatus {\n return {\n environment: wire.environment,\n results: wire.results.map(mapSuiteResult),\n skippedDeployment: wire.skipped_deployment && {\n message: wire.skipped_deployment.message,\n reason: wire.skipped_deployment.reason,\n },\n skippedTriggers: wire.skipped_triggers?.map((trigger) => ({\n environmentId: trigger.environment_id,\n message: trigger.message,\n reason: trigger.reason,\n triggerId: trigger.trigger_id,\n })),\n warning: wire.warning,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n // Arrays are objects too; a deploy_success body or any of its parts must be a\n // plain object, never an array. (JSON cannot produce other non-plain objects\n // such as Date or Map, so excluding arrays is sufficient here.)\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === \"string\";\n}\n\n// Validates each arm against the `outcome` the backend declared, matching how\n// mapSuiteResult discriminates. Keying both off the same field is what keeps an\n// outcome-based mapper from reading a missing payload field as undefined. It\n// also tightens `{ outcome: \"failed\" }` with no `failure_reason`: key-presence\n// classified that as unrecognized, and it is now an invalid body.\nfunction isWireSuiteResult(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.trigger_id !== \"string\") return false;\n if (!isOptionalString(value.outcome)) return false;\n switch (value.outcome) {\n case \"created\":\n return typeof value.created_suite_id === \"string\";\n case \"failed\":\n return (\n typeof value.failure_reason === \"string\" &&\n isOptionalString(value.failure_code) &&\n isOptionalString(value.failure_message)\n );\n case \"skipped\":\n return (\n typeof value.duplicate_suite_id === \"string\" &&\n typeof value.skip_reason === \"string\"\n );\n default:\n // An outcome this SDK version does not know, or none at all. Accept it so\n // an older SDK does not reject the whole response; mapSuiteResult maps it\n // to an explicit unrecognized outcome.\n return true;\n }\n}\n\nfunction isEnvironment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.isStatic !== \"boolean\") return false;\n if (value.alias !== undefined && typeof value.alias !== \"string\")\n return false;\n return true;\n}\n\nfunction isSkippedDeployment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return typeof value.message === \"string\" && typeof value.reason === \"string\";\n}\n\nfunction isSkippedTrigger(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return (\n typeof value.environment_id === \"string\" &&\n typeof value.message === \"string\" &&\n typeof value.reason === \"string\" &&\n typeof value.trigger_id === \"string\"\n );\n}\n\nfunction isDeploySuccessWireResponse(\n value: unknown,\n): value is DeploySuccessWireResponse {\n if (!isRecord(value)) return false;\n if (value.environment !== undefined && !isEnvironment(value.environment))\n return false;\n\n if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))\n return false;\n\n if (\n value.skipped_deployment !== undefined &&\n !isSkippedDeployment(value.skipped_deployment)\n )\n return false;\n\n if (\n value.skipped_triggers !== undefined &&\n (!Array.isArray(value.skipped_triggers) ||\n !value.skipped_triggers.every(isSkippedTrigger))\n )\n return false;\n\n if (!isOptionalString(value.warning)) return false;\n\n return true;\n}\n\n// Validate the deploy_success success body at runtime instead of trusting a\n// cast. `environment` is required to be present-or-explicitly-undefined; the\n// two skip fields are optional (older servers omit them).\nexport function parseDeploySuccessWireResponse(\n value: unknown,\n): DeploySuccessWireResponse | \"invalid\" {\n return isDeploySuccessWireResponse(value) ? value : \"invalid\";\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport { handleSuccessResponse } from \"./handleSuccessResponse.js\";\nimport { mapDeploySuccessResponse } from \"./mapDeploySuccessResponse.js\";\nimport { parseDeploySuccessWireResponse } from \"./parseDeploySuccessWireResponse.js\";\nimport type {\n AttemptDeployHttpAbortReason,\n DeployConfig,\n NotifyDeployStatus,\n} from \"./types.js\";\n\nexport async function attemptNotifyDeploy(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: Partial<DeployConfig>,\n): Promise<NotifyDeployStatus> {\n const { fetch: localFetch, log } = deps;\n\n let response: Response;\n let bodyText: string;\n try {\n response = await localFetch(\n new URL(\"/api/webhooks/deploy_success\", apiConfig.serviceBase),\n {\n body: JSON.stringify({\n branch: config.branch,\n commit_url: config.commitUrl,\n deduplication_key: config.deduplicationKey,\n deployment_type: config.deploymentType,\n deployment_url: config.deploymentUrl,\n ...(\"ephemeralEnvironment\" in config\n ? {\n ephemeral_environment: config.ephemeralEnvironment,\n }\n : \"hostingService\" in config && {\n hosting_service: config.hostingService,\n merge_request_number:\n config.hostingService === \"GitLab\"\n ? config.mergeRequestNumber\n : undefined,\n pull_request_number:\n config.hostingService === \"GitHub\"\n ? config.pullRequestNumber\n : undefined,\n repository: config.repository,\n }),\n sha: config.sha,\n variables: config.variables,\n workspaceId: config.workspaceId,\n }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n // Override default timeout to 5 minutes. This gives extra room\n // for both (1) waiting for reconciliation (2) creating the run.\n signal: AbortSignal.timeout(5 * 60 * 1000),\n },\n );\n\n if (!response.ok) return handleErrorResponse(response, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from deploy_success, aborting.`);\n return {\n abortReason: \"network-error\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n\n let rawBody: unknown;\n try {\n rawBody = JSON.parse(bodyText);\n } catch {\n return abortInvalidResponseBody(log, \"the response body was not JSON\");\n }\n\n const wire = parseDeploySuccessWireResponse(rawBody);\n if (wire === \"invalid\") {\n return abortInvalidResponseBody(\n log,\n \"the response body did not match the expected shape\",\n );\n }\n\n const data = mapDeploySuccessResponse(wire);\n return handleSuccessResponse(data, log);\n}\n\nfunction abortInvalidResponseBody(\n log: LogDriver,\n detail: string,\n): NotifyDeployStatus {\n log.error(`\uD83D\uDEAB Invalid response from deploy_success (${detail}), aborting.`);\n return {\n abortReason: \"invalid-response-body\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n}\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const status = response.status;\n let abortReason: AttemptDeployHttpAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"attemptNotifyDeploy\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "const signedUrlPaths = {\n runInputsExecutables: \"/api/v0/run-inputs-executables-signed-urls\",\n teamStorage: \"/api/v0/team-storage-signed-url\",\n} as const;\n\nexport function buildSignedUrl({\n destinationFilePath,\n endpoint,\n serviceBase,\n workspaceId,\n}: {\n destinationFilePath: string | undefined;\n endpoint: keyof typeof signedUrlPaths;\n serviceBase: string;\n workspaceId: string | undefined;\n}): URL {\n const url = new URL(signedUrlPaths[endpoint], serviceBase);\n if (destinationFilePath !== undefined)\n url.searchParams.set(\"file\", destinationFilePath);\n if (workspaceId !== undefined)\n url.searchParams.set(\"workspaceId\", workspaceId);\n return url;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForRunInputsExecutablesStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: GenerateSignedUrlConfig,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"runInputsExecutables\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForRunInputsExecutablesStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForRunInputsExecutablesStorage } from \"../../../api/generate-signed-url-for-run-inputs-executables.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n GenerateSignedUrlAbortReason,\n GenerateSignedUrlConfig,\n GenerateSignedUrlStatus,\n} from \"./types.js\";\n\nexport async function generateSignedUrlForRunInputsExecutablesStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState =\n await callGenerateSignedUrlForRunInputsExecutablesStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForTempTeamStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: Partial<GenerateSignedUrlConfig>,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"teamStorage\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForTempTeamStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForTempTeamStorage } from \"../../../api/generate-signed-url-for-team-storage.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type { GenerateSignedUrlConfig } from \"./types.js\";\n\ntype GenerateSignedUrlStatus =\n | {\n fileLocation?: string;\n playgroundFileLocation?: string;\n success: true;\n uploadUrl?: string;\n }\n | {\n abortReason: GenerateSignedUrlAbortReason;\n httpStatus?: number;\n success: false;\n };\n\nexport type GenerateSignedUrlAbortReason =\n | \"client-network-error\"\n | \"sdk-argument-validation-failed\"\n | \"400-invalid-request\"\n | \"401-invalid-credentials\"\n | \"403-forbidden\"\n | \"5XX-server-error\"\n | \"XXX-other-http-code\";\n\nexport async function generateSignedUrlForTempTeamStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState = await callGenerateSignedUrlForTempTeamStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n NotifyTerminatedEphemeralEnvironmentAbortReason,\n NotifyTerminatedEphemeralEnvironmentInput,\n NotifyTerminatedEphemeralEnvironmentResult,\n TerminatedEphemeralEnvironmentSuccessResult,\n} from \"./types.js\";\n\nexport const notifyTerminatedEphemeralEnvironment = async (\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: NotifyTerminatedEphemeralEnvironmentInput,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> => {\n const { fetch: localFetch, log } = deps;\n try {\n const response = await localFetch(\n new URL(\"/api/webhooks/environment_terminated\", apiConfig.serviceBase),\n {\n body: JSON.stringify(config),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n if (!response.ok) return handleErrorResponse(response, log);\n const { environmentId, warning } =\n (await response.json()) as TerminatedEphemeralEnvironmentSuccessResult;\n if (warning) log.warn(`\u26A0\uFE0F ${warning}`);\n return { environmentId, outcome: \"success\" };\n } catch {\n log.error(`\uD83D\uDEAB Network error from terminate_preview_environment, aborting.`);\n return {\n abortReason: \"network-error\",\n outcome: \"aborted\",\n };\n }\n};\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> {\n const status = response.status;\n let abortReason: NotifyTerminatedEphemeralEnvironmentAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status === 409) abortReason = \"409-conflict\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"notifyTerminatedEphemeralEnvironment\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\n\nimport type { PollCiGreenlightStatus } from \"./types.js\";\n\n/**\n * Build the result for a completed run\n */\nexport function buildCompletedRunResult(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): PollCiGreenlightStatus {\n if (status.greenlight)\n return { greenlightStatus: status, outcome: \"success\" };\n else return { greenlightStatus: status, outcome: \"failed\" };\n}\n", "import type { PollCiGreenlightPollConfig } from \"./types.js\";\n\n/**\n * Safe default values for polling configuration.\n * If you change these values, make sure you update the JSDoc\n * comments in the PollCiGreenlightPollConfig type.\n */\nexport const pollCiGreenlightDefaults: PollCiGreenlightPollConfig = {\n abortOnSuperseded: false,\n maxRetries: 10,\n pollTimeout: 120 * 60 * 1000, // 2 hours\n retryInterval: 10 * 1000, // 10 seconds\n runInProgressInterval: 30 * 1000, // 30 seconds\n runUnderReviewInterval: 60 * 1000, // 60 seconds\n};\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\n\nimport type { CiGreenlightBugData } from \"./ci-greenlight-bug-data.js\";\nimport { logFetchError } from \"./log.js\";\n\nexport type {\n CiGreenlightBugData,\n CiGreenlightBugDetails,\n} from \"./ci-greenlight-bug-data.js\";\n\nexport type CiGreenlightStatusBase = {\n relevantRunId: string;\n relevantRunUrl: string;\n rootRunId: string;\n rootRunUrl: string;\n};\n\nexport type CiGreenlightStatusExtended = {\n relevantRunWithBugsUrl: string;\n workflowsDisabledAfterRunCount: number;\n workflowsInRunCount: number;\n workflowsUnderInvestigationCount: number;\n};\n\n/**\n * The status of a CI greenlight run. See the API documentation here for\n * more details: https://qawolf.notion.site/1b170576efea411fa785842a71e7c99e\n */\nexport type CiGreenlightStatus = CiGreenlightStatusBase &\n (\n | ({\n greenlight: boolean;\n runStage: \"completed\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"underReview\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"initializing\";\n } & Partial<CiGreenlightStatusExtended>)\n | ({\n greenlight: false;\n /**\n * Human-readable copy explaining why the run was canceled, when the\n * server provides it.\n */\n message?: string;\n /**\n * Stable, machine-readable code for why the run was canceled, when the\n * server provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"canceled\";\n } & Partial<CiGreenlightStatusExtended>)\n );\n\nexport async function fetchCiGreenlightStatus(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n {\n runId,\n }: {\n runId: string;\n },\n { fetch: localFetch, log }: SdkDependencies,\n) {\n try {\n const resp = await localFetch(\n new URL(\n `/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,\n serviceBase,\n ),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent,\n },\n },\n );\n\n if (resp.ok) {\n const greenlightStatus = (await resp.json()) as CiGreenlightStatus;\n return {\n greenlightStatus,\n httpStatus: resp.status,\n ok: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"fetchCiGreenlightStatus\",\n response: resp,\n });\n if (resp.status === 404) {\n return {\n canRetry: true,\n errorType: \"not-found\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n if (resp.status >= 500) {\n return {\n canRetry: true,\n errorType: \"server\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n return {\n canRetry: false,\n errorType: \"client\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n } catch {\n return {\n canRetry: true,\n errorType: \"network\",\n httpStatus: 0,\n ok: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { fetchCiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { sleep } from \"../../../other.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport type {\n MakePollCiGreenlightStatusIteratorParams,\n PollCiGreenlightIteration,\n} from \"./types.js\";\n\n/**\n * Creates an async generator that yields CI greenlight status updates or abort notifications.\n *\n * This low-level API gives you full control over the polling loop, allowing you to:\n * - Inspect status after each fetch\n * - Break out of the loop based on custom criteria\n * - Add custom logging or side effects\n * - Handle abort conditions without exceptions\n *\n * The iterator yields a discriminated union with `isAborted` property:\n * - `isAborted: false` - Normal status update with run information\n * - `isAborted: true` - Terminal condition (timeout, error, canceled, etc.)\n *\n * Note: This function does not throw errors. All error conditions are yielded as\n * abort results that you must check and handle.\n *\n * @example\n * ```typescript\n * const greenlightIterator = makePollCiGreenlightStatusIterator({ runId: \"my-run-id\" });\n *\n * for await (const lastPoll of greenlightIterator) {\n * // Check for abort conditions first\n * if (lastPoll.isAborted) {\n * console.error(`Aborted: ${lastPoll.abortReason}`);\n * process.exit(1);\n * }\n *\n * // Handle normal status updates\n * const { status } = lastPoll;\n * console.log(`Current stage: ${status.runStage}`);\n *\n * // Exit with error if run reached a terminal stage without greenlight\n * if (lastPoll.isFailedTerminalStage) {\n * process.exit(1);\n * }\n * }\n * ```\n *\n */\nexport async function* makePollCiGreenlightStatusIterator(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n { runId, ...pollConfig }: MakePollCiGreenlightStatusIteratorParams,\n): AsyncGenerator<PollCiGreenlightIteration, void, unknown> {\n const { log } = deps;\n\n const {\n maxRetries = pollCiGreenlightDefaults.maxRetries,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n retryInterval = pollCiGreenlightDefaults.retryInterval,\n runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,\n runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval,\n } = pollConfig;\n\n let retries = 0;\n let previousStatus: CiGreenlightStatus | undefined = undefined;\n const startedAt = Date.now();\n\n while (Date.now() - startedAt <= pollTimeout) {\n const responseState = await fetchCiGreenlightStatus(\n apiConfig,\n { runId },\n deps,\n );\n\n const elapsedMs = Date.now() - startedAt;\n\n if (!responseState.ok && !responseState.canRetry) {\n yield {\n abortReason: \"4XX-client-error\",\n elapsedMs,\n httpStatus: responseState.httpStatus,\n isAborted: true,\n };\n return;\n }\n\n if (!responseState.ok) {\n retries += 1;\n const { errorType, httpStatus } = responseState;\n if (retries > maxRetries) {\n switch (errorType) {\n case \"network\":\n yield {\n abortReason: \"network-error\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n break;\n case \"not-found\":\n yield {\n abortReason: \"404-run-not-found\",\n elapsedMs,\n httpStatus: httpStatus ?? 404,\n isAborted: true,\n };\n break;\n case \"server\":\n yield {\n abortReason: \"5XX-server-error\",\n elapsedMs,\n httpStatus: httpStatus ?? 500,\n isAborted: true,\n };\n break;\n default:\n throw Error(`Unexpected error type: ${errorType satisfies never}`);\n }\n return;\n }\n\n const retryLabel = `${\n httpStatus ? ` (status ${httpStatus})` : \"\"\n }, will try again... (${retries}/${maxRetries})`;\n\n if (errorType === \"network\") log.warn(`\u274C Network error${retryLabel}`);\n else if (errorType === \"not-found\")\n log.info(`\u23F3 Run not found${retryLabel}`);\n else if (errorType === \"server\") log.warn(`\u274C Server error${retryLabel}`);\n\n await sleep(retryInterval);\n continue;\n }\n\n // Success - reset retry counter\n retries = 0;\n const { greenlightStatus } = responseState;\n const stageChanged =\n !previousStatus || previousStatus.runStage !== greenlightStatus.runStage;\n\n // Determine if this is a failed terminal stage\n const isFailedTerminalStage =\n greenlightStatus.runStage === \"canceled\" ||\n (greenlightStatus.runStage === \"completed\" &&\n greenlightStatus.greenlight === false);\n\n yield {\n elapsedMs,\n isAborted: false,\n isFailedTerminalStage,\n previousStatus,\n stageChanged,\n status: greenlightStatus,\n };\n\n // Update previous status for next iteration\n previousStatus = greenlightStatus;\n\n switch (greenlightStatus.runStage) {\n case \"canceled\": {\n yield {\n abortReason: \"run-canceled\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n }\n case \"completed\":\n return;\n case \"initializing\":\n await sleep(runInProgressInterval);\n break;\n case \"underReview\":\n await sleep(runUnderReviewInterval);\n break;\n default:\n throw Error(\n `Unexpected run stage: ${greenlightStatus satisfies never}`,\n );\n }\n }\n\n // Timeout\n yield {\n abortReason: \"poll-timed-out\",\n elapsedMs: Date.now() - startedAt,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { pluralize } from \"../../../other.js\";\n\n/**\n * Build log message for successful completed run\n */\nexport function buildSuccessLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { nonBlockingBugsCount, relevantRunUrl } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n return `\u2705 Run passed and no blocking bugs found${\n nonBlockingBugsCount > 0\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )} found`\n : \"\"\n }.\\n${urlInfo}`;\n}\n\n/**\n * Build log message for failed completed run\n */\nexport function buildFailedLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const {\n blockingBugsCount,\n nonBlockingBugsCount,\n relevantRunWithBugsUrl,\n reproducedBugs,\n } = status;\n\n const blockingBugUrls = reproducedBugs\n .filter((bug) => bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n const nonBlockingBugUrls = reproducedBugs\n .filter((bug) => !bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n\n const blockingBugList = blockingBugUrls.map((url) => `\\n\u2022 ${url}`).join(\"\");\n const nonBlockingBugList = nonBlockingBugUrls\n .map((url) => `\\n\u2022 ${url}`)\n .join(\"\");\n const bugsListInText = `${\n blockingBugUrls.length > 0 ? `\\nBLOCKING BUGS:${blockingBugList}` : \"\"\n }${\n nonBlockingBugUrls.length > 0\n ? `\\nNON BLOCKING BUGS:${nonBlockingBugList}`\n : \"\"\n }`;\n\n return (\n `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(\n blockingBugsCount,\n )} found${\n nonBlockingBugsCount\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )}`\n : \"\"\n }.\\nSee ${relevantRunWithBugsUrl}\\n` +\n \"You may review the priority of certain bugs to mark these non-blocking and retry the job.\\n\" +\n bugsListInText\n );\n}\n\n/**\n * Build log message for superseded run (aborting)\n */\nexport function buildSupersededAbortLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `\u274C Aborting due to superseded run (option 'abortOnSuperseded' is enabled).${supersedingDetails}`;\n}\n\n/**\n * Build log message for superseded run (continuing)\n */\nexport function buildSupersededContinueLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `Root run was superseded:${supersedingDetails}`;\n}\n\n/**\n * Build log messages for different run stages\n */\nexport function buildRunStageLogMessage(\n runStage: CiGreenlightStatus[\"runStage\"],\n relevantRunUrl: string,\n): string {\n const urlInfo = `See ${relevantRunUrl}`;\n\n switch (runStage) {\n case \"canceled\":\n return `\uD83D\uDEAB Run was canceled. Aborting... Please contact support.\\n${urlInfo}`;\n case \"initializing\":\n return `\u23F3 Run is in progress... ${urlInfo}`;\n case \"underReview\":\n return `\uD83D\uDD75\uFE0F Run is under review... ${urlInfo}`;\n case \"completed\":\n // Completed is handled separately by buildSuccessLogMessage/buildFailedLogMessage\n throw Error(\n \"buildRunStageLogMessage should not be called for completed stage\",\n );\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n}\n", "import type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n PollCiGreenlightIteratorHttpAborted,\n PollCiGreenlightIteratorNonHttpAborted,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * Handles aborted iterations from the CI greenlight poll iterator\n * and converts them to appropriate result objects with logging\n */\nexport function mapIteratorAbortToGreenlightStatus(\n iteration:\n | PollCiGreenlightIteratorHttpAborted\n | PollCiGreenlightIteratorNonHttpAborted,\n pollTimeout: number,\n deps: SdkDependencies,\n): PollCiGreenlightStatus {\n const { log } = deps;\n const { abortReason, httpStatus } = iteration;\n\n switch (abortReason) {\n case \"4XX-client-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"5XX-server-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"404-run-not-found\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"network-error\":\n log.error(`\uD83D\uDEAB Unrecoverable network error from CI greenlight, aborting.`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"poll-timed-out\":\n log.warn(`\u274C Poll timed out after ${pollTimeout / 1000}s`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"run-canceled\":\n log.info(`Run was canceled`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"XXX-other-http-code\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n default:\n throw Error(`Unexpected abort reason: ${abortReason satisfies never}`);\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { buildCompletedRunResult } from \"./buildCompletedRunResult.js\";\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./iterator.js\";\nimport {\n buildFailedLogMessage,\n buildRunStageLogMessage,\n buildSuccessLogMessage,\n buildSupersededAbortLogMessage,\n buildSupersededContinueLogMessage,\n} from \"./logging.js\";\nimport { mapIteratorAbortToGreenlightStatus } from \"./mapIteratorAbortToGreenlightStatus.js\";\nimport type {\n PollCiGreenlightParams,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\nexport async function pollCiGreenlightStatus(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n onRunStageChanged = () => undefined,\n runId,\n ...pollConfig\n }: PollCiGreenlightParams,\n): Promise<PollCiGreenlightStatus> {\n const { log } = deps;\n const {\n abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n } = pollConfig;\n\n const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {\n runId,\n ...pollConfig,\n });\n\n for await (const lastPoll of iterator) {\n if (lastPoll.isAborted)\n return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);\n\n // Handle status iterations\n const { previousStatus, stageChanged, status } = lastPoll;\n\n // Call onRunStageChanged callback when stage changes\n if (stageChanged) {\n try {\n await onRunStageChanged(status, previousStatus);\n } catch (e) {\n log.error(`Error in onRunStageChanged callback`, e);\n }\n }\n\n const { relevantRunId, relevantRunUrl, rootRunId, rootRunUrl, runStage } =\n status;\n\n // Superseded run handling\n const isSuperseded = rootRunId !== relevantRunId;\n const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;\n if (shouldAbortOnSuperseded) {\n const message = buildSupersededAbortLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.warn(message);\n return {\n abortReason: \"superseded-run\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n if (isSuperseded) {\n const message = buildSupersededContinueLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.info(message);\n }\n\n switch (runStage) {\n case \"canceled\":\n case \"initializing\":\n case \"underReview\": {\n log.info(buildRunStageLogMessage(runStage, relevantRunUrl));\n break;\n }\n case \"completed\": {\n const result = buildCompletedRunResult(status);\n switch (result.outcome) {\n case \"aborted\": {\n break;\n }\n case \"failed\": {\n const message = buildFailedLogMessage(status);\n log.warn(message);\n break;\n }\n case \"success\": {\n const message = buildSuccessLogMessage(status);\n log.info(message);\n break;\n }\n default:\n throw Error(`Unexpected outcome: ${result satisfies never}`);\n }\n return result;\n }\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n }\n\n // This should never be reached as the iterator handles timeout\n throw Error(\"Iterator ended unexpectedly\");\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport { buildFetchWithTimeout } from \"../other.js\";\n\nimport { defaultFetch } from \"./defaults/fetch.js\";\nimport { defaultLogDriver } from \"./defaults/log.js\";\nimport { defaultServiceBase } from \"./defaults/serviceBase.js\";\nimport { defaultUserAgent } from \"./defaults/userAgent.js\";\nimport type { SdkDependencies } from \"./dependencies.js\";\nimport { attemptNotifyDeploy } from \"./domain/attemptDeploy/index.js\";\nimport { generateSignedUrlForRunInputsExecutablesStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.js\";\nimport { generateSignedUrlForTempTeamStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-team-storage.js\";\nimport { notifyTerminatedEphemeralEnvironment } from \"./domain/notifyTerminatedEphemeralEnvironment/index.js\";\nimport { pollCiGreenlightStatus } from \"./domain/pollCiGreenlight/index.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./domain/pollCiGreenlight/iterator.js\";\n\nexport function makeQaWolfSdk(\n {\n apiKey,\n serviceBase = defaultServiceBase,\n userAgent = defaultUserAgent,\n }: {\n apiKey: string;\n serviceBase?: string;\n userAgent?: string;\n },\n {\n fetch = defaultFetch,\n log = defaultLogDriver,\n }: Partial<SdkDependencies> = {},\n) {\n if (typeof fetch !== \"function\") {\n throw Error(\n `QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.\nWe recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`,\n );\n }\n\n const deps: SdkDependencies = {\n // Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.\n // The increased timeout helps avoid edge cases where we need to search for a commit against multiple\n // code hosting service repositories as a fallback when not finding the repository based on organization/name.\n fetch: buildFetchWithTimeout(fetch, 120000),\n log,\n };\n const apiConfig: ApiConfig = { apiKey, serviceBase, userAgent };\n return {\n attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),\n generateSignedUrlForRunInputsExecutablesStorage:\n generateSignedUrlForRunInputsExecutablesStorage.bind(\n null,\n deps,\n apiConfig,\n ),\n generateSignedUrlForTempTeamStorage:\n generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),\n makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(\n null,\n deps,\n apiConfig,\n ),\n notifyTerminatedEphemeralEnvironment:\n notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),\n pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig),\n };\n}\n\nexport type * from \"./domain/attemptDeploy/index.js\";\nexport type * from \"./domain/generateSignedUrls/types.js\";\nexport type * from \"./domain/notifyTerminatedEphemeralEnvironment/types.js\";\nexport type * from \"./domain/pollCiGreenlight/types.js\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { FetchDriver } from \"./sdk/dependencies.js\";\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function pluralize(count: number) {\n return count === 1 ? \"\" : \"s\";\n}\n\nexport function getBackoffMs(\n attemptNumber: number,\n minWaitMs = 1000,\n maxWaitMs = 10000,\n): number {\n return Math.min(maxWaitMs, minWaitMs * 1.2 ** attemptNumber);\n}\n\nexport const buildFetchWithTimeout =\n (fetch: FetchDriver, defaultTimeoutMs: number) =>\n async (...args: Parameters<FetchDriver>) => {\n // Allow signal to be overridden by the caller\n const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);\n\n return fetch(args[0], { ...args[1], signal });\n };\n", "export const defaultFetch = globalThis.fetch;\n", "import type { LogDriver } from \"../dependencies.js\";\n\nexport const defaultLogDriver: LogDriver = {\n error(message, error) {\n console.error(message, error);\n },\n info(message) {\n console.log(message);\n },\n warn(message) {\n console.warn(message);\n },\n};\n", "export const defaultServiceBase = \"https://app.qawolf.com/\";\n", "{\n \"name\": \"@qawolf/ci-sdk\",\n \"version\": \"2.7.0\",\n \"private\": false,\n \"description\": \"A simple SDK for interacting with QAWolf in CI scripts.\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"author\": \"Jules Sam. Randolph<jules@qawolf.com>\",\n \"files\": [\n \"/dist\",\n \"/README.md\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"platform-builder --config platformBuilder.config.ts --config platformBuilder.cjs.config.ts\",\n \"lint:ci\": \"npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT\",\n \"lint:dev\": \"npm run lint:first-half\",\n \"lint:first-half\": \"eslint . --fix --quiet && oxfmt --write .\",\n \"lint:second-half\": \"dpdm --exit-code circular:1 --no-tree --no-warning --transform --include='.*' --exclude='/(dist|node_modules)/' '**/*'\",\n \"prepublishOnly\": \"nx run ci-sdk:build\",\n \"test\": \"NODE_OPTIONS=\\\"--experimental-vm-modules\\\" NODE_NO_WARNINGS=1 jest\",\n \"tsc:check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@qawolf/ci-utils\": \"^1.1.2\",\n \"@sinonjs/fake-timers\": \"^10.3.0\",\n \"tslib\": \"^2.6.2\"\n },\n \"devDependencies\": {\n \"@qawolf/platform-builder\": \"^1.2.2\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=20\"\n }\n}\n", "import packageJson from \"../../../../package.json\" with { type: \"json\" };\n\nexport const defaultUserAgent = `ci-sdk/${packageJson.version}`;\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nexport async function logFetchError({\n log,\n methodName,\n response,\n}: {\n log: LogDriver;\n methodName: string;\n response: Response;\n}) {\n if (response.ok) return;\n\n const { eventId, failureMessage } = await (async () => {\n try {\n const body = (await response.json().catch(() => response.text())) as\n | Record<string, unknown>\n | string;\n if (typeof body === \"object\" && body !== null) {\n return {\n eventId: body.eventId,\n failureMessage: body.failureMessage,\n };\n }\n // If body is not an object (i.e., it's the text from catch)\n return {\n eventId: undefined,\n failureMessage: body,\n };\n } catch {\n // If both parsing attempts somehow fail\n return {\n eventId: undefined,\n failureMessage: undefined,\n };\n }\n })();\n\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = failureMessage ? `: ${failureMessage}` : \"\";\n\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n\n log.error(\n `\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n}\n", "import type { LogDriver } from \"../../dependencies.js\";\n\nimport type { DeployStatus, NotifyDeployStatus } from \"./types.js\";\n\nexport async function handleSuccessResponse(\n data: DeployStatus,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const { environment, results } = data;\n const skippedTriggers = data.skippedTriggers ?? [];\n const skippedDeployment = data.skippedDeployment;\n const isPreviewDeployment = environment && !environment.isStatic;\n\n if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);\n\n if (environment) {\n const logPrefix = environment.isStatic\n ? \"Static environment\"\n : \"Preview environment\";\n log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);\n }\n\n // No suites were created for this deployment.\n if (results.length === 0) {\n const skipMessages = [\n ...skippedTriggers.map((trigger) => trigger.message),\n ...(skippedDeployment ? [skippedDeployment.message] : []),\n ];\n const skipDetail =\n skipMessages.length > 0 ? ` ${skipMessages.join(\" \")}` : \"\";\n\n // Preview deployments legitimately often produce no run; keep the success\n // outcome but surface any skip reason so it is not silently dropped.\n if (isPreviewDeployment) {\n log.info(\n `\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: undefined,\n };\n }\n\n // A trigger matched but could not run (e.g. environment still syncing).\n // Only a backend that still sends skipped_triggers reaches this arm. Current\n // backends omit the field, so those responses bypass it and fall to the\n // generic \"no trigger matched\" warning below even when a trigger did match.\n if (skippedTriggers.length > 0) {\n log.error(`\uD83D\uDEAB No run was created for this deployment.${skipDetail}`);\n return {\n failReason: \"trigger-skipped\",\n outcome: \"failed\",\n skippedTriggers,\n };\n }\n\n log.warn(\n skippedDeployment\n ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}`\n : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`,\n );\n return {\n outcome: \"skipped\",\n skippedDeployment,\n };\n }\n\n // If there are results, environment must be defined\n if (!environment) {\n log.error(`\uD83D\uDEAB No environment matched the request. Please contact support.`);\n return { failReason: \"no-environment\", outcome: \"failed\" };\n }\n\n // A result arm this SDK version does not recognize (newer backend). We cannot\n // classify the outcome, so surface it as a failure rather than guessing.\n const unrecognizedResult = results.find((result) => \"unrecognized\" in result);\n if (unrecognizedResult) {\n log.error(\n `\uD83D\uDEAB The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`,\n );\n return { failReason: \"unknown-result\", outcome: \"failed\" };\n }\n\n const failedTrigger = results.find((result) => \"failureReason\" in result);\n if (failedTrigger) {\n // Prefer the customer-facing message; older backends send only the internal\n // reason, which is all we can show in that case.\n log.error(\n `\uD83D\uDEAB Run could not be created. Reason: \"${failedTrigger.failureMessage ?? failedTrigger.failureReason}\". Please contact support.`,\n );\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n\n const duplicateSuite = results.find((result) => \"duplicateSuiteId\" in result);\n if (duplicateSuite) {\n log.info(\n `\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: duplicateSuite.duplicateSuiteId,\n };\n }\n\n const successfulTrigger = results.find(\n (result) => \"createdSuiteId\" in result,\n );\n if (!successfulTrigger) {\n // results is non-empty here, so triggers did match \u2014 this is not the\n // deterministic no-trigger-match skip. Reaching this point means the\n // response carried results we could not turn into a run, so it is an\n // unexpected failure rather than a skip.\n log.error(`\uD83D\uDEAB Run could not be created. Please contact support.`);\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n log.info(\n `\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: successfulTrigger.createdSuiteId,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\nimport type { DeployStatus, DeploySuccessSuiteResult } from \"./types.js\";\n\n// An arm is classified by the outcome the backend declared, not by which keys\n// happen to be present.\nfunction mapSuiteResult(\n result: DeploySuccessWireResponse[\"results\"][number],\n): DeploySuccessSuiteResult {\n switch (result.outcome) {\n case \"created\":\n return {\n createdSuiteId: result.created_suite_id,\n triggerId: result.trigger_id,\n };\n case \"failed\":\n return {\n failureCode: result.failure_code,\n failureMessage: result.failure_message,\n failureReason: result.failure_reason,\n triggerId: result.trigger_id,\n };\n case \"skipped\":\n return {\n duplicateSuiteId: result.duplicate_suite_id,\n skipReason: result.skip_reason,\n triggerId: result.trigger_id,\n };\n default:\n // An outcome added by a newer backend: surface it explicitly rather than\n // forcing it into one of the known shapes.\n return { triggerId: result.trigger_id, unrecognized: true };\n }\n}\n\n// The deploy_success success body is the SDK's only snake_case wire shape; this\n// is the single place that renames it to the camelCase `DeployStatus` used\n// everywhere downstream.\nexport function mapDeploySuccessResponse(\n wire: DeploySuccessWireResponse,\n): DeployStatus {\n return {\n environment: wire.environment,\n results: wire.results.map(mapSuiteResult),\n skippedDeployment: wire.skipped_deployment && {\n message: wire.skipped_deployment.message,\n reason: wire.skipped_deployment.reason,\n },\n skippedTriggers: wire.skipped_triggers?.map((trigger) => ({\n environmentId: trigger.environment_id,\n message: trigger.message,\n reason: trigger.reason,\n triggerId: trigger.trigger_id,\n })),\n warning: wire.warning,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n // Arrays are objects too; a deploy_success body or any of its parts must be a\n // plain object, never an array. (JSON cannot produce other non-plain objects\n // such as Date or Map, so excluding arrays is sufficient here.)\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === \"string\";\n}\n\n// Validates each arm against the `outcome` the backend declared, matching how\n// mapSuiteResult discriminates. Keying both off the same field is what keeps an\n// outcome-based mapper from reading a missing payload field as undefined. It\n// also tightens `{ outcome: \"failed\" }` with no `failure_reason`: key-presence\n// classified that as unrecognized, and it is now an invalid body.\nfunction isWireSuiteResult(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.trigger_id !== \"string\") return false;\n if (!isOptionalString(value.outcome)) return false;\n switch (value.outcome) {\n case \"created\":\n return typeof value.created_suite_id === \"string\";\n case \"failed\":\n return (\n typeof value.failure_reason === \"string\" &&\n isOptionalString(value.failure_code) &&\n isOptionalString(value.failure_message)\n );\n case \"skipped\":\n return (\n typeof value.duplicate_suite_id === \"string\" &&\n typeof value.skip_reason === \"string\"\n );\n default:\n // An outcome this SDK version does not know, or none at all. Accept it so\n // an older SDK does not reject the whole response; mapSuiteResult maps it\n // to an explicit unrecognized outcome.\n return true;\n }\n}\n\nfunction isEnvironment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.isStatic !== \"boolean\") return false;\n if (value.alias !== undefined && typeof value.alias !== \"string\")\n return false;\n return true;\n}\n\nfunction isSkippedDeployment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return typeof value.message === \"string\" && typeof value.reason === \"string\";\n}\n\nfunction isSkippedTrigger(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return (\n typeof value.environment_id === \"string\" &&\n typeof value.message === \"string\" &&\n typeof value.reason === \"string\" &&\n typeof value.trigger_id === \"string\"\n );\n}\n\nfunction isDeploySuccessWireResponse(\n value: unknown,\n): value is DeploySuccessWireResponse {\n if (!isRecord(value)) return false;\n if (value.environment !== undefined && !isEnvironment(value.environment))\n return false;\n\n if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))\n return false;\n\n if (\n value.skipped_deployment !== undefined &&\n !isSkippedDeployment(value.skipped_deployment)\n )\n return false;\n\n if (\n value.skipped_triggers !== undefined &&\n (!Array.isArray(value.skipped_triggers) ||\n !value.skipped_triggers.every(isSkippedTrigger))\n )\n return false;\n\n if (!isOptionalString(value.warning)) return false;\n\n return true;\n}\n\n// Validate the deploy_success success body at runtime instead of trusting a\n// cast. `environment` is required to be present-or-explicitly-undefined; the\n// two skip fields are optional (older servers omit them).\nexport function parseDeploySuccessWireResponse(\n value: unknown,\n): DeploySuccessWireResponse | \"invalid\" {\n return isDeploySuccessWireResponse(value) ? value : \"invalid\";\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport { handleSuccessResponse } from \"./handleSuccessResponse.js\";\nimport { mapDeploySuccessResponse } from \"./mapDeploySuccessResponse.js\";\nimport { parseDeploySuccessWireResponse } from \"./parseDeploySuccessWireResponse.js\";\nimport type {\n AttemptDeployHttpAbortReason,\n DeployConfig,\n NotifyDeployStatus,\n} from \"./types.js\";\n\nexport async function attemptNotifyDeploy(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: Partial<DeployConfig>,\n): Promise<NotifyDeployStatus> {\n const { fetch: localFetch, log } = deps;\n\n let response: Response;\n let bodyText: string;\n try {\n response = await localFetch(\n new URL(\"/api/webhooks/deploy_success\", apiConfig.serviceBase),\n {\n body: JSON.stringify({\n branch: config.branch,\n commit_url: config.commitUrl,\n deduplication_key: config.deduplicationKey,\n deployment_type: config.deploymentType,\n deployment_url: config.deploymentUrl,\n ...(\"ephemeralEnvironment\" in config\n ? {\n ephemeral_environment: config.ephemeralEnvironment,\n }\n : \"hostingService\" in config && {\n hosting_service: config.hostingService,\n merge_request_number:\n config.hostingService === \"GitLab\"\n ? config.mergeRequestNumber\n : undefined,\n pull_request_number:\n config.hostingService === \"GitHub\"\n ? config.pullRequestNumber\n : undefined,\n repository: config.repository,\n }),\n sha: config.sha,\n variables: config.variables,\n workspaceId: config.workspaceId,\n }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n // Override default timeout to 5 minutes. This gives extra room\n // for both (1) waiting for reconciliation (2) creating the run.\n signal: AbortSignal.timeout(5 * 60 * 1000),\n },\n );\n\n if (!response.ok) return handleErrorResponse(response, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from deploy_success, aborting.`);\n return {\n abortReason: \"network-error\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n\n let rawBody: unknown;\n try {\n rawBody = JSON.parse(bodyText);\n } catch {\n return abortInvalidResponseBody(log, \"the response body was not JSON\");\n }\n\n const wire = parseDeploySuccessWireResponse(rawBody);\n if (wire === \"invalid\") {\n return abortInvalidResponseBody(\n log,\n \"the response body did not match the expected shape\",\n );\n }\n\n const data = mapDeploySuccessResponse(wire);\n return handleSuccessResponse(data, log);\n}\n\nfunction abortInvalidResponseBody(\n log: LogDriver,\n detail: string,\n): NotifyDeployStatus {\n log.error(`\uD83D\uDEAB Invalid response from deploy_success (${detail}), aborting.`);\n return {\n abortReason: \"invalid-response-body\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n}\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const status = response.status;\n let abortReason: AttemptDeployHttpAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"attemptNotifyDeploy\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "const signedUrlPaths = {\n runInputsExecutables: \"/api/v0/run-inputs-executables-signed-urls\",\n teamStorage: \"/api/v0/team-storage-signed-url\",\n} as const;\n\nexport function buildSignedUrl({\n destinationFilePath,\n endpoint,\n serviceBase,\n workspaceId,\n}: {\n destinationFilePath: string | undefined;\n endpoint: keyof typeof signedUrlPaths;\n serviceBase: string;\n workspaceId: string | undefined;\n}): URL {\n const url = new URL(signedUrlPaths[endpoint], serviceBase);\n if (destinationFilePath !== undefined)\n url.searchParams.set(\"file\", destinationFilePath);\n if (workspaceId !== undefined)\n url.searchParams.set(\"workspaceId\", workspaceId);\n return url;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForRunInputsExecutablesStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: GenerateSignedUrlConfig,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"runInputsExecutables\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForRunInputsExecutablesStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForRunInputsExecutablesStorage } from \"../../../api/generate-signed-url-for-run-inputs-executables.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n GenerateSignedUrlAbortReason,\n GenerateSignedUrlConfig,\n GenerateSignedUrlStatus,\n} from \"./types.js\";\n\nexport async function generateSignedUrlForRunInputsExecutablesStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState =\n await callGenerateSignedUrlForRunInputsExecutablesStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForTempTeamStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: Partial<GenerateSignedUrlConfig>,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"teamStorage\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForTempTeamStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForTempTeamStorage } from \"../../../api/generate-signed-url-for-team-storage.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type { GenerateSignedUrlConfig } from \"./types.js\";\n\ntype GenerateSignedUrlStatus =\n | {\n fileLocation?: string;\n interactiveRunFileLocation?: string;\n /** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */\n playgroundFileLocation?: string;\n success: true;\n uploadUrl?: string;\n }\n | {\n abortReason: GenerateSignedUrlAbortReason;\n httpStatus?: number;\n success: false;\n };\n\nexport type GenerateSignedUrlAbortReason =\n | \"client-network-error\"\n | \"sdk-argument-validation-failed\"\n | \"400-invalid-request\"\n | \"401-invalid-credentials\"\n | \"403-forbidden\"\n | \"5XX-server-error\"\n | \"XXX-other-http-code\";\n\nexport async function generateSignedUrlForTempTeamStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState = await callGenerateSignedUrlForTempTeamStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n NotifyTerminatedEphemeralEnvironmentAbortReason,\n NotifyTerminatedEphemeralEnvironmentInput,\n NotifyTerminatedEphemeralEnvironmentResult,\n TerminatedEphemeralEnvironmentSuccessResult,\n} from \"./types.js\";\n\nexport const notifyTerminatedEphemeralEnvironment = async (\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: NotifyTerminatedEphemeralEnvironmentInput,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> => {\n const { fetch: localFetch, log } = deps;\n try {\n const response = await localFetch(\n new URL(\"/api/webhooks/environment_terminated\", apiConfig.serviceBase),\n {\n body: JSON.stringify(config),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n if (!response.ok) return handleErrorResponse(response, log);\n const { environmentId, warning } =\n (await response.json()) as TerminatedEphemeralEnvironmentSuccessResult;\n if (warning) log.warn(`\u26A0\uFE0F ${warning}`);\n return { environmentId, outcome: \"success\" };\n } catch {\n log.error(`\uD83D\uDEAB Network error from terminate_preview_environment, aborting.`);\n return {\n abortReason: \"network-error\",\n outcome: \"aborted\",\n };\n }\n};\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> {\n const status = response.status;\n let abortReason: NotifyTerminatedEphemeralEnvironmentAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status === 409) abortReason = \"409-conflict\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"notifyTerminatedEphemeralEnvironment\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\n\nimport type { PollCiGreenlightStatus } from \"./types.js\";\n\n/**\n * Build the result for a completed run\n */\nexport function buildCompletedRunResult(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): PollCiGreenlightStatus {\n if (status.greenlight)\n return { greenlightStatus: status, outcome: \"success\" };\n else return { greenlightStatus: status, outcome: \"failed\" };\n}\n", "import type { PollCiGreenlightPollConfig } from \"./types.js\";\n\n/**\n * Safe default values for polling configuration.\n * If you change these values, make sure you update the JSDoc\n * comments in the PollCiGreenlightPollConfig type.\n */\nexport const pollCiGreenlightDefaults: PollCiGreenlightPollConfig = {\n abortOnSuperseded: false,\n maxRetries: 10,\n pollTimeout: 120 * 60 * 1000, // 2 hours\n retryInterval: 10 * 1000, // 10 seconds\n runInProgressInterval: 30 * 1000, // 30 seconds\n runUnderReviewInterval: 60 * 1000, // 60 seconds\n};\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\n\nimport type { CiGreenlightBugData } from \"./ci-greenlight-bug-data.js\";\nimport { logFetchError } from \"./log.js\";\n\nexport type {\n CiGreenlightBugData,\n CiGreenlightBugDetails,\n} from \"./ci-greenlight-bug-data.js\";\n\nexport type CiGreenlightStatusBase = {\n relevantRunId: string;\n relevantRunUrl: string;\n rootRunId: string;\n rootRunUrl: string;\n};\n\nexport type CiGreenlightStatusExtended = {\n relevantRunWithBugsUrl: string;\n workflowsDisabledAfterRunCount: number;\n workflowsInRunCount: number;\n workflowsUnderInvestigationCount: number;\n};\n\n/**\n * The status of a CI greenlight run. See the API documentation here for\n * more details: https://qawolf.notion.site/1b170576efea411fa785842a71e7c99e\n */\nexport type CiGreenlightStatus = CiGreenlightStatusBase &\n (\n | ({\n greenlight: boolean;\n runStage: \"completed\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"underReview\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"initializing\";\n } & Partial<CiGreenlightStatusExtended>)\n | ({\n greenlight: false;\n /**\n * Human-readable copy explaining why the run was canceled, when the\n * server provides it.\n */\n message?: string;\n /**\n * Stable, machine-readable code for why the run was canceled, when the\n * server provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"canceled\";\n } & Partial<CiGreenlightStatusExtended>)\n );\n\nexport async function fetchCiGreenlightStatus(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n {\n runId,\n }: {\n runId: string;\n },\n { fetch: localFetch, log }: SdkDependencies,\n) {\n try {\n const resp = await localFetch(\n new URL(\n `/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,\n serviceBase,\n ),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent,\n },\n },\n );\n\n if (resp.ok) {\n const greenlightStatus = (await resp.json()) as CiGreenlightStatus;\n return {\n greenlightStatus,\n httpStatus: resp.status,\n ok: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"fetchCiGreenlightStatus\",\n response: resp,\n });\n if (resp.status === 404) {\n return {\n canRetry: true,\n errorType: \"not-found\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n if (resp.status >= 500) {\n return {\n canRetry: true,\n errorType: \"server\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n return {\n canRetry: false,\n errorType: \"client\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n } catch {\n return {\n canRetry: true,\n errorType: \"network\",\n httpStatus: 0,\n ok: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { fetchCiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { sleep } from \"../../../other.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport type {\n MakePollCiGreenlightStatusIteratorParams,\n PollCiGreenlightIteration,\n} from \"./types.js\";\n\n/**\n * Creates an async generator that yields CI greenlight status updates or abort notifications.\n *\n * This low-level API gives you full control over the polling loop, allowing you to:\n * - Inspect status after each fetch\n * - Break out of the loop based on custom criteria\n * - Add custom logging or side effects\n * - Handle abort conditions without exceptions\n *\n * The iterator yields a discriminated union with `isAborted` property:\n * - `isAborted: false` - Normal status update with run information\n * - `isAborted: true` - Terminal condition (timeout, error, canceled, etc.)\n *\n * Note: This function does not throw errors. All error conditions are yielded as\n * abort results that you must check and handle.\n *\n * @example\n * ```typescript\n * const greenlightIterator = makePollCiGreenlightStatusIterator({ runId: \"my-run-id\" });\n *\n * for await (const lastPoll of greenlightIterator) {\n * // Check for abort conditions first\n * if (lastPoll.isAborted) {\n * console.error(`Aborted: ${lastPoll.abortReason}`);\n * process.exit(1);\n * }\n *\n * // Handle normal status updates\n * const { status } = lastPoll;\n * console.log(`Current stage: ${status.runStage}`);\n *\n * // Exit with error if run reached a terminal stage without greenlight\n * if (lastPoll.isFailedTerminalStage) {\n * process.exit(1);\n * }\n * }\n * ```\n *\n */\nexport async function* makePollCiGreenlightStatusIterator(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n { runId, ...pollConfig }: MakePollCiGreenlightStatusIteratorParams,\n): AsyncGenerator<PollCiGreenlightIteration, void, unknown> {\n const { log } = deps;\n\n const {\n maxRetries = pollCiGreenlightDefaults.maxRetries,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n retryInterval = pollCiGreenlightDefaults.retryInterval,\n runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,\n runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval,\n } = pollConfig;\n\n let retries = 0;\n let previousStatus: CiGreenlightStatus | undefined = undefined;\n const startedAt = Date.now();\n\n while (Date.now() - startedAt <= pollTimeout) {\n const responseState = await fetchCiGreenlightStatus(\n apiConfig,\n { runId },\n deps,\n );\n\n const elapsedMs = Date.now() - startedAt;\n\n if (!responseState.ok && !responseState.canRetry) {\n yield {\n abortReason: \"4XX-client-error\",\n elapsedMs,\n httpStatus: responseState.httpStatus,\n isAborted: true,\n };\n return;\n }\n\n if (!responseState.ok) {\n retries += 1;\n const { errorType, httpStatus } = responseState;\n if (retries > maxRetries) {\n switch (errorType) {\n case \"network\":\n yield {\n abortReason: \"network-error\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n break;\n case \"not-found\":\n yield {\n abortReason: \"404-run-not-found\",\n elapsedMs,\n httpStatus: httpStatus ?? 404,\n isAborted: true,\n };\n break;\n case \"server\":\n yield {\n abortReason: \"5XX-server-error\",\n elapsedMs,\n httpStatus: httpStatus ?? 500,\n isAborted: true,\n };\n break;\n default:\n throw Error(`Unexpected error type: ${errorType satisfies never}`);\n }\n return;\n }\n\n const retryLabel = `${\n httpStatus ? ` (status ${httpStatus})` : \"\"\n }, will try again... (${retries}/${maxRetries})`;\n\n if (errorType === \"network\") log.warn(`\u274C Network error${retryLabel}`);\n else if (errorType === \"not-found\")\n log.info(`\u23F3 Run not found${retryLabel}`);\n else if (errorType === \"server\") log.warn(`\u274C Server error${retryLabel}`);\n\n await sleep(retryInterval);\n continue;\n }\n\n // Success - reset retry counter\n retries = 0;\n const { greenlightStatus } = responseState;\n const stageChanged =\n !previousStatus || previousStatus.runStage !== greenlightStatus.runStage;\n\n // Determine if this is a failed terminal stage\n const isFailedTerminalStage =\n greenlightStatus.runStage === \"canceled\" ||\n (greenlightStatus.runStage === \"completed\" &&\n greenlightStatus.greenlight === false);\n\n yield {\n elapsedMs,\n isAborted: false,\n isFailedTerminalStage,\n previousStatus,\n stageChanged,\n status: greenlightStatus,\n };\n\n // Update previous status for next iteration\n previousStatus = greenlightStatus;\n\n switch (greenlightStatus.runStage) {\n case \"canceled\": {\n yield {\n abortReason: \"run-canceled\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n message: greenlightStatus.message,\n reason: greenlightStatus.reason,\n };\n return;\n }\n case \"completed\":\n return;\n case \"initializing\":\n await sleep(runInProgressInterval);\n break;\n case \"underReview\":\n await sleep(runUnderReviewInterval);\n break;\n default:\n throw Error(\n `Unexpected run stage: ${greenlightStatus satisfies never}`,\n );\n }\n }\n\n // Timeout\n yield {\n abortReason: \"poll-timed-out\",\n elapsedMs: Date.now() - startedAt,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { pluralize } from \"../../../other.js\";\n\n/**\n * Build log message for successful completed run\n */\nexport function buildSuccessLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { nonBlockingBugsCount, relevantRunUrl } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n return `\u2705 Run passed and no blocking bugs found${\n nonBlockingBugsCount > 0\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )} found`\n : \"\"\n }.\\n${urlInfo}`;\n}\n\n/**\n * Build log message for failed completed run\n */\nexport function buildFailedLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const {\n blockingBugsCount,\n nonBlockingBugsCount,\n relevantRunWithBugsUrl,\n reproducedBugs,\n } = status;\n\n const blockingBugUrls = reproducedBugs\n .filter((bug) => bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n const nonBlockingBugUrls = reproducedBugs\n .filter((bug) => !bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n\n const blockingBugList = blockingBugUrls.map((url) => `\\n\u2022 ${url}`).join(\"\");\n const nonBlockingBugList = nonBlockingBugUrls\n .map((url) => `\\n\u2022 ${url}`)\n .join(\"\");\n const bugsListInText = `${\n blockingBugUrls.length > 0 ? `\\nBLOCKING BUGS:${blockingBugList}` : \"\"\n }${\n nonBlockingBugUrls.length > 0\n ? `\\nNON BLOCKING BUGS:${nonBlockingBugList}`\n : \"\"\n }`;\n\n return (\n `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(\n blockingBugsCount,\n )} found${\n nonBlockingBugsCount\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )}`\n : \"\"\n }.\\nSee ${relevantRunWithBugsUrl}\\n` +\n \"You may review the priority of certain bugs to mark these non-blocking and retry the job.\\n\" +\n bugsListInText\n );\n}\n\n/**\n * Build log message for superseded run (aborting)\n */\nexport function buildSupersededAbortLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `\u274C Aborting due to superseded run (option 'abortOnSuperseded' is enabled).${supersedingDetails}`;\n}\n\n/**\n * Build log message for superseded run (continuing)\n */\nexport function buildSupersededContinueLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `Root run was superseded:${supersedingDetails}`;\n}\n\n/**\n * Build log messages for different run stages\n */\nexport function buildRunStageLogMessage(\n status: Exclude<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { relevantRunUrl, runStage } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n switch (runStage) {\n case \"canceled\":\n return `\uD83D\uDEAB Run was canceled. ${\n status.message || \"Aborting... Please contact support.\"\n }\\n${urlInfo}`;\n case \"initializing\":\n return `\u23F3 Run is in progress... ${urlInfo}`;\n case \"underReview\":\n return `\uD83D\uDD75\uFE0F Run is under review... ${urlInfo}`;\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n}\n", "import type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n PollCiGreenlightIteratorHttpAborted,\n PollCiGreenlightIteratorNonHttpAborted,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * Handles aborted iterations from the CI greenlight poll iterator\n * and converts them to appropriate result objects with logging\n */\nexport function mapIteratorAbortToGreenlightStatus(\n iteration:\n | PollCiGreenlightIteratorHttpAborted\n | PollCiGreenlightIteratorNonHttpAborted,\n pollTimeout: number,\n deps: SdkDependencies,\n): PollCiGreenlightStatus {\n const { log } = deps;\n const { abortReason, httpStatus } = iteration;\n\n switch (abortReason) {\n case \"4XX-client-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"5XX-server-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"404-run-not-found\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"network-error\":\n log.error(`\uD83D\uDEAB Unrecoverable network error from CI greenlight, aborting.`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"poll-timed-out\":\n log.warn(`\u274C Poll timed out after ${pollTimeout / 1000}s`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"run-canceled\":\n log.info(\n iteration.message\n ? `Run was canceled. ${iteration.message}`\n : `Run was canceled`,\n );\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"XXX-other-http-code\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n default:\n throw Error(`Unexpected abort reason: ${abortReason satisfies never}`);\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { buildCompletedRunResult } from \"./buildCompletedRunResult.js\";\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./iterator.js\";\nimport {\n buildFailedLogMessage,\n buildRunStageLogMessage,\n buildSuccessLogMessage,\n buildSupersededAbortLogMessage,\n buildSupersededContinueLogMessage,\n} from \"./logging.js\";\nimport { mapIteratorAbortToGreenlightStatus } from \"./mapIteratorAbortToGreenlightStatus.js\";\nimport type {\n PollCiGreenlightParams,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\nexport async function pollCiGreenlightStatus(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n onRunStageChanged = () => undefined,\n runId,\n ...pollConfig\n }: PollCiGreenlightParams,\n): Promise<PollCiGreenlightStatus> {\n const { log } = deps;\n const {\n abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n } = pollConfig;\n\n const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {\n runId,\n ...pollConfig,\n });\n\n for await (const lastPoll of iterator) {\n if (lastPoll.isAborted)\n return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);\n\n // Handle status iterations\n const { previousStatus, stageChanged, status } = lastPoll;\n\n // Call onRunStageChanged callback when stage changes\n if (stageChanged) {\n try {\n await onRunStageChanged(status, previousStatus);\n } catch (e) {\n log.error(`Error in onRunStageChanged callback`, e);\n }\n }\n\n const { relevantRunId, relevantRunUrl, rootRunId, rootRunUrl, runStage } =\n status;\n\n // Superseded run handling\n const isSuperseded = rootRunId !== relevantRunId;\n const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;\n if (shouldAbortOnSuperseded) {\n const message = buildSupersededAbortLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.warn(message);\n return {\n abortReason: \"superseded-run\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n if (isSuperseded) {\n const message = buildSupersededContinueLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.info(message);\n }\n\n switch (runStage) {\n case \"canceled\":\n case \"initializing\":\n case \"underReview\": {\n log.info(buildRunStageLogMessage(status));\n break;\n }\n case \"completed\": {\n const result = buildCompletedRunResult(status);\n switch (result.outcome) {\n case \"aborted\": {\n break;\n }\n case \"failed\": {\n const message = buildFailedLogMessage(status);\n log.warn(message);\n break;\n }\n case \"success\": {\n const message = buildSuccessLogMessage(status);\n log.info(message);\n break;\n }\n default:\n throw Error(`Unexpected outcome: ${result satisfies never}`);\n }\n return result;\n }\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n }\n\n // This should never be reached as the iterator handles timeout\n throw Error(\"Iterator ended unexpectedly\");\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport { buildFetchWithTimeout } from \"../other.js\";\n\nimport { defaultFetch } from \"./defaults/fetch.js\";\nimport { defaultLogDriver } from \"./defaults/log.js\";\nimport { defaultServiceBase } from \"./defaults/serviceBase.js\";\nimport { defaultUserAgent } from \"./defaults/userAgent.js\";\nimport type { SdkDependencies } from \"./dependencies.js\";\nimport { attemptNotifyDeploy } from \"./domain/attemptDeploy/index.js\";\nimport { generateSignedUrlForRunInputsExecutablesStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.js\";\nimport { generateSignedUrlForTempTeamStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-team-storage.js\";\nimport { notifyTerminatedEphemeralEnvironment } from \"./domain/notifyTerminatedEphemeralEnvironment/index.js\";\nimport { pollCiGreenlightStatus } from \"./domain/pollCiGreenlight/index.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./domain/pollCiGreenlight/iterator.js\";\n\nexport function makeQaWolfSdk(\n {\n apiKey,\n serviceBase = defaultServiceBase,\n userAgent = defaultUserAgent,\n }: {\n apiKey: string;\n serviceBase?: string;\n userAgent?: string;\n },\n {\n fetch = defaultFetch,\n log = defaultLogDriver,\n }: Partial<SdkDependencies> = {},\n) {\n if (typeof fetch !== \"function\") {\n throw Error(\n `QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.\nWe recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`,\n );\n }\n\n const deps: SdkDependencies = {\n // Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.\n // The increased timeout helps avoid edge cases where we need to search for a commit against multiple\n // code hosting service repositories as a fallback when not finding the repository based on organization/name.\n fetch: buildFetchWithTimeout(fetch, 120000),\n log,\n };\n const apiConfig: ApiConfig = { apiKey, serviceBase, userAgent };\n return {\n attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),\n generateSignedUrlForRunInputsExecutablesStorage:\n generateSignedUrlForRunInputsExecutablesStorage.bind(\n null,\n deps,\n apiConfig,\n ),\n generateSignedUrlForTempTeamStorage:\n generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),\n makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(\n null,\n deps,\n apiConfig,\n ),\n notifyTerminatedEphemeralEnvironment:\n notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),\n pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig),\n };\n}\n\nexport type * from \"./domain/attemptDeploy/index.js\";\nexport type * from \"./domain/generateSignedUrls/types.js\";\nexport type * from \"./domain/notifyTerminatedEphemeralEnvironment/types.js\";\nexport type * from \"./domain/pollCiGreenlight/types.js\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["handleErrorResponse"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,8 @@ import type { SdkDependencies } from "../../dependencies.js";
|
|
|
3
3
|
import type { GenerateSignedUrlConfig } from "./types.js";
|
|
4
4
|
type GenerateSignedUrlStatus = {
|
|
5
5
|
fileLocation?: string;
|
|
6
|
+
interactiveRunFileLocation?: string;
|
|
7
|
+
/** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */
|
|
6
8
|
playgroundFileLocation?: string;
|
|
7
9
|
success: true;
|
|
8
10
|
uploadUrl?: string;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type GenerateSignedUrlStatus = {
|
|
2
2
|
fileLocation?: string;
|
|
3
|
+
interactiveRunFileLocation?: string;
|
|
4
|
+
/** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */
|
|
3
5
|
playgroundFileLocation?: string;
|
|
4
6
|
success: true;
|
|
5
7
|
uploadUrl?: string;
|
|
@@ -22,6 +24,8 @@ export type GenerateSignedUrlResponse = {
|
|
|
22
24
|
errorMessage?: string;
|
|
23
25
|
fileLocation?: string;
|
|
24
26
|
httpStatus: number;
|
|
27
|
+
interactiveRunFileLocation?: string;
|
|
28
|
+
/** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */
|
|
25
29
|
playgroundFileLocation?: string;
|
|
26
30
|
signedUrl?: string;
|
|
27
31
|
success: boolean;
|
|
@@ -22,4 +22,6 @@ export declare function buildSupersededContinueLogMessage(rootRunUrl: string, re
|
|
|
22
22
|
/**
|
|
23
23
|
* Build log messages for different run stages
|
|
24
24
|
*/
|
|
25
|
-
export declare function buildRunStageLogMessage(
|
|
25
|
+
export declare function buildRunStageLogMessage(status: Exclude<CiGreenlightStatus, {
|
|
26
|
+
runStage: "completed";
|
|
27
|
+
}>): string;
|
|
@@ -122,7 +122,7 @@ export type PollCiGreenlightIteratorHttpAborted = {
|
|
|
122
122
|
isAborted: true;
|
|
123
123
|
};
|
|
124
124
|
/**
|
|
125
|
-
* Iterator aborted due to non-HTTP reasons (timeout, canceled, network
|
|
125
|
+
* Iterator aborted due to non-HTTP reasons (timeout, canceled, network)
|
|
126
126
|
*/
|
|
127
127
|
export type PollCiGreenlightIteratorNonHttpAborted = {
|
|
128
128
|
abortReason: Exclude<PollCiGreenlightNonHttpAbortReason, "superseded-run">;
|
|
@@ -132,6 +132,17 @@ export type PollCiGreenlightIteratorNonHttpAborted = {
|
|
|
132
132
|
* True when the iterator was aborted
|
|
133
133
|
*/
|
|
134
134
|
isAborted: true;
|
|
135
|
+
/**
|
|
136
|
+
* Human-readable copy explaining the cancellation, when the server sent it.
|
|
137
|
+
* Only a `run-canceled` abort carries it.
|
|
138
|
+
*/
|
|
139
|
+
message?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Stable, machine-readable code for the cancellation, when the server sent
|
|
142
|
+
* it. Only a `run-canceled` abort carries it, and it is an open set of
|
|
143
|
+
* values.
|
|
144
|
+
*/
|
|
145
|
+
reason?: string;
|
|
135
146
|
};
|
|
136
147
|
/**
|
|
137
148
|
* Yielded value from the async generator - either a status update or a terminal abort condition
|
package/dist/lib/sdk/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function makeQaWolfSdk({ apiKey, serviceBase, userAgent, }: {
|
|
|
8
8
|
generateSignedUrlForRunInputsExecutablesStorage: (config: import("./domain/generateSignedUrls/types.js").GenerateSignedUrlConfig) => Promise<import("./domain/generateSignedUrls/types.js").GenerateSignedUrlStatus>;
|
|
9
9
|
generateSignedUrlForTempTeamStorage: (config: import("./domain/generateSignedUrls/types.js").GenerateSignedUrlConfig) => Promise<{
|
|
10
10
|
fileLocation?: string;
|
|
11
|
+
interactiveRunFileLocation?: string;
|
|
11
12
|
playgroundFileLocation?: string;
|
|
12
13
|
success: true;
|
|
13
14
|
uploadUrl?: string;
|