happo 6.5.1 → 6.6.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/dist/cli/cancelJob-HZDX6274.js +10 -0
- package/dist/cli/{chunk-SCQIFNJG.js → chunk-AFAI3HL3.js} +2 -2
- package/dist/cli/{chunk-7LVB6VSD.js → chunk-DUWOS4XT.js} +5 -5
- package/dist/cli/{chunk-7LVB6VSD.js.map → chunk-DUWOS4XT.js.map} +1 -1
- package/dist/cli/{chunk-4DIEFVB6.js → chunk-LCNHMIOU.js} +2 -2
- package/dist/cli/chunk-OXGH6FW4.js +84 -0
- package/dist/cli/chunk-OXGH6FW4.js.map +7 -0
- package/dist/cli/{chunk-Z3ISMK3L.js → chunk-PRPDWPU3.js} +3 -3
- package/dist/cli/{chunk-SVXHNTZV.js → chunk-QC2HOKDQ.js} +2 -2
- package/dist/cli/createAsyncComparison-FQQHINTM.js +10 -0
- package/dist/cli/{createAsyncReport-YYPR6QMH.js → createAsyncReport-IQO7YVCA.js} +4 -4
- package/dist/cli/{getFlakes-2IDWWM6K.js → getFlakes-HICLTPZC.js} +4 -4
- package/dist/cli/main.js +11 -11
- package/dist/cli/main.js.map +2 -2
- package/dist/cli/package-RZI6QOJX.js +7 -0
- package/dist/cli/{prepareSnapRequests-YRX3FLO3.js → prepareSnapRequests-VFWDWE5X.js} +156 -78
- package/dist/cli/prepareSnapRequests-VFWDWE5X.js.map +7 -0
- package/dist/cli/startJob-QZA4POSE.js +10 -0
- package/dist/cli/{wrapper-YSLGURLA.js → wrapper-IQJTUXE4.js} +7 -9
- package/dist/cli/wrapper-IQJTUXE4.js.map +7 -0
- package/dist/config/RemoteBrowserTarget.d.ts.map +1 -1
- package/dist/cypress/task.js +190 -86
- package/dist/cypress/task.js.map +4 -4
- package/dist/e2e/controller.d.ts.map +1 -1
- package/dist/e2e/wrapper.d.ts.map +1 -1
- package/dist/network/getSignedToken.d.ts +3 -0
- package/dist/network/getSignedToken.d.ts.map +1 -0
- package/dist/network/makeHappoAPIRequest.d.ts +0 -1
- package/dist/network/makeHappoAPIRequest.d.ts.map +1 -1
- package/dist/network/uploadAssets.d.ts.map +1 -1
- package/dist/playwright/index.js +190 -86
- package/dist/playwright/index.js.map +4 -4
- package/dist/utils/deterministicArchive.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/cli/cancelJob-RNJNTEO6.js +0 -10
- package/dist/cli/chunk-ZFINBURL.js +0 -54
- package/dist/cli/chunk-ZFINBURL.js.map +0 -7
- package/dist/cli/createAsyncComparison-7TQ6WCAL.js +0 -10
- package/dist/cli/package-XNDR47YX.js +0 -7
- package/dist/cli/prepareSnapRequests-YRX3FLO3.js.map +0 -7
- package/dist/cli/startJob-6UNQDHQ6.js +0 -10
- package/dist/cli/wrapper-YSLGURLA.js.map +0 -7
- /package/dist/cli/{cancelJob-RNJNTEO6.js.map → cancelJob-HZDX6274.js.map} +0 -0
- /package/dist/cli/{chunk-SCQIFNJG.js.map → chunk-AFAI3HL3.js.map} +0 -0
- /package/dist/cli/{chunk-4DIEFVB6.js.map → chunk-LCNHMIOU.js.map} +0 -0
- /package/dist/cli/{chunk-Z3ISMK3L.js.map → chunk-PRPDWPU3.js.map} +0 -0
- /package/dist/cli/{chunk-SVXHNTZV.js.map → chunk-QC2HOKDQ.js.map} +0 -0
- /package/dist/cli/{createAsyncComparison-7TQ6WCAL.js.map → createAsyncComparison-FQQHINTM.js.map} +0 -0
- /package/dist/cli/{createAsyncReport-YYPR6QMH.js.map → createAsyncReport-IQO7YVCA.js.map} +0 -0
- /package/dist/cli/{getFlakes-2IDWWM6K.js.map → getFlakes-HICLTPZC.js.map} +0 -0
- /package/dist/cli/{package-XNDR47YX.js.map → package-RZI6QOJX.js.map} +0 -0
- /package/dist/cli/{startJob-6UNQDHQ6.js.map → startJob-QZA4POSE.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DUWOS4XT.js";
|
|
4
4
|
|
|
5
5
|
// src/network/fetchWithRetry.ts
|
|
6
6
|
import asyncRetry from "async-retry";
|
|
@@ -95,4 +95,4 @@ export {
|
|
|
95
95
|
ErrorWithStatusCode,
|
|
96
96
|
fetchWithRetry
|
|
97
97
|
};
|
|
98
|
-
//# sourceMappingURL=chunk-
|
|
98
|
+
//# sourceMappingURL=chunk-AFAI3HL3.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "happo",
|
|
4
|
-
version: "6.
|
|
4
|
+
version: "6.6.0",
|
|
5
5
|
description: "Catch unexpected visual and accessibility changes and UI bugs",
|
|
6
6
|
license: "MIT",
|
|
7
7
|
repository: {
|
|
@@ -62,10 +62,10 @@ var package_default = {
|
|
|
62
62
|
all: "node ./scripts/allchecks.ts",
|
|
63
63
|
build: "pnpm build:types && pnpm build:dist",
|
|
64
64
|
"build:custom": "esbuild src/custom/__happo__/index.ts --bundle --format=iife --global-name=happoCustom --outfile=tmp/happo-custom/bundle.js --platform=browser --target=esnext",
|
|
65
|
-
"build:dist": "./scripts/build.ts",
|
|
65
|
+
"build:dist": "node ./scripts/build.ts",
|
|
66
66
|
"build:types": "pnpm tsc --pretty",
|
|
67
67
|
"build:watch": "tsc --build --watch",
|
|
68
|
-
clean: "
|
|
68
|
+
clean: "node ./scripts/clean.ts",
|
|
69
69
|
lint: "eslint .",
|
|
70
70
|
prepublishOnly: "pnpm clean && pnpm build",
|
|
71
71
|
"storybook:dev": "storybook dev --config-dir src/storybook/__tests__/storybook-app -p ${PORT:-6007}",
|
|
@@ -125,7 +125,7 @@ var package_default = {
|
|
|
125
125
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
126
126
|
"eslint-plugin-unicorn": "^63.0.0",
|
|
127
127
|
jiti: "^2.6.1",
|
|
128
|
-
jsdom: "^
|
|
128
|
+
jsdom: "^29.0.0",
|
|
129
129
|
multiparty: "^4.2.3",
|
|
130
130
|
prettier: "^3.6.2",
|
|
131
131
|
react: "^19.2.0",
|
|
@@ -183,4 +183,4 @@ var package_default = {
|
|
|
183
183
|
export {
|
|
184
184
|
package_default
|
|
185
185
|
};
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
186
|
+
//# sourceMappingURL=chunk-DUWOS4XT.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../package.json"],
|
|
4
|
-
"sourcesContent": ["{\n \"name\": \"happo\",\n \"version\": \"6.
|
|
4
|
+
"sourcesContent": ["{\n \"name\": \"happo\",\n \"version\": \"6.6.0\",\n \"description\": \"Catch unexpected visual and accessibility changes and UI bugs\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/happo/happo.git\"\n },\n \"bugs\": \"https://github.com/happo/happo/issues\",\n \"homepage\": \"https://happo.io\",\n \"bin\": {\n \"happo\": \"dist/cli/main.js\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/config/index.js\",\n \"types\": \"./dist/config/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/config/index.d.ts\",\n \"default\": \"./dist/config/index.js\"\n },\n \"./cypress\": {\n \"types\": \"./dist/cypress/index.d.ts\",\n \"default\": \"./dist/cypress/index.js\"\n },\n \"./cypress/task\": {\n \"types\": \"./dist/cypress/task.d.ts\",\n \"default\": \"./dist/cypress/task.js\"\n },\n \"./playwright\": {\n \"types\": \"./dist/playwright/index.d.ts\",\n \"default\": \"./dist/playwright/index.js\"\n },\n \"./custom\": {\n \"types\": \"./dist/custom/index.d.ts\",\n \"default\": \"./dist/custom/index.js\"\n },\n \"./storybook/addon\": {\n \"types\": \"./dist/storybook/browser/addon.d.ts\",\n \"default\": \"./dist/storybook/browser/addon.js\"\n },\n \"./storybook/decorator\": {\n \"types\": \"./dist/storybook/browser/decorator.d.ts\",\n \"default\": \"./dist/storybook/browser/decorator.js\"\n },\n \"./storybook/preset\": {\n \"types\": \"./dist/storybook/preset.d.ts\",\n \"default\": \"./dist/storybook/preset.js\"\n },\n \"./storybook/register\": {\n \"types\": \"./dist/storybook/browser/register.d.ts\",\n \"default\": \"./dist/storybook/browser/register.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"preset.js\"\n ],\n \"scripts\": {\n \"all\": \"node ./scripts/allchecks.ts\",\n \"build\": \"pnpm build:types && pnpm build:dist\",\n \"build:custom\": \"esbuild src/custom/__happo__/index.ts --bundle --format=iife --global-name=happoCustom --outfile=tmp/happo-custom/bundle.js --platform=browser --target=esnext\",\n \"build:dist\": \"node ./scripts/build.ts\",\n \"build:types\": \"pnpm tsc --pretty\",\n \"build:watch\": \"tsc --build --watch\",\n \"clean\": \"node ./scripts/clean.ts\",\n \"lint\": \"eslint .\",\n \"prepublishOnly\": \"pnpm clean && pnpm build\",\n \"storybook:dev\": \"storybook dev --config-dir src/storybook/__tests__/storybook-app -p ${PORT:-6007}\",\n \"test\": \"node --env-file-if-exists=.env.local ./scripts/test.ts\",\n \"test:custom\": \"pnpm build:dist && pnpm build:custom && node --env-file-if-exists=.env.local dist/cli/main.js -c ./happoconfigs/happo.custom.config.ts\",\n \"test:cypress\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/main.js -c ./happoconfigs/happo.cypress.config.ts e2e -- cypress run -C src/cypress/__cypress__/cypress.config.ts\",\n \"test:cypress:open\": \"cypress open -C src/cypress/__cypress__/cypress.config.ts\",\n \"test:playwright\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/main.js -c ./happoconfigs/happo.playwright.config.ts e2e -- playwright test\",\n \"test:storybook\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/main.js -c ./happoconfigs/happo.storybook.config.ts\",\n \"test:pages\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/main.js -c ./happoconfigs/happo.pages.config.ts\",\n \"tsc\": \"tsc --build tsconfig.json\"\n },\n \"browserslist\": {\n \"node\": [\n \"node 22\"\n ],\n \"browser\": [\n \"last 2 Chrome major versions\",\n \"last 2 Firefox major versions\",\n \"last 2 Safari major versions\",\n \"last 2 Edge major versions\"\n ],\n \"isomorphic\": [\n \"node 22\",\n \"last 2 Chrome major versions\",\n \"last 2 Firefox major versions\",\n \"last 2 Safari major versions\",\n \"last 2 Edge major versions\"\n ]\n },\n \"prettier\": {\n \"printWidth\": 85,\n \"singleQuote\": true,\n \"trailingComma\": \"all\",\n \"arrowParens\": \"always\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@playwright/test\": \"^1.55.1\",\n \"@reporters/github\": \"^1.11.0\",\n \"@storybook/builder-vite\": \"^10.0.1\",\n \"@storybook/react-vite\": \"^10.0.1\",\n \"@types/async-retry\": \"^1.4.9\",\n \"@types/base64-stream\": \"^1.0.5\",\n \"@types/jsdom\": \"^28.0.0\",\n \"@types/mime-types\": \"^3.0.1\",\n \"@types/multiparty\": \"^4.2.1\",\n \"@types/node\": \"^24.9.1\",\n \"@types/react\": \"^19.2.0\",\n \"@types/react-dom\": \"^19.2.0\",\n \"cypress\": \"^15.5.0\",\n \"esbuild\": \"^0.27.0\",\n \"eslint\": \"^10.0.2\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-compat\": \"^7.0.1\",\n \"eslint-plugin-depend\": \"^1.4.0\",\n \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n \"eslint-plugin-unicorn\": \"^63.0.0\",\n \"jiti\": \"^2.6.1\",\n \"jsdom\": \"^29.0.0\",\n \"multiparty\": \"^4.2.3\",\n \"prettier\": \"^3.6.2\",\n \"react\": \"^19.2.0\",\n \"react-dom\": \"^19.2.0\",\n \"react-error-boundary\": \"^6.0.0\",\n \"storybook\": \"^10.0.1\",\n \"typescript\": \"^5.9.2\",\n \"typescript-eslint\": \"^8.56.1\"\n },\n \"dependencies\": {\n \"async-retry\": \"^1.3.3\",\n \"base64-stream\": \"^1.0.0\",\n \"empathic\": \"^2.0.0\",\n \"fflate\": \"^0.8.2\",\n \"jose\": \"^6.1.0\",\n \"limit-concur\": \"^4.0.0\",\n \"mime-types\": \"^3.0.1\",\n \"srcset\": \"^5.0.2\"\n },\n \"storybook\": {\n \"displayName\": \"Happo\",\n \"icon\": \"https://happo.io/static/happo-hippo.png\",\n \"supportedFrameworks\": [\n \"angular\",\n \"ember\",\n \"html\",\n \"preact\",\n \"react\",\n \"react-native\",\n \"svelte\",\n \"vue\",\n \"web-components\"\n ],\n \"unsupportedFrameworks\": []\n },\n \"keywords\": [\n \"storybook-addon\",\n \"accessibility\",\n \"cypress\",\n \"playwright\",\n \"regression\",\n \"storybook\",\n \"test\",\n \"testing\",\n \"ui\",\n \"visual-regression\",\n \"visual\",\n \"vrt\"\n ],\n \"engines\": {\n \"node\": \"^22.18.0 || ^23.6.0 || >=24.0.0\"\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OXGH6FW4.js";
|
|
4
4
|
|
|
5
5
|
// src/network/startJob.ts
|
|
6
6
|
function assertResultIsStartJobResult(result) {
|
|
@@ -36,4 +36,4 @@ async function startJob(config, { beforeSha, afterSha, link, message }, logger)
|
|
|
36
36
|
export {
|
|
37
37
|
startJob
|
|
38
38
|
};
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
39
|
+
//# sourceMappingURL=chunk-LCNHMIOU.js.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fetchWithRetry
|
|
3
|
+
} from "./chunk-AFAI3HL3.js";
|
|
4
|
+
|
|
5
|
+
// src/network/getSignedToken.ts
|
|
6
|
+
import { SignJWT } from "jose";
|
|
7
|
+
var TOKEN_TTL_SECONDS = 5 * 60;
|
|
8
|
+
var TOKEN_REFRESH_BUFFER_SECONDS = 30;
|
|
9
|
+
var cache = /* @__PURE__ */ new Map();
|
|
10
|
+
function getCacheKey(apiKey, apiSecret) {
|
|
11
|
+
return `${apiKey}:${apiSecret}`;
|
|
12
|
+
}
|
|
13
|
+
async function getSignedToken(apiKey, apiSecret) {
|
|
14
|
+
const cacheKey = getCacheKey(apiKey, apiSecret);
|
|
15
|
+
const cachedPromise = cache.get(cacheKey);
|
|
16
|
+
if (cachedPromise) {
|
|
17
|
+
const cached = await cachedPromise;
|
|
18
|
+
const nowSeconds = Date.now() / 1e3;
|
|
19
|
+
if (cached.expiresAt - nowSeconds > TOKEN_REFRESH_BUFFER_SECONDS) {
|
|
20
|
+
return cached.token;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const signingPromise = (async () => {
|
|
24
|
+
const nowSeconds = Date.now() / 1e3;
|
|
25
|
+
const expiresAt = Math.floor(nowSeconds) + TOKEN_TTL_SECONDS;
|
|
26
|
+
const encodedSecret = new TextEncoder().encode(apiSecret);
|
|
27
|
+
const token = await new SignJWT({ key: apiKey }).setProtectedHeader({ alg: "HS256", kid: apiKey }).setExpirationTime(expiresAt).sign(encodedSecret);
|
|
28
|
+
return { token, expiresAt };
|
|
29
|
+
})();
|
|
30
|
+
cache.set(cacheKey, signingPromise);
|
|
31
|
+
try {
|
|
32
|
+
const { token } = await signingPromise;
|
|
33
|
+
return token;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
cache.delete(cacheKey);
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/network/makeHappoAPIRequest.ts
|
|
41
|
+
async function makeHappoAPIRequest({ url, path, method = "GET", formData, body }, { apiKey, apiSecret, endpoint }, {
|
|
42
|
+
retryCount = 0,
|
|
43
|
+
timeout = 6e4,
|
|
44
|
+
retryMinTimeout = 1e3,
|
|
45
|
+
retryMaxTimeout = Infinity
|
|
46
|
+
}, logger = console) {
|
|
47
|
+
const fetchURL = path ? new URL(path, endpoint) : url;
|
|
48
|
+
if (!fetchURL) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
"No fetch URL provided. Either `path` (preferred) or `url` must be provided."
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const signed = await getSignedToken(apiKey, apiSecret);
|
|
54
|
+
const headers = {
|
|
55
|
+
Authorization: `Bearer ${signed}`
|
|
56
|
+
};
|
|
57
|
+
const response = await fetchWithRetry(
|
|
58
|
+
fetchURL,
|
|
59
|
+
{
|
|
60
|
+
method,
|
|
61
|
+
headers,
|
|
62
|
+
formData,
|
|
63
|
+
body,
|
|
64
|
+
timeout,
|
|
65
|
+
retryCount,
|
|
66
|
+
retryMinTimeout,
|
|
67
|
+
retryMaxTimeout
|
|
68
|
+
},
|
|
69
|
+
logger
|
|
70
|
+
);
|
|
71
|
+
if (response.status === 204) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const result = await response.json();
|
|
75
|
+
if (typeof result !== "object") {
|
|
76
|
+
throw new TypeError(`Response is not an object: ${JSON.stringify(result)}`);
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
makeHappoAPIRequest
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=chunk-OXGH6FW4.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/network/getSignedToken.ts", "../../src/network/makeHappoAPIRequest.ts"],
|
|
4
|
+
"sourcesContent": ["import { SignJWT } from 'jose';\n\nconst TOKEN_TTL_SECONDS = 5 * 60;\nconst TOKEN_REFRESH_BUFFER_SECONDS = 30;\n\ninterface CachedToken {\n token: string;\n expiresAt: number; // Unix timestamp in seconds\n}\n\nconst cache = new Map<string, Promise<CachedToken>>();\n\nfunction getCacheKey(apiKey: string, apiSecret: string): string {\n return `${apiKey}:${apiSecret}`;\n}\n\nexport async function getSignedToken(apiKey: string, apiSecret: string): Promise<string> {\n const cacheKey = getCacheKey(apiKey, apiSecret);\n const cachedPromise = cache.get(cacheKey);\n\n if (cachedPromise) {\n const cached = await cachedPromise;\n const nowSeconds = Date.now() / 1000;\n if (cached.expiresAt - nowSeconds > TOKEN_REFRESH_BUFFER_SECONDS) {\n return cached.token;\n }\n }\n\n const signingPromise = (async (): Promise<CachedToken> => {\n const nowSeconds = Date.now() / 1000;\n const expiresAt = Math.floor(nowSeconds) + TOKEN_TTL_SECONDS;\n const encodedSecret = new TextEncoder().encode(apiSecret);\n const token = await new SignJWT({ key: apiKey })\n .setProtectedHeader({ alg: 'HS256', kid: apiKey })\n .setExpirationTime(expiresAt)\n .sign(encodedSecret);\n return { token, expiresAt };\n })();\n\n cache.set(cacheKey, signingPromise);\n try {\n const { token } = await signingPromise;\n return token;\n } catch (error) {\n cache.delete(cacheKey);\n throw error;\n }\n}\n\n// Exported for use in tests\nexport function clearTokenCache(): void {\n cache.clear();\n}\n", "import type { ConfigWithDefaults } from '../config/index.ts';\nimport type { Logger } from '../isomorphic/types.ts';\nimport fetchWithRetry from './fetchWithRetry.ts';\nimport { getSignedToken } from './getSignedToken.ts';\n\ntype FormDataValue = string | number | File | undefined;\n\nexport interface RequestAttributes {\n /**\n * The path to the API endpoint\n *\n * @example\n * '/api/snap-requests/with-results'\n */\n path?: `/api/${string}`;\n\n /**\n * The URL to fetch\n *\n * Prefer using the `path` property instead. If both are provided, the `path`\n * property will be used.\n */\n url?: string;\n\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE';\n formData?: Record<string, FormDataValue>;\n body?: unknown;\n}\n\nexport interface MakeHappoAPIRequestOptions {\n /**\n * The timeout in milliseconds\n * @default 60_000\n */\n timeout?: number;\n\n /**\n * The number of times to retry the request\n * @default 0\n */\n retryCount?: number;\n\n /**\n * The minimum timeout in milliseconds\n * @default 1000\n */\n retryMinTimeout?: number;\n\n /**\n * The maximum timeout in milliseconds\n * @default Infinity\n */\n retryMaxTimeout?: number;\n}\n\nexport default async function makeHappoAPIRequest(\n { url, path, method = 'GET', formData, body }: RequestAttributes,\n { apiKey, apiSecret, endpoint }: ConfigWithDefaults,\n {\n retryCount = 0,\n timeout = 60_000,\n retryMinTimeout = 1000,\n retryMaxTimeout = Infinity,\n }: MakeHappoAPIRequestOptions,\n logger: Logger = console,\n): Promise<object | null> {\n const fetchURL = path ? new URL(path, endpoint) : url;\n\n if (!fetchURL) {\n throw new Error(\n 'No fetch URL provided. Either `path` (preferred) or `url` must be provided.',\n );\n }\n\n const signed = await getSignedToken(apiKey, apiSecret);\n\n const headers = {\n Authorization: `Bearer ${signed}`,\n };\n\n const response = await fetchWithRetry(\n fetchURL,\n {\n method,\n headers,\n formData,\n body,\n timeout,\n retryCount,\n retryMinTimeout,\n retryMaxTimeout,\n },\n logger,\n );\n\n if (response.status === 204) {\n return null;\n }\n\n // We expect API responses to be JSON, so let's parse it as JSON here for\n // convenience.\n const result = await response.json();\n\n if (typeof result !== 'object') {\n throw new TypeError(`Response is not an object: ${JSON.stringify(result)}`);\n }\n\n return result;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAAA,SAAS,eAAe;AAExB,IAAM,oBAAoB,IAAI;AAC9B,IAAM,+BAA+B;AAOrC,IAAM,QAAQ,oBAAI,IAAkC;AAEpD,SAAS,YAAY,QAAgB,WAA2B;AAC9D,SAAO,GAAG,MAAM,IAAI,SAAS;AAC/B;AAEA,eAAsB,eAAe,QAAgB,WAAoC;AACvF,QAAM,WAAW,YAAY,QAAQ,SAAS;AAC9C,QAAM,gBAAgB,MAAM,IAAI,QAAQ;AAExC,MAAI,eAAe;AACjB,UAAM,SAAS,MAAM;AACrB,UAAM,aAAa,KAAK,IAAI,IAAI;AAChC,QAAI,OAAO,YAAY,aAAa,8BAA8B;AAChE,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,kBAAkB,YAAkC;AACxD,UAAM,aAAa,KAAK,IAAI,IAAI;AAChC,UAAM,YAAY,KAAK,MAAM,UAAU,IAAI;AAC3C,UAAM,gBAAgB,IAAI,YAAY,EAAE,OAAO,SAAS;AACxD,UAAM,QAAQ,MAAM,IAAI,QAAQ,EAAE,KAAK,OAAO,CAAC,EAC5C,mBAAmB,EAAE,KAAK,SAAS,KAAK,OAAO,CAAC,EAChD,kBAAkB,SAAS,EAC3B,KAAK,aAAa;AACrB,WAAO,EAAE,OAAO,UAAU;AAAA,EAC5B,GAAG;AAEH,QAAM,IAAI,UAAU,cAAc;AAClC,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,MAAM;AACxB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,OAAO,QAAQ;AACrB,UAAM;AAAA,EACR;AACF;;;ACQA,eAAO,oBACL,EAAE,KAAK,MAAM,SAAS,OAAO,UAAU,KAAK,GAC5C,EAAE,QAAQ,WAAW,SAAS,GAC9B;AAAA,EACE,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,kBAAkB;AACpB,GACA,SAAiB,SACO;AACxB,QAAM,WAAW,OAAO,IAAI,IAAI,MAAM,QAAQ,IAAI;AAElD,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,eAAe,QAAQ,SAAS;AAErD,QAAM,UAAU;AAAA,IACd,eAAe,UAAU,MAAM;AAAA,EACjC;AAEA,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO;AAAA,EACT;AAIA,QAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,IAAI,UAAU,8BAA8B,KAAK,UAAU,MAAM,CAAC,EAAE;AAAA,EAC5E;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OXGH6FW4.js";
|
|
4
4
|
import {
|
|
5
5
|
ErrorWithStatusCode
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AFAI3HL3.js";
|
|
7
7
|
|
|
8
8
|
// src/network/cancelJob.ts
|
|
9
9
|
async function cancelJob(status, message, config, { beforeSha, afterSha, link }, logger) {
|
|
@@ -43,4 +43,4 @@ async function cancelJob(status, message, config, { beforeSha, afterSha, link },
|
|
|
43
43
|
export {
|
|
44
44
|
cancelJob
|
|
45
45
|
};
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-PRPDWPU3.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OXGH6FW4.js";
|
|
4
4
|
|
|
5
5
|
// src/network/createAsyncComparison.ts
|
|
6
6
|
function assertResultIsCreateAsyncComparisonResult(result) {
|
|
@@ -60,4 +60,4 @@ async function createAsyncComparison(config, {
|
|
|
60
60
|
export {
|
|
61
61
|
createAsyncComparison
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-QC2HOKDQ.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAsyncComparison
|
|
3
|
+
} from "./chunk-QC2HOKDQ.js";
|
|
4
|
+
import "./chunk-OXGH6FW4.js";
|
|
5
|
+
import "./chunk-AFAI3HL3.js";
|
|
6
|
+
import "./chunk-DUWOS4XT.js";
|
|
7
|
+
export {
|
|
8
|
+
createAsyncComparison as default
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=createAsyncComparison-FQQHINTM.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-OXGH6FW4.js";
|
|
4
|
+
import "./chunk-AFAI3HL3.js";
|
|
5
|
+
import "./chunk-DUWOS4XT.js";
|
|
6
6
|
|
|
7
7
|
// src/network/createAsyncReport.ts
|
|
8
8
|
function assertResultIsCreateAsyncReportResult(result) {
|
|
@@ -38,4 +38,4 @@ async function createAsyncReport(snapRequestIds, config, { afterSha, link, messa
|
|
|
38
38
|
export {
|
|
39
39
|
createAsyncReport as default
|
|
40
40
|
};
|
|
41
|
-
//# sourceMappingURL=createAsyncReport-
|
|
41
|
+
//# sourceMappingURL=createAsyncReport-IQO7YVCA.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-OXGH6FW4.js";
|
|
4
|
+
import "./chunk-AFAI3HL3.js";
|
|
5
|
+
import "./chunk-DUWOS4XT.js";
|
|
6
6
|
|
|
7
7
|
// src/network/getFlakes.ts
|
|
8
8
|
function formatFlakeOutput(flakes) {
|
|
@@ -70,4 +70,4 @@ export {
|
|
|
70
70
|
getFlakes as default,
|
|
71
71
|
formatFlakeOutput
|
|
72
72
|
};
|
|
73
|
-
//# sourceMappingURL=getFlakes-
|
|
73
|
+
//# sourceMappingURL=getFlakes-HICLTPZC.js.map
|
package/dist/cli/main.js
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-JTRP4JVC.js";
|
|
5
5
|
import {
|
|
6
6
|
fetchWithRetry
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AFAI3HL3.js";
|
|
8
8
|
import {
|
|
9
9
|
package_default
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DUWOS4XT.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/index.ts
|
|
13
13
|
import path3 from "node:path";
|
|
@@ -1189,7 +1189,7 @@ function createReporter(opts = {}) {
|
|
|
1189
1189
|
|
|
1190
1190
|
// src/cli/index.ts
|
|
1191
1191
|
async function getVersion() {
|
|
1192
|
-
const packageJson = await import("./package-
|
|
1192
|
+
const packageJson = await import("./package-RZI6QOJX.js");
|
|
1193
1193
|
return packageJson.default.version;
|
|
1194
1194
|
}
|
|
1195
1195
|
function parseDashdashCommandParts(rawArgs) {
|
|
@@ -1431,10 +1431,10 @@ async function main(rawArgs = process.argv, logger = console) {
|
|
|
1431
1431
|
async function handleDefaultCommand(config, environment, logger) {
|
|
1432
1432
|
logger.log("Running happo tests...");
|
|
1433
1433
|
const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] = await Promise.all([
|
|
1434
|
-
(await import("./startJob-
|
|
1435
|
-
(await import("./createAsyncComparison-
|
|
1436
|
-
(await import("./createAsyncReport-
|
|
1437
|
-
(await import("./prepareSnapRequests-
|
|
1434
|
+
(await import("./startJob-QZA4POSE.js")).default,
|
|
1435
|
+
(await import("./createAsyncComparison-FQQHINTM.js")).default,
|
|
1436
|
+
(await import("./createAsyncReport-IQO7YVCA.js")).default,
|
|
1437
|
+
(await import("./prepareSnapRequests-VFWDWE5X.js")).default
|
|
1438
1438
|
]);
|
|
1439
1439
|
await startJob(config, environment, logger);
|
|
1440
1440
|
try {
|
|
@@ -1467,7 +1467,7 @@ async function handleDefaultCommand(config, environment, logger) {
|
|
|
1467
1467
|
} catch (e) {
|
|
1468
1468
|
const message = e instanceof Error ? e.message : String(e);
|
|
1469
1469
|
logger.error(`${config.integration.type} run failed: ${message}`, e);
|
|
1470
|
-
const cancelJob = (await import("./cancelJob-
|
|
1470
|
+
const cancelJob = (await import("./cancelJob-HZDX6274.js")).default;
|
|
1471
1471
|
await cancelJob("failure", message, config, environment, logger);
|
|
1472
1472
|
process.exitCode = 1;
|
|
1473
1473
|
return;
|
|
@@ -1478,7 +1478,7 @@ async function handleFinalizeCommand(config, environment, logger) {
|
|
|
1478
1478
|
logger.log("Config:", config);
|
|
1479
1479
|
logger.log("Environment:", environment);
|
|
1480
1480
|
try {
|
|
1481
|
-
const finalizeAll = (await import("./wrapper-
|
|
1481
|
+
const finalizeAll = (await import("./wrapper-IQJTUXE4.js")).finalizeAll;
|
|
1482
1482
|
await finalizeAll({ happoConfig: config, environment, logger });
|
|
1483
1483
|
} catch (e) {
|
|
1484
1484
|
logger.error(e instanceof Error ? e.message : String(e), e);
|
|
@@ -1506,7 +1506,7 @@ async function handleFlakeCommand(config, {
|
|
|
1506
1506
|
process.exitCode = 1;
|
|
1507
1507
|
return;
|
|
1508
1508
|
}
|
|
1509
|
-
const { default: getFlakes, formatFlakeOutput } = await import("./getFlakes-
|
|
1509
|
+
const { default: getFlakes, formatFlakeOutput } = await import("./getFlakes-HICLTPZC.js");
|
|
1510
1510
|
const project = allProjects ? void 0 : projectOverride ?? config.project;
|
|
1511
1511
|
const flakes = await getFlakes(
|
|
1512
1512
|
{
|
|
@@ -1548,7 +1548,7 @@ async function handleE2ECommand(config, environment, dashdashCommandParts, confi
|
|
|
1548
1548
|
logger.log("Config:", config);
|
|
1549
1549
|
logger.log("Environment:", environment);
|
|
1550
1550
|
logger.log("Dashdash command parts:", dashdashCommandParts);
|
|
1551
|
-
const runWithWrapper = (await import("./wrapper-
|
|
1551
|
+
const runWithWrapper = (await import("./wrapper-IQJTUXE4.js")).default;
|
|
1552
1552
|
const exitCode = await runWithWrapper(
|
|
1553
1553
|
dashdashCommandParts,
|
|
1554
1554
|
config,
|