happo 6.0.6 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cli/{cancelJob-NIUI7GBR.js → cancelJob-UUJ3U2WI.js} +4 -4
  2. package/dist/cli/{chunk-6SJAK2WZ.js → chunk-2N7DDGFD.js} +2 -2
  3. package/dist/cli/{chunk-FCZLLRXU.js → chunk-6WOLMTD3.js} +2 -2
  4. package/dist/cli/{chunk-FCZLLRXU.js.map → chunk-6WOLMTD3.js.map} +1 -1
  5. package/dist/cli/{chunk-NNZOCTDI.js → chunk-CJYS7OH2.js} +2 -2
  6. package/dist/cli/chunk-JTRP4JVC.js +24 -0
  7. package/dist/cli/chunk-JTRP4JVC.js.map +7 -0
  8. package/dist/cli/{chunk-BLNR2H52.js → chunk-L75P3SD7.js} +2 -2
  9. package/dist/cli/createAsyncComparison-JZL5FR2R.js +10 -0
  10. package/dist/cli/{createAsyncReport-7QIIMSNX.js → createAsyncReport-QM3S5HYH.js} +4 -4
  11. package/dist/cli/main.js +191 -27
  12. package/dist/cli/main.js.map +4 -4
  13. package/dist/cli/package-LIJK2K32.js +7 -0
  14. package/dist/cli/{prepareSnapRequests-T6RBWTYD.js → prepareSnapRequests-7H6SFFKT.js} +4 -4
  15. package/dist/cli/{startJob-74BLUAGF.js → startJob-BT5H6AZS.js} +4 -4
  16. package/dist/cli/{wrapper-IM3TNBSL.js → wrapper-XGGHYT3I.js} +8 -25
  17. package/dist/cli/{wrapper-IM3TNBSL.js.map → wrapper-XGGHYT3I.js.map} +4 -4
  18. package/dist/config/getShortLivedAPIToken.d.ts +6 -0
  19. package/dist/config/getShortLivedAPIToken.d.ts.map +1 -0
  20. package/dist/config/index.d.ts +4 -2
  21. package/dist/config/index.d.ts.map +1 -1
  22. package/dist/config/index.js.map +2 -2
  23. package/dist/config/loadConfig.d.ts +1 -1
  24. package/dist/config/loadConfig.d.ts.map +1 -1
  25. package/dist/config/openBrowser.d.ts +2 -0
  26. package/dist/config/openBrowser.d.ts.map +1 -0
  27. package/dist/config/promptUser.d.ts +2 -0
  28. package/dist/config/promptUser.d.ts.map +1 -0
  29. package/dist/cypress/task.js +193 -15
  30. package/dist/cypress/task.js.map +4 -4
  31. package/dist/environment/index.d.ts +1 -0
  32. package/dist/environment/index.d.ts.map +1 -1
  33. package/dist/isomorphic/types.d.ts +1 -1
  34. package/dist/isomorphic/types.d.ts.map +1 -1
  35. package/dist/playwright/index.js +193 -15
  36. package/dist/playwright/index.js.map +4 -4
  37. package/dist/storybook/browser/register.d.ts.map +1 -1
  38. package/dist/storybook/browser/register.js +6 -5
  39. package/dist/storybook/browser/register.js.map +2 -2
  40. package/package.json +1 -1
  41. package/dist/cli/createAsyncComparison-DTUUZUEX.js +0 -10
  42. package/dist/cli/package-BYHQMCNB.js +0 -7
  43. /package/dist/cli/{cancelJob-NIUI7GBR.js.map → cancelJob-UUJ3U2WI.js.map} +0 -0
  44. /package/dist/cli/{chunk-6SJAK2WZ.js.map → chunk-2N7DDGFD.js.map} +0 -0
  45. /package/dist/cli/{chunk-NNZOCTDI.js.map → chunk-CJYS7OH2.js.map} +0 -0
  46. /package/dist/cli/{chunk-BLNR2H52.js.map → chunk-L75P3SD7.js.map} +0 -0
  47. /package/dist/cli/{createAsyncComparison-DTUUZUEX.js.map → createAsyncComparison-JZL5FR2R.js.map} +0 -0
  48. /package/dist/cli/{createAsyncReport-7QIIMSNX.js.map → createAsyncReport-QM3S5HYH.js.map} +0 -0
  49. /package/dist/cli/{package-BYHQMCNB.js.map → package-LIJK2K32.js.map} +0 -0
  50. /package/dist/cli/{prepareSnapRequests-T6RBWTYD.js.map → prepareSnapRequests-7H6SFFKT.js.map} +0 -0
  51. /package/dist/cli/{startJob-74BLUAGF.js.map → startJob-BT5H6AZS.js.map} +0 -0
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-BLNR2H52.js";
4
- import "./chunk-NNZOCTDI.js";
5
- import "./chunk-FCZLLRXU.js";
3
+ } from "./chunk-L75P3SD7.js";
4
+ import "./chunk-CJYS7OH2.js";
5
+ import "./chunk-6WOLMTD3.js";
6
6
 
7
7
  // src/network/cancelJob.ts
8
8
  async function cancelJob(status, config, { beforeSha, afterSha, link, message }, logger) {
@@ -25,4 +25,4 @@ async function cancelJob(status, config, { beforeSha, afterSha, link, message },
25
25
  export {
26
26
  cancelJob as default
27
27
  };
28
- //# sourceMappingURL=cancelJob-NIUI7GBR.js.map
28
+ //# sourceMappingURL=cancelJob-UUJ3U2WI.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-BLNR2H52.js";
3
+ } from "./chunk-L75P3SD7.js";
4
4
 
5
5
  // src/network/createAsyncComparison.ts
6
6
  function assertResultIsCreateAsyncComparisonResult(result) {
@@ -56,4 +56,4 @@ async function createAsyncComparison(config, {
56
56
  export {
57
57
  createAsyncComparison
58
58
  };
59
- //# sourceMappingURL=chunk-6SJAK2WZ.js.map
59
+ //# sourceMappingURL=chunk-2N7DDGFD.js.map
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "happo",
4
- version: "6.0.6",
4
+ version: "6.1.0",
5
5
  description: "Catch unexpected visual and accessibility changes and UI bugs",
6
6
  license: "MIT",
7
7
  repository: {
@@ -184,4 +184,4 @@ var package_default = {
184
184
  export {
185
185
  package_default
186
186
  };
187
- //# sourceMappingURL=chunk-FCZLLRXU.js.map
187
+ //# sourceMappingURL=chunk-6WOLMTD3.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.0.6\",\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 ],\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\": \"./scripts/build.ts\",\n \"build:types\": \"pnpm tsc --pretty\",\n \"build:watch\": \"tsc --build --watch\",\n \"clean\": \"rm -rf dist tmp/tsc tmp/happo-custom\",\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\": \"^9.36.0\",\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\": \"^27.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 \"@types/serve-handler\": \"^6.1.4\",\n \"cypress\": \"^15.5.0\",\n \"esbuild\": \"^0.27.0\",\n \"eslint\": \"^9.36.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-compat\": \"^6.0.2\",\n \"eslint-plugin-depend\": \"^1.3.1\",\n \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n \"eslint-plugin-unicorn\": \"^62.0.0\",\n \"jiti\": \"^2.6.0\",\n \"jsdom\": \"^27.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 \"serve-handler\": \"^6.1.6\",\n \"storybook\": \"^10.0.1\",\n \"typescript\": \"^5.9.2\",\n \"typescript-eslint\": \"^8.44.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\"\n }\n}\n"],
4
+ "sourcesContent": ["{\n \"name\": \"happo\",\n \"version\": \"6.1.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 ],\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\": \"./scripts/build.ts\",\n \"build:types\": \"pnpm tsc --pretty\",\n \"build:watch\": \"tsc --build --watch\",\n \"clean\": \"rm -rf dist tmp/tsc tmp/happo-custom\",\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\": \"^9.36.0\",\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\": \"^27.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 \"@types/serve-handler\": \"^6.1.4\",\n \"cypress\": \"^15.5.0\",\n \"esbuild\": \"^0.27.0\",\n \"eslint\": \"^9.36.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-compat\": \"^6.0.2\",\n \"eslint-plugin-depend\": \"^1.3.1\",\n \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n \"eslint-plugin-unicorn\": \"^62.0.0\",\n \"jiti\": \"^2.6.0\",\n \"jsdom\": \"^27.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 \"serve-handler\": \"^6.1.6\",\n \"storybook\": \"^10.0.1\",\n \"typescript\": \"^5.9.2\",\n \"typescript-eslint\": \"^8.44.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\"\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "./chunk-FCZLLRXU.js";
3
+ } from "./chunk-6WOLMTD3.js";
4
4
 
5
5
  // src/network/fetchWithRetry.ts
6
6
  import asyncRetry from "async-retry";
@@ -93,4 +93,4 @@ async function fetchWithRetry(url, {
93
93
  export {
94
94
  fetchWithRetry
95
95
  };
96
- //# sourceMappingURL=chunk-NNZOCTDI.js.map
96
+ //# sourceMappingURL=chunk-CJYS7OH2.js.map
@@ -0,0 +1,24 @@
1
+ // src/network/startServer.ts
2
+ import http from "node:http";
3
+ function startServer(requestHandler, { port } = {}) {
4
+ return new Promise((resolve) => {
5
+ const server = http.createServer(requestHandler);
6
+ server.listen(port, () => {
7
+ const address = server.address();
8
+ if (!address || typeof address === "string") {
9
+ throw new Error("Expected server address to be AddressInfo");
10
+ }
11
+ resolve({
12
+ close: () => new Promise(
13
+ (resolve2, reject) => server.close((err) => err ? reject(err) : resolve2())
14
+ ),
15
+ port: address.port
16
+ });
17
+ });
18
+ });
19
+ }
20
+
21
+ export {
22
+ startServer
23
+ };
24
+ //# sourceMappingURL=chunk-JTRP4JVC.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/network/startServer.ts"],
4
+ "sourcesContent": ["import http from 'node:http';\n\nexport interface ServerInfo {\n close: () => Promise<void>;\n port: number;\n}\n\nexport default function startServer(\n requestHandler: (req: http.IncomingMessage, res: http.ServerResponse) => void,\n { port }: { port?: number | undefined } = {},\n): Promise<ServerInfo> {\n return new Promise((resolve) => {\n const server = http.createServer(requestHandler);\n server.listen(port, () => {\n const address = server.address();\n if (!address || typeof address === 'string') {\n throw new Error('Expected server address to be AddressInfo');\n }\n resolve({\n close: () =>\n new Promise((resolve, reject) =>\n server.close((err) => (err ? reject(err) : resolve())),\n ),\n port: address.port,\n });\n });\n });\n}\n"],
5
+ "mappings": ";AAAA,OAAO,UAAU;AAOF,SAAR,YACL,gBACA,EAAE,KAAK,IAAmC,CAAC,GACtB;AACrB,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,SAAS,KAAK,aAAa,cAAc;AAC/C,WAAO,OAAO,MAAM,MAAM;AACxB,YAAM,UAAU,OAAO,QAAQ;AAC/B,UAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AACA,cAAQ;AAAA,QACN,OAAO,MACL,IAAI;AAAA,UAAQ,CAACA,UAAS,WACpB,OAAO,MAAM,CAAC,QAAS,MAAM,OAAO,GAAG,IAAIA,SAAQ,CAAE;AAAA,QACvD;AAAA,QACF,MAAM,QAAQ;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;",
6
+ "names": ["resolve"]
7
+ }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  fetchWithRetry
3
- } from "./chunk-NNZOCTDI.js";
3
+ } from "./chunk-CJYS7OH2.js";
4
4
 
5
5
  // src/network/makeHappoAPIRequest.ts
6
6
  import { SignJWT } from "jose";
@@ -48,4 +48,4 @@ async function makeHappoAPIRequest({ url, path, method = "GET", formData, body }
48
48
  export {
49
49
  makeHappoAPIRequest
50
50
  };
51
- //# sourceMappingURL=chunk-BLNR2H52.js.map
51
+ //# sourceMappingURL=chunk-L75P3SD7.js.map
@@ -0,0 +1,10 @@
1
+ import {
2
+ createAsyncComparison
3
+ } from "./chunk-2N7DDGFD.js";
4
+ import "./chunk-L75P3SD7.js";
5
+ import "./chunk-CJYS7OH2.js";
6
+ import "./chunk-6WOLMTD3.js";
7
+ export {
8
+ createAsyncComparison as default
9
+ };
10
+ //# sourceMappingURL=createAsyncComparison-JZL5FR2R.js.map
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-BLNR2H52.js";
4
- import "./chunk-NNZOCTDI.js";
5
- import "./chunk-FCZLLRXU.js";
3
+ } from "./chunk-L75P3SD7.js";
4
+ import "./chunk-CJYS7OH2.js";
5
+ import "./chunk-6WOLMTD3.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-7QIIMSNX.js.map
41
+ //# sourceMappingURL=createAsyncReport-QM3S5HYH.js.map
package/dist/cli/main.js CHANGED
@@ -1,9 +1,12 @@
1
+ import {
2
+ startServer
3
+ } from "./chunk-JTRP4JVC.js";
1
4
  import {
2
5
  fetchWithRetry
3
- } from "./chunk-NNZOCTDI.js";
6
+ } from "./chunk-CJYS7OH2.js";
4
7
  import {
5
8
  package_default
6
- } from "./chunk-FCZLLRXU.js";
9
+ } from "./chunk-6WOLMTD3.js";
7
10
 
8
11
  // src/cli/index.ts
9
12
  import path2 from "node:path";
@@ -12,6 +15,145 @@ import { parseArgs } from "node:util";
12
15
  // src/config/loadConfig.ts
13
16
  import fs from "node:fs";
14
17
  import { any as findAny } from "empathic/find";
18
+
19
+ // src/config/openBrowser.ts
20
+ import { exec } from "node:child_process";
21
+ import { promisify } from "node:util";
22
+ var execAsync = promisify(exec);
23
+ function openBrowser(url) {
24
+ const platform = process.platform;
25
+ let command;
26
+ if (platform === "darwin") {
27
+ command = `open "${url}"`;
28
+ } else if (platform === "win32") {
29
+ command = `start "" "${url}"`;
30
+ } else {
31
+ command = `xdg-open "${url}"`;
32
+ }
33
+ return execAsync(command).then(() => {
34
+ });
35
+ }
36
+
37
+ // src/config/promptUser.ts
38
+ import { createInterface } from "node:readline";
39
+ function promptUser(message) {
40
+ return new Promise((resolve, reject) => {
41
+ const rl = createInterface({
42
+ input: process.stdin,
43
+ output: process.stdout
44
+ });
45
+ rl.question(message, (answer) => {
46
+ rl.close();
47
+ if (answer.trim() === "") {
48
+ resolve();
49
+ } else {
50
+ reject(new Error("User cancelled authentication"));
51
+ }
52
+ });
53
+ });
54
+ }
55
+
56
+ // src/config/getShortLivedAPIToken.ts
57
+ var VALID_HEX_REGEX = /^[0-9a-fA-F]+$/;
58
+ function createHTML(endpoint, phase) {
59
+ return `<!DOCTYPE html>
60
+ <html lang="en">
61
+ <head>
62
+ <title>Happo CLI Authentication</title>
63
+ <meta charset="utf-8">
64
+ <meta name="viewport" content="width=device-width, initial-scale=1">
65
+ <script type="text/javascript">
66
+ const message = { type: 'happo-cli-auth', payload: { phase: '${phase}' } };
67
+ // Use the exact origin of the parent page
68
+ window.parent.postMessage(message, '${endpoint}');
69
+ </script>
70
+ </head>
71
+ <body>
72
+ <main>
73
+ <h1>Happo CLI Authentication</h1>
74
+ <p>Authentication successful!</p>
75
+ </main>
76
+ </body>
77
+ </html>`;
78
+ }
79
+ function validateKeyAndSecret(args) {
80
+ const { key, secret } = args;
81
+ if (!key) {
82
+ return false;
83
+ }
84
+ if (!secret) {
85
+ return false;
86
+ }
87
+ if (key.length < 10 || key.length > 64) {
88
+ return false;
89
+ }
90
+ if (secret.length < 20 || secret.length > 256) {
91
+ return false;
92
+ }
93
+ if (!VALID_HEX_REGEX.test(key)) {
94
+ return false;
95
+ }
96
+ if (!VALID_HEX_REGEX.test(secret)) {
97
+ return false;
98
+ }
99
+ return true;
100
+ }
101
+ async function getShortLivedAPIToken(endpoint, logger) {
102
+ if (!process.stdin.isTTY) {
103
+ return null;
104
+ }
105
+ await promptUser("Press <Enter> to authenticate in the browser");
106
+ let resolveCallback;
107
+ let rejectCallback;
108
+ const callbackPromise = new Promise(
109
+ (resolve, reject) => {
110
+ resolveCallback = resolve;
111
+ rejectCallback = reject;
112
+ }
113
+ );
114
+ const serverInfo = await startServer((req, res) => {
115
+ const url = new URL(req.url ?? "", `http://localhost:${serverInfo.port}`);
116
+ if (url.pathname === "/callback") {
117
+ const token = {
118
+ key: url.searchParams.get("key"),
119
+ secret: url.searchParams.get("secret")
120
+ };
121
+ const ping = url.searchParams.get("ping");
122
+ if (ping) {
123
+ res.writeHead(200, { "Content-Type": "text/html" });
124
+ res.end(createHTML(endpoint, "auth"));
125
+ return;
126
+ }
127
+ if (validateKeyAndSecret(token)) {
128
+ res.writeHead(200, { "Content-Type": "text/html" });
129
+ res.end(createHTML(endpoint, "done"));
130
+ return resolveCallback(token);
131
+ }
132
+ res.writeHead(400, { "Content-Type": "text/html" });
133
+ res.end("Bad request");
134
+ return rejectCallback(new Error("Missing key or secret in callback"));
135
+ }
136
+ res.writeHead(404, { "Content-Type": "text/plain" });
137
+ res.end("Not found");
138
+ });
139
+ const callbackUrl = `http://localhost:${serverInfo.port}/callback`;
140
+ const authUrl = `${endpoint}/cli/auth?callbackUrl=${encodeURIComponent(callbackUrl)}`;
141
+ try {
142
+ console.log(`Opening URL: ${authUrl}`);
143
+ await openBrowser(authUrl);
144
+ const result = await callbackPromise;
145
+ return result;
146
+ } catch (error) {
147
+ logger.error(
148
+ `Failed to authenticate: ${error instanceof Error ? error.message : String(error)}`
149
+ );
150
+ return null;
151
+ } finally {
152
+ await serverInfo.close();
153
+ }
154
+ }
155
+
156
+ // src/config/loadConfig.ts
15
157
  var CONFIG_FILENAMES = [
16
158
  "happo.config.js",
17
159
  "happo.config.mjs",
@@ -58,6 +200,30 @@ async function getPullRequestSecret(endpoint, prUrl, logger) {
58
200
  assertIsPullRequestTokenResponse(json);
59
201
  return json.secret;
60
202
  }
203
+ async function getFallbackApiToken(endpoint, environment, logger) {
204
+ if (environment?.link) {
205
+ try {
206
+ const pullRequestSecret = await getPullRequestSecret(
207
+ endpoint,
208
+ environment.link,
209
+ logger
210
+ );
211
+ return {
212
+ key: environment.link,
213
+ secret: pullRequestSecret
214
+ };
215
+ } catch {
216
+ logger.log(
217
+ `Failed to obtain temporary pull-request token for URL: ${environment.link}`
218
+ );
219
+ }
220
+ }
221
+ if (!environment?.ci) {
222
+ const shortLivedApiToken = await getShortLivedAPIToken(endpoint, logger);
223
+ return shortLivedApiToken ?? void 0;
224
+ }
225
+ return void 0;
226
+ }
61
227
  async function loadConfigFile(configFilePath, environment, logger = console) {
62
228
  try {
63
229
  const stats = await fs.promises.stat(configFilePath);
@@ -82,24 +248,21 @@ async function loadConfigFile(configFilePath, environment, logger = console) {
82
248
  config.apiKey ? null : "apiKey",
83
249
  config.apiSecret ? null : "apiSecret"
84
250
  ].filter(Boolean).map((key) => `\`${key}\``).join(" and ");
85
- if (!environment?.link) {
251
+ logger.log(
252
+ `Missing ${missing} in Happo config. Attempting alternative authentication.`
253
+ );
254
+ const fallbackApiToken = await getFallbackApiToken(
255
+ config.endpoint || DEFAULT_ENDPOINT,
256
+ environment,
257
+ logger
258
+ );
259
+ if (!fallbackApiToken) {
86
260
  throw new Error(
87
261
  `Missing ${missing} in your Happo config. Reference yours at https://happo.io/settings`
88
262
  );
89
263
  }
90
- try {
91
- logger.log(
92
- `Missing ${missing} in Happo config. Falling back to pull-request authentication.`
93
- );
94
- config.apiKey = environment.link;
95
- config.apiSecret = await getPullRequestSecret(
96
- config.endpoint || DEFAULT_ENDPOINT,
97
- environment.link,
98
- logger
99
- );
100
- } catch (e) {
101
- throw new Error("Failed to obtain temporary pull-request token", { cause: e });
102
- }
264
+ config.apiKey = fallbackApiToken.key;
265
+ config.apiSecret = fallbackApiToken.secret;
103
266
  }
104
267
  if (!config.targets) {
105
268
  config.targets = {
@@ -513,7 +676,8 @@ async function resolveEnvironment(cliArgs, env = process.env) {
513
676
  debugMode,
514
677
  notify: cliArgs.notify,
515
678
  fallbackShas: resolveFallbackShas(cliArgs, nonNullBeforeSha),
516
- githubToken: cliArgs.githubToken
679
+ githubToken: cliArgs.githubToken,
680
+ ci: !!env.CI
517
681
  };
518
682
  if (debugMode) {
519
683
  console.log("[HAPPO] Raw environment", getRawEnv(env));
@@ -526,7 +690,7 @@ async function resolveEnvironment(cliArgs, env = process.env) {
526
690
  import crypto2 from "node:crypto";
527
691
  import fs2 from "node:fs";
528
692
  import path from "node:path";
529
- import { createInterface } from "node:readline";
693
+ import { createInterface as createInterface2 } from "node:readline";
530
694
  import { up as findPackage } from "empathic/package";
531
695
  var SENTRY_DSN = "https://3a495ff2101313edb024de73b005398f@o108341.ingest.us.sentry.io/4510341337645056";
532
696
  var MAX_STACK_FRAMES = 50;
@@ -694,7 +858,7 @@ async function readContextLines(filePath, lineNumber, contextLines = 5) {
694
858
  let context_line;
695
859
  const post_context = [];
696
860
  const fileStream = fs2.createReadStream(cleanPath, { encoding: "utf8" });
697
- const rl = createInterface({
861
+ const rl = createInterface2({
698
862
  input: fileStream,
699
863
  crlfDelay: Infinity
700
864
  });
@@ -807,7 +971,7 @@ function createReporter(opts = {}) {
807
971
 
808
972
  // src/cli/index.ts
809
973
  async function getVersion() {
810
- const packageJson = await import("./package-BYHQMCNB.js");
974
+ const packageJson = await import("./package-LIJK2K32.js");
811
975
  return packageJson.default.version;
812
976
  }
813
977
  function parseDashdashCommandParts(rawArgs) {
@@ -997,10 +1161,10 @@ async function main(rawArgs = process.argv, logger = console) {
997
1161
  async function handleDefaultCommand(config, environment, logger) {
998
1162
  logger.log("Running happo tests...");
999
1163
  const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] = await Promise.all([
1000
- (await import("./startJob-74BLUAGF.js")).default,
1001
- (await import("./createAsyncComparison-DTUUZUEX.js")).default,
1002
- (await import("./createAsyncReport-7QIIMSNX.js")).default,
1003
- (await import("./prepareSnapRequests-T6RBWTYD.js")).default
1164
+ (await import("./startJob-BT5H6AZS.js")).default,
1165
+ (await import("./createAsyncComparison-JZL5FR2R.js")).default,
1166
+ (await import("./createAsyncReport-QM3S5HYH.js")).default,
1167
+ (await import("./prepareSnapRequests-7H6SFFKT.js")).default
1004
1168
  ]);
1005
1169
  await startJob(config, environment, logger);
1006
1170
  try {
@@ -1022,7 +1186,7 @@ async function handleDefaultCommand(config, environment, logger) {
1022
1186
  }
1023
1187
  } catch (e) {
1024
1188
  logger.error(e instanceof Error ? e.message : String(e), e);
1025
- const cancelJob = (await import("./cancelJob-NIUI7GBR.js")).default;
1189
+ const cancelJob = (await import("./cancelJob-UUJ3U2WI.js")).default;
1026
1190
  await cancelJob("failure", config, environment, logger);
1027
1191
  process.exitCode = 1;
1028
1192
  return;
@@ -1033,7 +1197,7 @@ async function handleFinalizeCommand(config, environment, logger) {
1033
1197
  logger.log("Config:", config);
1034
1198
  logger.log("Environment:", environment);
1035
1199
  try {
1036
- const finalizeAll = (await import("./wrapper-IM3TNBSL.js")).finalizeAll;
1200
+ const finalizeAll = (await import("./wrapper-XGGHYT3I.js")).finalizeAll;
1037
1201
  await finalizeAll({ happoConfig: config, environment, logger });
1038
1202
  } catch (e) {
1039
1203
  logger.error(e instanceof Error ? e.message : String(e), e);
@@ -1062,7 +1226,7 @@ async function handleE2ECommand(config, environment, dashdashCommandParts, confi
1062
1226
  logger.log("Config:", config);
1063
1227
  logger.log("Environment:", environment);
1064
1228
  logger.log("Dashdash command parts:", dashdashCommandParts);
1065
- const runWithWrapper = (await import("./wrapper-IM3TNBSL.js")).default;
1229
+ const runWithWrapper = (await import("./wrapper-XGGHYT3I.js")).default;
1066
1230
  const exitCode = await runWithWrapper(
1067
1231
  dashdashCommandParts,
1068
1232
  config,