happo 6.0.0-beta.7 → 6.0.0-beta.8

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 (29) hide show
  1. package/dist/cli/{cancelJob-ZSTC24AN.js → cancelJob-Q5NR5HV2.js} +3 -3
  2. package/dist/cli/{chunk-HCMCNDII.js → chunk-AK57NWGE.js} +2 -2
  3. package/dist/cli/{chunk-MQN57GVD.js → chunk-RWJCN6TI.js} +2 -2
  4. package/dist/cli/{chunk-MQN57GVD.js.map → chunk-RWJCN6TI.js.map} +1 -1
  5. package/dist/cli/{chunk-33S3P2UT.js → chunk-SCCWUPCL.js} +2 -2
  6. package/dist/cli/createAsyncComparison-K5OAEZI3.js +9 -0
  7. package/dist/cli/{createAsyncReport-MUPQH5YG.js → createAsyncReport-IQFYMH2A.js} +3 -3
  8. package/dist/cli/index.js +8 -8
  9. package/dist/cli/package-ZXLUATPW.js +7 -0
  10. package/dist/cli/{prepareSnapRequests-KXP2GCXB.js → prepareSnapRequests-TKNXRSQO.js} +7 -8
  11. package/dist/cli/{prepareSnapRequests-KXP2GCXB.js.map → prepareSnapRequests-TKNXRSQO.js.map} +2 -2
  12. package/dist/cli/{startJob-4EQXSOMD.js → startJob-3MAGI2AV.js} +3 -3
  13. package/dist/cli/{wrapper-GHIE52PM.js → wrapper-RNK4FFFV.js} +4 -4
  14. package/dist/cypress/task.js +5 -6
  15. package/dist/cypress/task.js.map +2 -2
  16. package/dist/playwright/index.js +5 -6
  17. package/dist/playwright/index.js.map +2 -2
  18. package/dist/utils/deterministicArchive.d.ts.map +1 -1
  19. package/package.json +1 -1
  20. package/dist/cli/createAsyncComparison-Y3V5JEEI.js +0 -9
  21. package/dist/cli/package-CZSERZWI.js +0 -7
  22. /package/dist/cli/{cancelJob-ZSTC24AN.js.map → cancelJob-Q5NR5HV2.js.map} +0 -0
  23. /package/dist/cli/{chunk-HCMCNDII.js.map → chunk-AK57NWGE.js.map} +0 -0
  24. /package/dist/cli/{chunk-33S3P2UT.js.map → chunk-SCCWUPCL.js.map} +0 -0
  25. /package/dist/cli/{createAsyncComparison-Y3V5JEEI.js.map → createAsyncComparison-K5OAEZI3.js.map} +0 -0
  26. /package/dist/cli/{createAsyncReport-MUPQH5YG.js.map → createAsyncReport-IQFYMH2A.js.map} +0 -0
  27. /package/dist/cli/{package-CZSERZWI.js.map → package-ZXLUATPW.js.map} +0 -0
  28. /package/dist/cli/{startJob-4EQXSOMD.js.map → startJob-3MAGI2AV.js.map} +0 -0
  29. /package/dist/cli/{wrapper-GHIE52PM.js.map → wrapper-RNK4FFFV.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-HCMCNDII.js";
4
- import "./chunk-MQN57GVD.js";
3
+ } from "./chunk-AK57NWGE.js";
4
+ import "./chunk-RWJCN6TI.js";
5
5
 
6
6
  // src/network/cancelJob.ts
7
7
  async function cancelJob(status, config, { beforeSha, afterSha, link, message }, logger) {
@@ -24,4 +24,4 @@ async function cancelJob(status, config, { beforeSha, afterSha, link, message },
24
24
  export {
25
25
  cancelJob as default
26
26
  };
27
- //# sourceMappingURL=cancelJob-ZSTC24AN.js.map
27
+ //# sourceMappingURL=cancelJob-Q5NR5HV2.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "./chunk-MQN57GVD.js";
3
+ } from "./chunk-RWJCN6TI.js";
4
4
 
5
5
  // src/network/makeHappoAPIRequest.ts
6
6
  import { SignJWT } from "jose";
@@ -138,4 +138,4 @@ async function makeHappoAPIRequest({ url, path, method = "GET", formData, body }
138
138
  export {
139
139
  makeHappoAPIRequest
140
140
  };
141
- //# sourceMappingURL=chunk-HCMCNDII.js.map
141
+ //# sourceMappingURL=chunk-AK57NWGE.js.map
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "happo",
4
- version: "6.0.0-beta.7",
4
+ version: "6.0.0-beta.8",
5
5
  description: "Visual regression testing and accessibility testing",
6
6
  license: "MIT",
7
7
  repository: {
@@ -165,4 +165,4 @@ var package_default = {
165
165
  export {
166
166
  package_default
167
167
  };
168
- //# sourceMappingURL=chunk-MQN57GVD.js.map
168
+ //# sourceMappingURL=chunk-RWJCN6TI.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.0-beta.7\",\n \"description\": \"Visual regression testing and accessibility testing\",\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/index.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/index.js -c ./happoconfigs/happo.custom.config.ts\",\n \"test:cypress\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.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/index.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/index.js -c ./happoconfigs/happo.storybook.config.ts\",\n \"test:pages\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.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.25.10\",\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 \"mime-types\": \"^3.0.1\",\n \"p-all\": \"^5.0.1\",\n \"srcset\": \"^5.0.2\"\n },\n \"keywords\": [\n \"accessibility\",\n \"cypress\",\n \"playwright\",\n \"regression\",\n \"storybook\",\n \"testing\",\n \"ui\",\n \"visual regression\",\n \"visual\"\n ],\n \"engines\": {\n \"node\": \">=22\"\n }\n}\n"],
4
+ "sourcesContent": ["{\n \"name\": \"happo\",\n \"version\": \"6.0.0-beta.8\",\n \"description\": \"Visual regression testing and accessibility testing\",\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/index.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/index.js -c ./happoconfigs/happo.custom.config.ts\",\n \"test:cypress\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.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/index.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/index.js -c ./happoconfigs/happo.storybook.config.ts\",\n \"test:pages\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.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.25.10\",\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 \"mime-types\": \"^3.0.1\",\n \"p-all\": \"^5.0.1\",\n \"srcset\": \"^5.0.2\"\n },\n \"keywords\": [\n \"accessibility\",\n \"cypress\",\n \"playwright\",\n \"regression\",\n \"storybook\",\n \"testing\",\n \"ui\",\n \"visual regression\",\n \"visual\"\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
  makeHappoAPIRequest
3
- } from "./chunk-HCMCNDII.js";
3
+ } from "./chunk-AK57NWGE.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-33S3P2UT.js.map
59
+ //# sourceMappingURL=chunk-SCCWUPCL.js.map
@@ -0,0 +1,9 @@
1
+ import {
2
+ createAsyncComparison
3
+ } from "./chunk-SCCWUPCL.js";
4
+ import "./chunk-AK57NWGE.js";
5
+ import "./chunk-RWJCN6TI.js";
6
+ export {
7
+ createAsyncComparison as default
8
+ };
9
+ //# sourceMappingURL=createAsyncComparison-K5OAEZI3.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-HCMCNDII.js";
4
- import "./chunk-MQN57GVD.js";
3
+ } from "./chunk-AK57NWGE.js";
4
+ import "./chunk-RWJCN6TI.js";
5
5
 
6
6
  // src/network/createAsyncReport.ts
7
7
  function assertResultIsCreateAsyncReportResult(result) {
@@ -37,4 +37,4 @@ async function createAsyncReport(snapRequestIds, config, { afterSha, link, messa
37
37
  export {
38
38
  createAsyncReport as default
39
39
  };
40
- //# sourceMappingURL=createAsyncReport-MUPQH5YG.js.map
40
+ //# sourceMappingURL=createAsyncReport-IQFYMH2A.js.map
package/dist/cli/index.js CHANGED
@@ -445,7 +445,7 @@ async function resolveEnvironment(cliArgs, env = process.env) {
445
445
 
446
446
  // src/cli/index.ts
447
447
  async function getVersion() {
448
- const packageJson = await import("./package-CZSERZWI.js");
448
+ const packageJson = await import("./package-ZXLUATPW.js");
449
449
  return packageJson.default.version;
450
450
  }
451
451
  function parseDashdashCommandParts(rawArgs) {
@@ -601,10 +601,10 @@ async function main(rawArgs = process.argv, logger = console) {
601
601
  async function handleDefaultCommand(config, environment, logger) {
602
602
  logger.log("Running happo tests...");
603
603
  const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] = await Promise.all([
604
- (await import("./startJob-4EQXSOMD.js")).default,
605
- (await import("./createAsyncComparison-Y3V5JEEI.js")).default,
606
- (await import("./createAsyncReport-MUPQH5YG.js")).default,
607
- (await import("./prepareSnapRequests-KXP2GCXB.js")).default
604
+ (await import("./startJob-3MAGI2AV.js")).default,
605
+ (await import("./createAsyncComparison-K5OAEZI3.js")).default,
606
+ (await import("./createAsyncReport-IQFYMH2A.js")).default,
607
+ (await import("./prepareSnapRequests-TKNXRSQO.js")).default
608
608
  ]);
609
609
  await startJob(config, environment, logger);
610
610
  try {
@@ -626,7 +626,7 @@ async function handleDefaultCommand(config, environment, logger) {
626
626
  }
627
627
  } catch (e) {
628
628
  logger.error(e instanceof Error ? e.message : String(e), e);
629
- const cancelJob = (await import("./cancelJob-ZSTC24AN.js")).default;
629
+ const cancelJob = (await import("./cancelJob-Q5NR5HV2.js")).default;
630
630
  await cancelJob("failure", config, environment, logger);
631
631
  process.exitCode = 1;
632
632
  return;
@@ -637,7 +637,7 @@ async function handleFinalizeCommand(config, environment, logger) {
637
637
  logger.log("Config:", config);
638
638
  logger.log("Environment:", environment);
639
639
  try {
640
- const finalizeAll = (await import("./wrapper-GHIE52PM.js")).finalizeAll;
640
+ const finalizeAll = (await import("./wrapper-RNK4FFFV.js")).finalizeAll;
641
641
  await finalizeAll({ happoConfig: config, environment, logger });
642
642
  } catch (e) {
643
643
  logger.error(e instanceof Error ? e.message : String(e), e);
@@ -666,7 +666,7 @@ async function handleE2ECommand(config, environment, dashdashCommandParts, confi
666
666
  logger.log("Config:", config);
667
667
  logger.log("Environment:", environment);
668
668
  logger.log("Dashdash command parts:", dashdashCommandParts);
669
- const runWithWrapper = (await import("./wrapper-GHIE52PM.js")).default;
669
+ const runWithWrapper = (await import("./wrapper-RNK4FFFV.js")).default;
670
670
  const exitCode = await runWithWrapper(
671
671
  dashdashCommandParts,
672
672
  config,
@@ -0,0 +1,7 @@
1
+ import {
2
+ package_default
3
+ } from "./chunk-RWJCN6TI.js";
4
+ export {
5
+ package_default as default
6
+ };
7
+ //# sourceMappingURL=package-ZXLUATPW.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-HCMCNDII.js";
4
- import "./chunk-MQN57GVD.js";
3
+ } from "./chunk-AK57NWGE.js";
4
+ import "./chunk-RWJCN6TI.js";
5
5
 
6
6
  // src/network/prepareSnapRequests.ts
7
7
  import fs5 from "node:fs";
@@ -425,12 +425,11 @@ async function deterministicArchive(dirsAndFiles, contentToArchive = []) {
425
425
  }
426
426
  }
427
427
  for (const file of contentToArchiveSorted) {
428
- const zipEntryName = path4.basename(file.name);
429
- if (!seenFiles.has(zipEntryName)) {
428
+ if (!seenFiles.has(file.name)) {
430
429
  const data = await contentToUint8Array(file.content);
431
- entryDataList.push({ name: zipEntryName, data });
432
- entries.push({ name: zipEntryName, size: data.length });
433
- seenFiles.add(zipEntryName);
430
+ entryDataList.push({ name: file.name, data });
431
+ entries.push({ name: file.name, size: data.length });
432
+ seenFiles.add(file.name);
434
433
  }
435
434
  }
436
435
  entryDataList.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
@@ -732,4 +731,4 @@ async function prepareSnapRequests(config) {
732
731
  export {
733
732
  prepareSnapRequests as default
734
733
  };
735
- //# sourceMappingURL=prepareSnapRequests-KXP2GCXB.js.map
734
+ //# sourceMappingURL=prepareSnapRequests-TKNXRSQO.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/network/prepareSnapRequests.ts", "../../src/utils/createHash.ts", "../../src/config/RemoteBrowserTarget.ts", "../../src/storybook/index.ts", "../../src/storybook/getStorybookBuildCommandParts.ts", "../../src/storybook/getStorybookVersionFromPackageJson.ts", "../../src/utils/deterministicArchive.ts", "../../src/utils/validateArchive.ts", "../../src/utils/Logger.ts", "../../src/network/uploadAssets.ts"],
4
- "sourcesContent": ["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport RemoteBrowserTarget, {\n type ExecuteParams,\n} from '../config/RemoteBrowserTarget.ts';\nimport buildStorybookPackage from '../storybook/index.ts';\nimport deterministicArchive from '../utils/deterministicArchive.ts';\nimport Logger, { logTag } from '../utils/Logger.ts';\nimport uploadAssets from './uploadAssets.ts';\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await fs.promises.stat(path);\n return true;\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return false;\n }\n\n throw error;\n }\n}\n\nasync function createIframeHTML(\n rootDir: string,\n entryPoint: string,\n logger: Logger,\n): Promise<void> {\n const iframePath = path.join(rootDir, 'iframe.html');\n\n if (await fileExists(iframePath)) {\n logger.info(`Using existing iframe.html at '${iframePath}'`);\n return;\n }\n\n const iframeContent = `<!DOCTYPE html>\n<html lang=\"en\" dir=\"ltr\">\n <head>\n <title>Happo</title>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n </head>\n <body>\n <script src=\"${entryPoint}\"></script>\n </body>\n</html>`;\n\n await fs.promises.mkdir(rootDir, { recursive: true });\n await fs.promises.writeFile(iframePath, iframeContent);\n}\n\nasync function buildPackage(\n { integration }: ConfigWithDefaults,\n logger: Logger,\n): Promise<string> {\n if (integration.type === 'custom') {\n const { rootDir, entryPoint } = await integration.build();\n await createIframeHTML(rootDir, entryPoint, logger);\n return rootDir;\n }\n\n if (integration.type === 'storybook') {\n return await buildStorybookPackage(integration);\n }\n\n throw new Error(`Unsupported integration type: ${integration.type}`);\n}\n\nasync function validatePackage(packageDir: string): Promise<void> {\n const iframePath = path.join(packageDir, 'iframe.html');\n\n if (!(await fileExists(iframePath))) {\n throw new Error(\n `Could not find iframe.html in static package at '${iframePath}'`,\n );\n }\n}\n\nasync function preparePackage(\n config: ConfigWithDefaults,\n logger: Logger,\n): Promise<string> {\n const packageDir = await buildPackage(config, logger);\n\n await validatePackage(packageDir);\n\n const { buffer, hash } = await deterministicArchive([packageDir]);\n return await uploadAssets(\n buffer,\n {\n hash,\n logger,\n },\n config,\n );\n}\n\nexport default async function prepareSnapRequests(\n config: ConfigWithDefaults,\n): Promise<Array<number>> {\n const logger = new Logger();\n const packagePath =\n config.integration.type === 'pages'\n ? null\n : await preparePackage(config, logger);\n\n const targetNames = Object.keys(config.targets);\n const tl = targetNames.length;\n logger.info(\n `${logTag(config.project)}Generating screenshots in ${tl} target${\n tl > 1 ? 's' : ''\n }...`,\n );\n const outerStartTime = Date.now();\n const results: Array<number> = [];\n await Promise.all(\n targetNames.map(async (name) => {\n const startTime = Date.now();\n if (!config.targets[name]) {\n throw new Error(`Target ${name} not found in config`);\n }\n const target = new RemoteBrowserTarget(\n config.targets[name].type,\n config.targets[name],\n );\n const targetParams: ExecuteParams = {\n targetName: name,\n };\n if (packagePath) {\n targetParams.staticPackage = packagePath;\n }\n if (config.integration.type === 'pages') {\n targetParams.pages = config.integration.pages;\n }\n const snapRequestIds = await target.execute(targetParams, config);\n logger.start(` - ${logTag(config.project)}${name}`, { startTime });\n logger.success();\n results.push(...snapRequestIds);\n }),\n );\n logger.start(undefined, { startTime: outerStartTime });\n logger.success();\n return results;\n}\n", "import crypto from 'node:crypto';\n\n/**\n * Creates an MD5 hash of the input data\n * @param data - The data to hash (string, Buffer, or TypedArray)\n * @returns The MD5 hash as a hexadecimal string\n */\nexport default function createHash(\n data: string | Buffer | NodeJS.TypedArray,\n): string {\n return crypto.createHash('md5').update(data).digest('hex');\n}\n", "import makeHappoAPIRequest from '../network/makeHappoAPIRequest.ts';\nimport createHash from '../utils/createHash.ts';\nimport type { ConfigWithDefaults, Page, TargetWithDefaults } from './index.ts';\n\nconst VIEWPORT_PATTERN = /^([0-9]+)x([0-9]+)$/;\n\n/**\n * PageSlice is an array of pages with the extra extendsSha property.\n */\ninterface PageSlice extends Array<Page> {\n extendsSha?: string;\n}\n\ninterface Chunk {\n index: number;\n total: number;\n}\n\ninterface BoundMakeRequestParams {\n slice?: Array<unknown> | undefined;\n chunk?: Chunk | undefined;\n pageSlice?: PageSlice | undefined;\n}\n\nexport interface CSSBlock {\n id: string;\n conditional: boolean;\n css: string;\n}\n\nexport interface ExecuteParams {\n globalCSS?: string | Array<CSSBlock>;\n\n /** Path to the assets package */\n assetsPackage?: string;\n\n /** Path to the static package */\n staticPackage?: string;\n\n snapPayloads?: Array<unknown>;\n pages?: Array<Page>;\n targetName?: string;\n}\n\nfunction getPageSlices(pages: Array<Page>, chunks: number): Array<PageSlice> {\n const result: Array<PageSlice> = [];\n\n // First, split the raw pages into chunks\n const pagesPerChunk = Math.ceil(pages.length / chunks);\n for (let i = 0; i < chunks; i += 1) {\n const pageSlice = pages.slice(\n i * pagesPerChunk,\n i * pagesPerChunk + pagesPerChunk,\n );\n\n if (pageSlice.length > 0) {\n result.push(pageSlice);\n }\n }\n return result;\n}\n\nexport default class RemoteBrowserTarget {\n public readonly chunks: number;\n public readonly browserName: string;\n public readonly viewport: string;\n public readonly maxHeight: number | undefined;\n public readonly otherOptions: Record<string, unknown>;\n\n constructor(\n browserName: string,\n {\n viewport = '1024x768',\n chunks = 1,\n maxHeight,\n ...otherOptions\n }: TargetWithDefaults,\n ) {\n const viewportMatch = viewport.match(VIEWPORT_PATTERN);\n if (!viewportMatch) {\n throw new Error(\n `Invalid viewport \"${viewport}\". Here's an example of a valid one: \"1024x768\".`,\n );\n }\n\n this.chunks = chunks;\n this.browserName = browserName;\n this.viewport = viewport;\n this.maxHeight = maxHeight ?? undefined;\n this.otherOptions = otherOptions;\n }\n\n async execute(\n {\n globalCSS,\n assetsPackage,\n staticPackage,\n snapPayloads,\n pages,\n targetName,\n }: ExecuteParams,\n config: ConfigWithDefaults,\n ): Promise<Array<number>> {\n const boundMakeRequest = async ({\n slice,\n chunk,\n pageSlice,\n }: BoundMakeRequestParams): Promise<number> => {\n const payloadString = JSON.stringify({\n viewport: this.viewport,\n maxHeight: this.maxHeight,\n ...this.otherOptions,\n globalCSS,\n snapPayloads: slice,\n chunk,\n staticPackage,\n assetsPackage,\n pages: pageSlice,\n extendsSha: pageSlice ? pageSlice.extendsSha : undefined,\n });\n\n const payloadHash = createHash(\n payloadString + (pageSlice ? Math.random() : ''),\n );\n\n const formData: Record<string, string | File | undefined> = {\n type:\n pageSlice && pageSlice.extendsSha\n ? 'extends-report'\n : `browser-${this.browserName}`,\n targetName,\n payloadHash,\n payload: new File([payloadString], 'payload.json', {\n type: 'application/json',\n }),\n };\n\n if (pageSlice && pageSlice.extendsSha) {\n formData.extendsSha = pageSlice.extendsSha;\n }\n\n const requestResult = await makeHappoAPIRequest(\n {\n path: `/api/snap-requests?payloadHash=${payloadHash}`,\n method: 'POST',\n json: true,\n formData,\n },\n config,\n { retryCount: 5 },\n );\n\n if (!requestResult) {\n throw new Error('No requestResult');\n }\n\n if (!('requestId' in requestResult)) {\n throw new Error('No requestId in requestResult');\n }\n\n if (typeof requestResult.requestId !== 'number') {\n throw new TypeError('requestId is not a number');\n }\n\n return requestResult.requestId;\n };\n\n const requestIds: Array<number> = [];\n\n if (staticPackage) {\n for (let i = 0; i < this.chunks; i += 1) {\n // We `await` here inside the loop to avoid POSTing all payloads to the\n // server at the same time (thus reducing load a little).\n const requestId = await boundMakeRequest({\n chunk: { index: i, total: this.chunks },\n });\n requestIds.push(requestId);\n }\n } else if (pages) {\n for (const pageSlice of getPageSlices(pages, this.chunks)) {\n // We `await` here inside the loop to avoid POSTing all payloads to the\n // server at the same time (thus reducing load a little).\n const requestId = await boundMakeRequest({\n pageSlice,\n });\n requestIds.push(requestId);\n }\n } else {\n const snapsPerChunk = Math.ceil((snapPayloads?.length ?? 0) / this.chunks);\n for (let i = 0; i < this.chunks; i += 1) {\n const slice = snapPayloads?.slice(\n i * snapsPerChunk,\n i * snapsPerChunk + snapsPerChunk,\n );\n\n // We `await` here inside the loop to avoid POSTing all payloads to the\n // server at the same time (thus reducing load a little).\n const requestId = await boundMakeRequest({\n slice,\n });\n requestIds.push(requestId);\n }\n }\n\n return requestIds;\n }\n}\n", "import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { StorybookIntegration } from '../config/index.ts';\nimport getStorybookBuildCommandParts from './getStorybookBuildCommandParts.ts';\nimport getStorybookVersionFromPackageJson from './getStorybookVersionFromPackageJson.ts';\nimport type { SkipItems } from './isomorphic/types.ts';\n\nconst { HAPPO_DEBUG } = process.env;\n\nfunction assertSkippedIsSkipItems(skipped: unknown): asserts skipped is SkipItems {\n if (!Array.isArray(skipped)) {\n throw new TypeError(`The \\`skip\\` option didn't provide an array`);\n }\n\n if (skipped.some((item) => !item.component || !item.variant)) {\n throw new Error(\n `Each item provided by the \\`skip\\` option needs a \\`component\\` and a \\`variant\\` property`,\n );\n }\n}\n\nfunction resolveBuildCommandParts() {\n const version = getStorybookVersionFromPackageJson();\n\n if (version < 9) {\n throw new Error(\n `Storybook v${version} is not supported. Please update storybook to v9 or later.`,\n );\n }\n\n return getStorybookBuildCommandParts();\n}\n\nfunction buildStorybook({\n configDir,\n staticDir,\n outputDir,\n}: {\n configDir: string;\n staticDir?: string | undefined;\n outputDir: string;\n}): Promise<void> {\n return new Promise((resolve, reject) => {\n fs.rmSync(outputDir, { recursive: true, force: true });\n\n const buildCommandParts = resolveBuildCommandParts();\n\n if (!buildCommandParts[0]) {\n throw new Error('Failed to resolve build command parts');\n }\n\n const params = [\n ...buildCommandParts,\n '--output-dir',\n outputDir,\n '--config-dir',\n configDir,\n ];\n\n if (staticDir) {\n params.push('--static-dir', staticDir);\n }\n\n let binary = fs.existsSync('yarn.lock') ? 'yarn' : 'npx';\n\n if (buildCommandParts[0].includes('node_modules')) {\n binary = buildCommandParts[0];\n params.shift(); // remove binary from params\n }\n\n if (HAPPO_DEBUG) {\n console.log(`[happo] Using build command \\`${binary} ${params.join(' ')}\\``);\n }\n\n const spawned = spawn(binary, params, {\n stdio: 'inherit',\n shell: process.platform == 'win32',\n });\n\n spawned.on('exit', (code) => {\n if (code === 0) {\n try {\n fs.unlinkSync(path.join(outputDir, 'project.json'));\n } catch (error) {\n console.warn(\n `Ignoring error when attempting to remove project.json: ${error}`,\n );\n }\n resolve();\n } else {\n reject(new Error('Failed to build static storybook package'));\n }\n });\n });\n}\n\nexport default async function buildStorybookPackage({\n configDir = '.storybook',\n staticDir,\n outputDir = '.out',\n usePrebuiltPackage = false,\n skip,\n}: Omit<StorybookIntegration, 'type'>): Promise<string> {\n if (!usePrebuiltPackage) {\n await buildStorybook({ configDir, staticDir, outputDir });\n }\n\n const iframePath = path.join(outputDir, 'iframe.html');\n if (!fs.existsSync(iframePath)) {\n throw new Error(\n 'Failed to build static storybook package (missing iframe.html)',\n );\n }\n\n try {\n const skipped =\n typeof skip === 'function' ? await skip() : Array.isArray(skip) ? skip : [];\n\n assertSkippedIsSkipItems(skipped);\n\n const iframeContent = fs.readFileSync(iframePath, 'utf8');\n\n fs.writeFileSync(\n iframePath,\n iframeContent.replace(\n '<head>',\n `<head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script type=\"text/javascript\">window.__IS_HAPPO_RUN = true;</script>\n <script type=\"text/javascript\">window.happoSkipped = ${JSON.stringify(\n skipped,\n )};</script>\n `,\n ),\n );\n\n // Tell happo where the files are located.\n return outputDir;\n } catch (e) {\n console.error(e);\n throw e;\n }\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\n\nconst { HAPPO_DEBUG } = process.env;\n\nexport default function getStorybookBuildCommandParts(\n packageJsonPath: string = path.join(process.cwd(), 'package.json'),\n): [string, string] {\n try {\n const data = fs.readFileSync(packageJsonPath, 'utf8');\n const packageJson = JSON.parse(data);\n\n if (packageJson.scripts.storybook) {\n if (HAPPO_DEBUG) {\n console.log(\n '[happo] Found `storybook` script in package.json. Will attempt to use binary found at `node_modules/.bin/storybook` instead',\n );\n }\n\n const pathToStorybookCommand = path.join(\n process.cwd(),\n 'node_modules',\n '.bin',\n 'storybook',\n );\n\n if (fs.existsSync(pathToStorybookCommand)) {\n return [pathToStorybookCommand, 'build'];\n }\n }\n } catch (e) {\n if (HAPPO_DEBUG) {\n console.log(\n '[happo] Caught error when resolving Storybook build command parts. Will use default.',\n e,\n );\n }\n }\n\n return ['storybook', 'build'];\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\n\nexport default function getStorybookVersionFromPackageJson(\n packageJsonPath: string = path.join(process.cwd(), 'package.json'),\n): number {\n const data = fs.readFileSync(packageJsonPath, 'utf8');\n const packageJson = JSON.parse(data);\n\n const combinedDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n const storybookPackage = [\n 'storybook',\n '@storybook/react',\n '@storybook/angular',\n '@storybook/vue',\n ].find((pkg) => combinedDependencies[pkg]);\n\n if (storybookPackage) {\n const storybookVersion = combinedDependencies[storybookPackage];\n const majorVersion = Number.parseInt(storybookVersion.match(/\\d+/)[0], 10);\n return majorVersion;\n } else {\n throw new Error('Storybook is not listed as a dependency in package.json');\n }\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport type { Zippable } from 'fflate';\nimport { zip } from 'fflate';\n\nimport createHash from './createHash.ts';\nimport validateArchive from './validateArchive.ts';\n\n// We're setting the creation date to the same for all files so that the zip\n// packages created for the same content ends up having the same fingerprint.\n// https://github.com/101arrowz/fflate/issues/219#issuecomment-2333945868\nconst FILE_CREATION_DATE = new Date(2019, 1, 8, 13, 31, 55);\n\n// Type definitions\ninterface FileEntry {\n name: string;\n stream: fs.ReadStream;\n}\n\nexport interface ArchiveContentEntry {\n name: string;\n content: string | Buffer | fs.ReadStream | Readable;\n}\n\ninterface ArchiveResult {\n buffer: Buffer<ArrayBuffer>;\n hash: string;\n}\n\ninterface ArchiveEntry {\n name: string;\n size: number;\n}\n\n/**\n * Resolves all files in a directory and all of its subdirectories\n *\n * @param dirOrFile - The directory or file path to resolve\n * @returns Promise resolving to an array of file entries\n */\nasync function resolveFilesRecursiveForDir(\n dirOrFile: string,\n): Promise<Array<FileEntry>> {\n const resolvedDirOrFile = path.resolve(dirOrFile);\n const isDir = (await fs.promises.lstat(resolvedDirOrFile)).isDirectory();\n\n if (isDir) {\n const fileEntries: Array<FileEntry> = [];\n\n for await (const fileType of fs.promises.glob('**/*', {\n cwd: resolvedDirOrFile,\n withFileTypes: true,\n })) {\n // Check if it's a file (not a directory)\n if (fileType.isFile()) {\n const fullPath = `${fileType.parentPath}/${fileType.name}`;\n\n fileEntries.push({\n name: path.relative(resolvedDirOrFile, fullPath),\n stream: fs.createReadStream(fullPath),\n });\n }\n }\n\n return fileEntries;\n }\n\n return [\n {\n name: path.relative(process.cwd(), resolvedDirOrFile),\n stream: fs.createReadStream(resolvedDirOrFile),\n },\n ];\n}\n\n/**\n * Resolves all files in all directories recursively\n *\n * @param dirsAndFiles - Variable number of directory and file paths\n * @returns Promise resolving to a flattened array of file entries\n */\nasync function resolveFilesRecursive(\n ...dirsAndFiles: Array<string>\n): Promise<Array<FileEntry>> {\n const files = await Promise.all(\n dirsAndFiles.map((dirOrFile) => resolveFilesRecursiveForDir(dirOrFile)),\n );\n\n return files.flat();\n}\n\n/**\n * Converts a stream to a Uint8Array\n */\nasync function streamToUint8Array(\n stream: fs.ReadStream | Readable,\n): Promise<Uint8Array> {\n const chunks: Array<Uint8Array> = [];\n for await (const chunk of stream) {\n chunks.push(chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk));\n }\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n}\n\n/**\n * Converts content to Uint8Array\n */\nasync function contentToUint8Array(\n content: string | Buffer | fs.ReadStream | Readable,\n): Promise<Uint8Array> {\n if (typeof content === 'string') {\n return new TextEncoder().encode(content);\n }\n if (Buffer.isBuffer(content)) {\n return new Uint8Array(content);\n }\n return streamToUint8Array(content);\n}\n\n/**\n * Creates a deterministic archive of the given files\n *\n * @param dirsAndFiles - Array of directory and file paths to include\n * @param contentToArchive - Array of content entries to include in the archive\n * @returns Promise resolving to archive result with buffer and hash\n */\nexport default async function deterministicArchive(\n dirsAndFiles: Array<string>,\n contentToArchive: Array<ArchiveContentEntry> = [],\n): Promise<ArchiveResult> {\n const uniqueDirsAndFiles = Array.from(new Set(dirsAndFiles));\n\n // Sort by name to make the output deterministic\n // Use simple string comparison instead of localeCompare for cross-platform determinism\n const filesToArchiveSorted = (\n await resolveFilesRecursive(...uniqueDirsAndFiles)\n ).toSorted((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n\n const contentToArchiveSorted = contentToArchive.toSorted((a, b) =>\n a.name < b.name ? -1 : a.name > b.name ? 1 : 0,\n );\n\n const seenFiles = new Set<string>();\n const entries: Array<ArchiveEntry> = [];\n\n // Collect all entries with their data first\n interface EntryData {\n name: string;\n data: Uint8Array;\n }\n\n const entryDataList: Array<EntryData> = [];\n\n // Process files from disk\n for (const file of filesToArchiveSorted) {\n if (!seenFiles.has(file.name)) {\n const data = await streamToUint8Array(file.stream);\n entryDataList.push({ name: file.name, data });\n entries.push({ name: file.name, size: data.length });\n seenFiles.add(file.name);\n }\n }\n\n // Process in-memory content\n // Extract basename to match archiver's behavior with prefix: '' for content entries\n for (const file of contentToArchiveSorted) {\n const zipEntryName = path.basename(file.name);\n if (!seenFiles.has(zipEntryName)) {\n const data = await contentToUint8Array(file.content);\n entryDataList.push({ name: zipEntryName, data });\n entries.push({ name: zipEntryName, size: data.length });\n seenFiles.add(zipEntryName);\n }\n }\n\n // Sort all entries by name to ensure deterministic order\n // Use simple string comparison instead of localeCompare for cross-platform determinism\n entryDataList.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n\n // Build zipData object in sorted order to ensure deterministic zip creation\n const zipData: Zippable = {};\n for (const entry of entryDataList) {\n zipData[entry.name] = [\n entry.data,\n {\n mtime: FILE_CREATION_DATE,\n level: 6,\n },\n ];\n }\n\n const zipBuffer = await new Promise<Uint8Array>((resolve, reject) => {\n zip(zipData, { level: 6 }, (err, data) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n });\n });\n const buffer = Buffer.from(zipBuffer);\n validateArchive(buffer.length, entries);\n const hash = createHash(buffer);\n\n return { buffer, hash };\n}\n", "/**\n * Validates that the archive was created successfully\n * @param totalBytes - The total bytes in the archive\n * @param entries - Array of archive entries\n */\nexport default function validateArchive(\n totalBytes: number,\n entries: Array<{ name: string; size: number }>,\n): void {\n const totalMegaBytes = Math.round(totalBytes / 1024 / 1024);\n\n if (totalMegaBytes < 30) {\n return;\n }\n\n const messageBits = [\n `Package size is ${totalMegaBytes} MB (${totalBytes} bytes), maximum is 60 MB.`,\n \"Here are the largest 20 files in the archive. Consider removing ones that aren't necessary.\",\n ];\n\n const fileSizes = entries.map((entry) => ({\n name: entry.name,\n size: entry.size || 0,\n }));\n\n for (const file of fileSizes.toSorted((a, b) => b.size - a.size).slice(0, 20)) {\n messageBits.push(\n `${file.name}: ${Math.round(file.size / 1024 / 1024)} MB (${file.size} bytes)`,\n );\n }\n\n if (totalMegaBytes > 60) {\n throw new Error(messageBits.join('\\n'));\n }\n\n console.warn(messageBits.join('\\n'));\n}\n", "import { styleText } from 'node:util';\n\ntype PrintFunction = (str: string) => void;\n\nconst red = (str: string) => styleText('red', str);\nconst green = (str: string) => styleText('green', str);\nconst dim = (str: string) => styleText('dim', str);\nconst underline = (str: string) => styleText('underline', str);\n\nexport function logTag(project?: string): string {\n return project ? `[${project}] ` : '';\n}\n\nfunction printDuration(print: PrintFunction, startTime?: number): void {\n if (startTime) {\n print(dim(` (${Date.now() - startTime}ms)`));\n }\n}\n\ninterface LoggerOptions {\n stderrPrint?: PrintFunction;\n print?: PrintFunction;\n}\n\ninterface StartOptions {\n startTime?: number;\n}\n\nexport default class Logger {\n private print: PrintFunction;\n private stderrPrint: PrintFunction;\n private startTime?: number | undefined;\n private startMsg?: string | undefined;\n\n constructor({\n stderrPrint = (str: string) => process.stderr.write(str),\n print = (str: string) => process.stdout.write(str),\n }: LoggerOptions = {}) {\n this.print = print;\n this.stderrPrint = stderrPrint;\n this.startTime = undefined;\n this.startMsg = undefined;\n }\n\n mute(): void {\n this.print = () => null;\n this.stderrPrint = () => null;\n }\n\n divider(): void {\n this.info('-----------------------------------------');\n }\n\n info(msg: string): void {\n this.print(`${msg}`.replaceAll(/https?:\\/\\/[^ ]+/g, underline));\n this.print('\\n');\n }\n\n start(msg?: string, { startTime }: StartOptions = {}): void {\n this.startTime = startTime || Date.now();\n this.startMsg = msg;\n if (msg) {\n this.print(`Starting: ${msg} `);\n this.print('\\n');\n }\n }\n\n success(msg?: string): void {\n this.print(green('\u2713'));\n\n if (this.startMsg) {\n this.print(green(` ${this.startMsg}:`));\n }\n\n if (msg) {\n this.print(green(` ${msg}`));\n }\n printDuration(this.print, this.startTime);\n this.print('\\n');\n\n this.startMsg = undefined;\n }\n\n fail(msg?: string): void {\n this.print(red('\u2717'));\n\n if (this.startMsg) {\n this.print(red(` ${this.startMsg}:`));\n }\n\n if (msg) {\n this.print(red(` ${msg}`));\n }\n printDuration(this.print, this.startTime);\n this.print('\\n');\n\n this.startMsg = undefined;\n }\n\n error(e: Error | string): void {\n let stack: string | undefined;\n if (typeof e === 'object' && e.stack) {\n stack = e.stack;\n if (stack) {\n stack = stack.split(`file://${process.cwd()}/`).join('');\n }\n }\n this.stderrPrint(\n red(stack || (typeof e === 'object' ? e.message : e) || String(e)),\n );\n this.stderrPrint('\\n');\n }\n\n warn(message: string): void {\n this.stderrPrint(red(message));\n this.stderrPrint('\\n');\n }\n}\n", "import retry from 'async-retry';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport { logTag } from '../utils/Logger.ts';\nimport makeHappoAPIRequest from './makeHappoAPIRequest.ts';\n\n// Type definitions\ninterface Logger {\n info: (message: string) => void;\n warn: (message: string) => void;\n}\n\ninterface UploadAssetsOptions {\n hash: string;\n logger: Logger;\n}\n\nexport default async function uploadAssets(\n buffer: Buffer<ArrayBuffer>,\n options: UploadAssetsOptions,\n config: ConfigWithDefaults,\n): Promise<string> {\n const { project } = config;\n const { hash, logger } = options;\n\n // First we need to get the signed URL from Happo.\n const signedUrlRes = await makeHappoAPIRequest(\n {\n path: `/api/snap-requests/assets/${hash}/signed-url`,\n method: 'GET',\n json: true,\n },\n config,\n { retryCount: 3 },\n );\n\n if (!signedUrlRes) {\n throw new Error('Failed to get signed URL');\n }\n\n if ('path' in signedUrlRes) {\n // If the asset has already been uploaded the response will have a path and\n // we can return it now.\n const { path: signedUrlPath } = signedUrlRes;\n\n logger.info(`${logTag(project)}Reusing existing assets at ${signedUrlPath}`);\n return typeof signedUrlPath === 'string' ? signedUrlPath : String(signedUrlPath);\n }\n\n if (!('signedUrl' in signedUrlRes)) {\n throw new Error(\n `Signed URL response does not have path or signedUrl. Response: ${JSON.stringify(signedUrlRes, null, 2)}`,\n );\n }\n\n const { signedUrl } = signedUrlRes;\n\n // Upload the assets to the signed URL using node's built-in fetch with\n // retries\n await retry(\n async (bail: (error: Error) => void) => {\n const res = await fetch(String(signedUrl), {\n method: 'PUT',\n body: buffer,\n headers: {\n 'Content-Type': 'application/zip',\n },\n });\n\n if (!res.ok) {\n const error = new Error(\n `Failed to upload assets to S3 signed URL: ${res.status} ${res.statusText}`,\n );\n\n if (res.status < 500 || res.status >= 600) {\n // If it's not a 5xx error, bail immediately instead of retrying\n bail(error);\n return;\n }\n\n throw error;\n }\n\n return res;\n },\n {\n retries: 3,\n onRetry: (error: Error, attempt: number) => {\n logger.warn(\n `${logTag(project)}PUT request attempt ${attempt} failed: ${error.message}. Retrying...`,\n );\n },\n },\n );\n\n // Finally, we need to tell Happo that we've uploaded the assets.\n const finalizeRes = await makeHappoAPIRequest(\n {\n path: `/api/snap-requests/assets/${hash}/signed-url/finalize`,\n method: 'POST',\n json: true,\n },\n config,\n { retryCount: 3 },\n );\n\n if (!finalizeRes) {\n throw new Error('Failed to finalize assets');\n }\n\n if (!('path' in finalizeRes)) {\n throw new Error('Finalize response is missing path');\n }\n\n const { path: finalizedPath } = finalizeRes;\n\n return typeof finalizedPath === 'string' ? finalizedPath : String(finalizedPath);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport RemoteBrowserTarget, {\n type ExecuteParams,\n} from '../config/RemoteBrowserTarget.ts';\nimport buildStorybookPackage from '../storybook/index.ts';\nimport deterministicArchive from '../utils/deterministicArchive.ts';\nimport Logger, { logTag } from '../utils/Logger.ts';\nimport uploadAssets from './uploadAssets.ts';\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await fs.promises.stat(path);\n return true;\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return false;\n }\n\n throw error;\n }\n}\n\nasync function createIframeHTML(\n rootDir: string,\n entryPoint: string,\n logger: Logger,\n): Promise<void> {\n const iframePath = path.join(rootDir, 'iframe.html');\n\n if (await fileExists(iframePath)) {\n logger.info(`Using existing iframe.html at '${iframePath}'`);\n return;\n }\n\n const iframeContent = `<!DOCTYPE html>\n<html lang=\"en\" dir=\"ltr\">\n <head>\n <title>Happo</title>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n </head>\n <body>\n <script src=\"${entryPoint}\"></script>\n </body>\n</html>`;\n\n await fs.promises.mkdir(rootDir, { recursive: true });\n await fs.promises.writeFile(iframePath, iframeContent);\n}\n\nasync function buildPackage(\n { integration }: ConfigWithDefaults,\n logger: Logger,\n): Promise<string> {\n if (integration.type === 'custom') {\n const { rootDir, entryPoint } = await integration.build();\n await createIframeHTML(rootDir, entryPoint, logger);\n return rootDir;\n }\n\n if (integration.type === 'storybook') {\n return await buildStorybookPackage(integration);\n }\n\n throw new Error(`Unsupported integration type: ${integration.type}`);\n}\n\nasync function validatePackage(packageDir: string): Promise<void> {\n const iframePath = path.join(packageDir, 'iframe.html');\n\n if (!(await fileExists(iframePath))) {\n throw new Error(\n `Could not find iframe.html in static package at '${iframePath}'`,\n );\n }\n}\n\nasync function preparePackage(\n config: ConfigWithDefaults,\n logger: Logger,\n): Promise<string> {\n const packageDir = await buildPackage(config, logger);\n\n await validatePackage(packageDir);\n\n const { buffer, hash } = await deterministicArchive([packageDir]);\n return await uploadAssets(\n buffer,\n {\n hash,\n logger,\n },\n config,\n );\n}\n\nexport default async function prepareSnapRequests(\n config: ConfigWithDefaults,\n): Promise<Array<number>> {\n const logger = new Logger();\n const packagePath =\n config.integration.type === 'pages'\n ? null\n : await preparePackage(config, logger);\n\n const targetNames = Object.keys(config.targets);\n const tl = targetNames.length;\n logger.info(\n `${logTag(config.project)}Generating screenshots in ${tl} target${\n tl > 1 ? 's' : ''\n }...`,\n );\n const outerStartTime = Date.now();\n const results: Array<number> = [];\n await Promise.all(\n targetNames.map(async (name) => {\n const startTime = Date.now();\n if (!config.targets[name]) {\n throw new Error(`Target ${name} not found in config`);\n }\n const target = new RemoteBrowserTarget(\n config.targets[name].type,\n config.targets[name],\n );\n const targetParams: ExecuteParams = {\n targetName: name,\n };\n if (packagePath) {\n targetParams.staticPackage = packagePath;\n }\n if (config.integration.type === 'pages') {\n targetParams.pages = config.integration.pages;\n }\n const snapRequestIds = await target.execute(targetParams, config);\n logger.start(` - ${logTag(config.project)}${name}`, { startTime });\n logger.success();\n results.push(...snapRequestIds);\n }),\n );\n logger.start(undefined, { startTime: outerStartTime });\n logger.success();\n return results;\n}\n", "import crypto from 'node:crypto';\n\n/**\n * Creates an MD5 hash of the input data\n * @param data - The data to hash (string, Buffer, or TypedArray)\n * @returns The MD5 hash as a hexadecimal string\n */\nexport default function createHash(\n data: string | Buffer | NodeJS.TypedArray,\n): string {\n return crypto.createHash('md5').update(data).digest('hex');\n}\n", "import makeHappoAPIRequest from '../network/makeHappoAPIRequest.ts';\nimport createHash from '../utils/createHash.ts';\nimport type { ConfigWithDefaults, Page, TargetWithDefaults } from './index.ts';\n\nconst VIEWPORT_PATTERN = /^([0-9]+)x([0-9]+)$/;\n\n/**\n * PageSlice is an array of pages with the extra extendsSha property.\n */\ninterface PageSlice extends Array<Page> {\n extendsSha?: string;\n}\n\ninterface Chunk {\n index: number;\n total: number;\n}\n\ninterface BoundMakeRequestParams {\n slice?: Array<unknown> | undefined;\n chunk?: Chunk | undefined;\n pageSlice?: PageSlice | undefined;\n}\n\nexport interface CSSBlock {\n id: string;\n conditional: boolean;\n css: string;\n}\n\nexport interface ExecuteParams {\n globalCSS?: string | Array<CSSBlock>;\n\n /** Path to the assets package */\n assetsPackage?: string;\n\n /** Path to the static package */\n staticPackage?: string;\n\n snapPayloads?: Array<unknown>;\n pages?: Array<Page>;\n targetName?: string;\n}\n\nfunction getPageSlices(pages: Array<Page>, chunks: number): Array<PageSlice> {\n const result: Array<PageSlice> = [];\n\n // First, split the raw pages into chunks\n const pagesPerChunk = Math.ceil(pages.length / chunks);\n for (let i = 0; i < chunks; i += 1) {\n const pageSlice = pages.slice(\n i * pagesPerChunk,\n i * pagesPerChunk + pagesPerChunk,\n );\n\n if (pageSlice.length > 0) {\n result.push(pageSlice);\n }\n }\n return result;\n}\n\nexport default class RemoteBrowserTarget {\n public readonly chunks: number;\n public readonly browserName: string;\n public readonly viewport: string;\n public readonly maxHeight: number | undefined;\n public readonly otherOptions: Record<string, unknown>;\n\n constructor(\n browserName: string,\n {\n viewport = '1024x768',\n chunks = 1,\n maxHeight,\n ...otherOptions\n }: TargetWithDefaults,\n ) {\n const viewportMatch = viewport.match(VIEWPORT_PATTERN);\n if (!viewportMatch) {\n throw new Error(\n `Invalid viewport \"${viewport}\". Here's an example of a valid one: \"1024x768\".`,\n );\n }\n\n this.chunks = chunks;\n this.browserName = browserName;\n this.viewport = viewport;\n this.maxHeight = maxHeight ?? undefined;\n this.otherOptions = otherOptions;\n }\n\n async execute(\n {\n globalCSS,\n assetsPackage,\n staticPackage,\n snapPayloads,\n pages,\n targetName,\n }: ExecuteParams,\n config: ConfigWithDefaults,\n ): Promise<Array<number>> {\n const boundMakeRequest = async ({\n slice,\n chunk,\n pageSlice,\n }: BoundMakeRequestParams): Promise<number> => {\n const payloadString = JSON.stringify({\n viewport: this.viewport,\n maxHeight: this.maxHeight,\n ...this.otherOptions,\n globalCSS,\n snapPayloads: slice,\n chunk,\n staticPackage,\n assetsPackage,\n pages: pageSlice,\n extendsSha: pageSlice ? pageSlice.extendsSha : undefined,\n });\n\n const payloadHash = createHash(\n payloadString + (pageSlice ? Math.random() : ''),\n );\n\n const formData: Record<string, string | File | undefined> = {\n type:\n pageSlice && pageSlice.extendsSha\n ? 'extends-report'\n : `browser-${this.browserName}`,\n targetName,\n payloadHash,\n payload: new File([payloadString], 'payload.json', {\n type: 'application/json',\n }),\n };\n\n if (pageSlice && pageSlice.extendsSha) {\n formData.extendsSha = pageSlice.extendsSha;\n }\n\n const requestResult = await makeHappoAPIRequest(\n {\n path: `/api/snap-requests?payloadHash=${payloadHash}`,\n method: 'POST',\n json: true,\n formData,\n },\n config,\n { retryCount: 5 },\n );\n\n if (!requestResult) {\n throw new Error('No requestResult');\n }\n\n if (!('requestId' in requestResult)) {\n throw new Error('No requestId in requestResult');\n }\n\n if (typeof requestResult.requestId !== 'number') {\n throw new TypeError('requestId is not a number');\n }\n\n return requestResult.requestId;\n };\n\n const requestIds: Array<number> = [];\n\n if (staticPackage) {\n for (let i = 0; i < this.chunks; i += 1) {\n // We `await` here inside the loop to avoid POSTing all payloads to the\n // server at the same time (thus reducing load a little).\n const requestId = await boundMakeRequest({\n chunk: { index: i, total: this.chunks },\n });\n requestIds.push(requestId);\n }\n } else if (pages) {\n for (const pageSlice of getPageSlices(pages, this.chunks)) {\n // We `await` here inside the loop to avoid POSTing all payloads to the\n // server at the same time (thus reducing load a little).\n const requestId = await boundMakeRequest({\n pageSlice,\n });\n requestIds.push(requestId);\n }\n } else {\n const snapsPerChunk = Math.ceil((snapPayloads?.length ?? 0) / this.chunks);\n for (let i = 0; i < this.chunks; i += 1) {\n const slice = snapPayloads?.slice(\n i * snapsPerChunk,\n i * snapsPerChunk + snapsPerChunk,\n );\n\n // We `await` here inside the loop to avoid POSTing all payloads to the\n // server at the same time (thus reducing load a little).\n const requestId = await boundMakeRequest({\n slice,\n });\n requestIds.push(requestId);\n }\n }\n\n return requestIds;\n }\n}\n", "import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { StorybookIntegration } from '../config/index.ts';\nimport getStorybookBuildCommandParts from './getStorybookBuildCommandParts.ts';\nimport getStorybookVersionFromPackageJson from './getStorybookVersionFromPackageJson.ts';\nimport type { SkipItems } from './isomorphic/types.ts';\n\nconst { HAPPO_DEBUG } = process.env;\n\nfunction assertSkippedIsSkipItems(skipped: unknown): asserts skipped is SkipItems {\n if (!Array.isArray(skipped)) {\n throw new TypeError(`The \\`skip\\` option didn't provide an array`);\n }\n\n if (skipped.some((item) => !item.component || !item.variant)) {\n throw new Error(\n `Each item provided by the \\`skip\\` option needs a \\`component\\` and a \\`variant\\` property`,\n );\n }\n}\n\nfunction resolveBuildCommandParts() {\n const version = getStorybookVersionFromPackageJson();\n\n if (version < 9) {\n throw new Error(\n `Storybook v${version} is not supported. Please update storybook to v9 or later.`,\n );\n }\n\n return getStorybookBuildCommandParts();\n}\n\nfunction buildStorybook({\n configDir,\n staticDir,\n outputDir,\n}: {\n configDir: string;\n staticDir?: string | undefined;\n outputDir: string;\n}): Promise<void> {\n return new Promise((resolve, reject) => {\n fs.rmSync(outputDir, { recursive: true, force: true });\n\n const buildCommandParts = resolveBuildCommandParts();\n\n if (!buildCommandParts[0]) {\n throw new Error('Failed to resolve build command parts');\n }\n\n const params = [\n ...buildCommandParts,\n '--output-dir',\n outputDir,\n '--config-dir',\n configDir,\n ];\n\n if (staticDir) {\n params.push('--static-dir', staticDir);\n }\n\n let binary = fs.existsSync('yarn.lock') ? 'yarn' : 'npx';\n\n if (buildCommandParts[0].includes('node_modules')) {\n binary = buildCommandParts[0];\n params.shift(); // remove binary from params\n }\n\n if (HAPPO_DEBUG) {\n console.log(`[happo] Using build command \\`${binary} ${params.join(' ')}\\``);\n }\n\n const spawned = spawn(binary, params, {\n stdio: 'inherit',\n shell: process.platform == 'win32',\n });\n\n spawned.on('exit', (code) => {\n if (code === 0) {\n try {\n fs.unlinkSync(path.join(outputDir, 'project.json'));\n } catch (error) {\n console.warn(\n `Ignoring error when attempting to remove project.json: ${error}`,\n );\n }\n resolve();\n } else {\n reject(new Error('Failed to build static storybook package'));\n }\n });\n });\n}\n\nexport default async function buildStorybookPackage({\n configDir = '.storybook',\n staticDir,\n outputDir = '.out',\n usePrebuiltPackage = false,\n skip,\n}: Omit<StorybookIntegration, 'type'>): Promise<string> {\n if (!usePrebuiltPackage) {\n await buildStorybook({ configDir, staticDir, outputDir });\n }\n\n const iframePath = path.join(outputDir, 'iframe.html');\n if (!fs.existsSync(iframePath)) {\n throw new Error(\n 'Failed to build static storybook package (missing iframe.html)',\n );\n }\n\n try {\n const skipped =\n typeof skip === 'function' ? await skip() : Array.isArray(skip) ? skip : [];\n\n assertSkippedIsSkipItems(skipped);\n\n const iframeContent = fs.readFileSync(iframePath, 'utf8');\n\n fs.writeFileSync(\n iframePath,\n iframeContent.replace(\n '<head>',\n `<head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script type=\"text/javascript\">window.__IS_HAPPO_RUN = true;</script>\n <script type=\"text/javascript\">window.happoSkipped = ${JSON.stringify(\n skipped,\n )};</script>\n `,\n ),\n );\n\n // Tell happo where the files are located.\n return outputDir;\n } catch (e) {\n console.error(e);\n throw e;\n }\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\n\nconst { HAPPO_DEBUG } = process.env;\n\nexport default function getStorybookBuildCommandParts(\n packageJsonPath: string = path.join(process.cwd(), 'package.json'),\n): [string, string] {\n try {\n const data = fs.readFileSync(packageJsonPath, 'utf8');\n const packageJson = JSON.parse(data);\n\n if (packageJson.scripts.storybook) {\n if (HAPPO_DEBUG) {\n console.log(\n '[happo] Found `storybook` script in package.json. Will attempt to use binary found at `node_modules/.bin/storybook` instead',\n );\n }\n\n const pathToStorybookCommand = path.join(\n process.cwd(),\n 'node_modules',\n '.bin',\n 'storybook',\n );\n\n if (fs.existsSync(pathToStorybookCommand)) {\n return [pathToStorybookCommand, 'build'];\n }\n }\n } catch (e) {\n if (HAPPO_DEBUG) {\n console.log(\n '[happo] Caught error when resolving Storybook build command parts. Will use default.',\n e,\n );\n }\n }\n\n return ['storybook', 'build'];\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\n\nexport default function getStorybookVersionFromPackageJson(\n packageJsonPath: string = path.join(process.cwd(), 'package.json'),\n): number {\n const data = fs.readFileSync(packageJsonPath, 'utf8');\n const packageJson = JSON.parse(data);\n\n const combinedDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n const storybookPackage = [\n 'storybook',\n '@storybook/react',\n '@storybook/angular',\n '@storybook/vue',\n ].find((pkg) => combinedDependencies[pkg]);\n\n if (storybookPackage) {\n const storybookVersion = combinedDependencies[storybookPackage];\n const majorVersion = Number.parseInt(storybookVersion.match(/\\d+/)[0], 10);\n return majorVersion;\n } else {\n throw new Error('Storybook is not listed as a dependency in package.json');\n }\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport type { Zippable } from 'fflate';\nimport { zip } from 'fflate';\n\nimport createHash from './createHash.ts';\nimport validateArchive from './validateArchive.ts';\n\n// We're setting the creation date to the same for all files so that the zip\n// packages created for the same content ends up having the same fingerprint.\n// https://github.com/101arrowz/fflate/issues/219#issuecomment-2333945868\nconst FILE_CREATION_DATE = new Date(2019, 1, 8, 13, 31, 55);\n\n// Type definitions\ninterface FileEntry {\n name: string;\n stream: fs.ReadStream;\n}\n\nexport interface ArchiveContentEntry {\n name: string;\n content: string | Buffer | fs.ReadStream | Readable;\n}\n\ninterface ArchiveResult {\n buffer: Buffer<ArrayBuffer>;\n hash: string;\n}\n\ninterface ArchiveEntry {\n name: string;\n size: number;\n}\n\n/**\n * Resolves all files in a directory and all of its subdirectories\n *\n * @param dirOrFile - The directory or file path to resolve\n * @returns Promise resolving to an array of file entries\n */\nasync function resolveFilesRecursiveForDir(\n dirOrFile: string,\n): Promise<Array<FileEntry>> {\n const resolvedDirOrFile = path.resolve(dirOrFile);\n const isDir = (await fs.promises.lstat(resolvedDirOrFile)).isDirectory();\n\n if (isDir) {\n const fileEntries: Array<FileEntry> = [];\n\n for await (const fileType of fs.promises.glob('**/*', {\n cwd: resolvedDirOrFile,\n withFileTypes: true,\n })) {\n // Check if it's a file (not a directory)\n if (fileType.isFile()) {\n const fullPath = `${fileType.parentPath}/${fileType.name}`;\n\n fileEntries.push({\n name: path.relative(resolvedDirOrFile, fullPath),\n stream: fs.createReadStream(fullPath),\n });\n }\n }\n\n return fileEntries;\n }\n\n return [\n {\n name: path.relative(process.cwd(), resolvedDirOrFile),\n stream: fs.createReadStream(resolvedDirOrFile),\n },\n ];\n}\n\n/**\n * Resolves all files in all directories recursively\n *\n * @param dirsAndFiles - Variable number of directory and file paths\n * @returns Promise resolving to a flattened array of file entries\n */\nasync function resolveFilesRecursive(\n ...dirsAndFiles: Array<string>\n): Promise<Array<FileEntry>> {\n const files = await Promise.all(\n dirsAndFiles.map((dirOrFile) => resolveFilesRecursiveForDir(dirOrFile)),\n );\n\n return files.flat();\n}\n\n/**\n * Converts a stream to a Uint8Array\n */\nasync function streamToUint8Array(\n stream: fs.ReadStream | Readable,\n): Promise<Uint8Array> {\n const chunks: Array<Uint8Array> = [];\n for await (const chunk of stream) {\n chunks.push(chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk));\n }\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n}\n\n/**\n * Converts content to Uint8Array\n */\nasync function contentToUint8Array(\n content: string | Buffer | fs.ReadStream | Readable,\n): Promise<Uint8Array> {\n if (typeof content === 'string') {\n return new TextEncoder().encode(content);\n }\n if (Buffer.isBuffer(content)) {\n return new Uint8Array(content);\n }\n return streamToUint8Array(content);\n}\n\n/**\n * Creates a deterministic archive of the given files\n *\n * @param dirsAndFiles - Array of directory and file paths to include\n * @param contentToArchive - Array of content entries to include in the archive\n * @returns Promise resolving to archive result with buffer and hash\n */\nexport default async function deterministicArchive(\n dirsAndFiles: Array<string>,\n contentToArchive: Array<ArchiveContentEntry> = [],\n): Promise<ArchiveResult> {\n const uniqueDirsAndFiles = Array.from(new Set(dirsAndFiles));\n\n // Sort by name to make the output deterministic\n // Use simple string comparison instead of localeCompare for cross-platform determinism\n const filesToArchiveSorted = (\n await resolveFilesRecursive(...uniqueDirsAndFiles)\n ).toSorted((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n\n const contentToArchiveSorted = contentToArchive.toSorted((a, b) =>\n a.name < b.name ? -1 : a.name > b.name ? 1 : 0,\n );\n\n const seenFiles = new Set<string>();\n const entries: Array<ArchiveEntry> = [];\n\n // Collect all entries with their data first\n interface EntryData {\n name: string;\n data: Uint8Array;\n }\n\n const entryDataList: Array<EntryData> = [];\n\n // Process files from disk\n for (const file of filesToArchiveSorted) {\n if (!seenFiles.has(file.name)) {\n const data = await streamToUint8Array(file.stream);\n entryDataList.push({ name: file.name, data });\n entries.push({ name: file.name, size: data.length });\n seenFiles.add(file.name);\n }\n }\n\n // Process in-memory content\n // Extract basename to match archiver's behavior with prefix: '' for content entries\n for (const file of contentToArchiveSorted) {\n if (!seenFiles.has(file.name)) {\n const data = await contentToUint8Array(file.content);\n entryDataList.push({ name: file.name, data });\n entries.push({ name: file.name, size: data.length });\n seenFiles.add(file.name);\n }\n }\n\n // Sort all entries by name to ensure deterministic order\n // Use simple string comparison instead of localeCompare for cross-platform determinism\n entryDataList.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n\n // Build zipData object in sorted order to ensure deterministic zip creation\n const zipData: Zippable = {};\n for (const entry of entryDataList) {\n zipData[entry.name] = [\n entry.data,\n {\n mtime: FILE_CREATION_DATE,\n level: 6,\n },\n ];\n }\n\n const zipBuffer = await new Promise<Uint8Array>((resolve, reject) => {\n zip(zipData, { level: 6 }, (err, data) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n });\n });\n const buffer = Buffer.from(zipBuffer);\n validateArchive(buffer.length, entries);\n const hash = createHash(buffer);\n\n return { buffer, hash };\n}\n", "/**\n * Validates that the archive was created successfully\n * @param totalBytes - The total bytes in the archive\n * @param entries - Array of archive entries\n */\nexport default function validateArchive(\n totalBytes: number,\n entries: Array<{ name: string; size: number }>,\n): void {\n const totalMegaBytes = Math.round(totalBytes / 1024 / 1024);\n\n if (totalMegaBytes < 30) {\n return;\n }\n\n const messageBits = [\n `Package size is ${totalMegaBytes} MB (${totalBytes} bytes), maximum is 60 MB.`,\n \"Here are the largest 20 files in the archive. Consider removing ones that aren't necessary.\",\n ];\n\n const fileSizes = entries.map((entry) => ({\n name: entry.name,\n size: entry.size || 0,\n }));\n\n for (const file of fileSizes.toSorted((a, b) => b.size - a.size).slice(0, 20)) {\n messageBits.push(\n `${file.name}: ${Math.round(file.size / 1024 / 1024)} MB (${file.size} bytes)`,\n );\n }\n\n if (totalMegaBytes > 60) {\n throw new Error(messageBits.join('\\n'));\n }\n\n console.warn(messageBits.join('\\n'));\n}\n", "import { styleText } from 'node:util';\n\ntype PrintFunction = (str: string) => void;\n\nconst red = (str: string) => styleText('red', str);\nconst green = (str: string) => styleText('green', str);\nconst dim = (str: string) => styleText('dim', str);\nconst underline = (str: string) => styleText('underline', str);\n\nexport function logTag(project?: string): string {\n return project ? `[${project}] ` : '';\n}\n\nfunction printDuration(print: PrintFunction, startTime?: number): void {\n if (startTime) {\n print(dim(` (${Date.now() - startTime}ms)`));\n }\n}\n\ninterface LoggerOptions {\n stderrPrint?: PrintFunction;\n print?: PrintFunction;\n}\n\ninterface StartOptions {\n startTime?: number;\n}\n\nexport default class Logger {\n private print: PrintFunction;\n private stderrPrint: PrintFunction;\n private startTime?: number | undefined;\n private startMsg?: string | undefined;\n\n constructor({\n stderrPrint = (str: string) => process.stderr.write(str),\n print = (str: string) => process.stdout.write(str),\n }: LoggerOptions = {}) {\n this.print = print;\n this.stderrPrint = stderrPrint;\n this.startTime = undefined;\n this.startMsg = undefined;\n }\n\n mute(): void {\n this.print = () => null;\n this.stderrPrint = () => null;\n }\n\n divider(): void {\n this.info('-----------------------------------------');\n }\n\n info(msg: string): void {\n this.print(`${msg}`.replaceAll(/https?:\\/\\/[^ ]+/g, underline));\n this.print('\\n');\n }\n\n start(msg?: string, { startTime }: StartOptions = {}): void {\n this.startTime = startTime || Date.now();\n this.startMsg = msg;\n if (msg) {\n this.print(`Starting: ${msg} `);\n this.print('\\n');\n }\n }\n\n success(msg?: string): void {\n this.print(green('\u2713'));\n\n if (this.startMsg) {\n this.print(green(` ${this.startMsg}:`));\n }\n\n if (msg) {\n this.print(green(` ${msg}`));\n }\n printDuration(this.print, this.startTime);\n this.print('\\n');\n\n this.startMsg = undefined;\n }\n\n fail(msg?: string): void {\n this.print(red('\u2717'));\n\n if (this.startMsg) {\n this.print(red(` ${this.startMsg}:`));\n }\n\n if (msg) {\n this.print(red(` ${msg}`));\n }\n printDuration(this.print, this.startTime);\n this.print('\\n');\n\n this.startMsg = undefined;\n }\n\n error(e: Error | string): void {\n let stack: string | undefined;\n if (typeof e === 'object' && e.stack) {\n stack = e.stack;\n if (stack) {\n stack = stack.split(`file://${process.cwd()}/`).join('');\n }\n }\n this.stderrPrint(\n red(stack || (typeof e === 'object' ? e.message : e) || String(e)),\n );\n this.stderrPrint('\\n');\n }\n\n warn(message: string): void {\n this.stderrPrint(red(message));\n this.stderrPrint('\\n');\n }\n}\n", "import retry from 'async-retry';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport { logTag } from '../utils/Logger.ts';\nimport makeHappoAPIRequest from './makeHappoAPIRequest.ts';\n\n// Type definitions\ninterface Logger {\n info: (message: string) => void;\n warn: (message: string) => void;\n}\n\ninterface UploadAssetsOptions {\n hash: string;\n logger: Logger;\n}\n\nexport default async function uploadAssets(\n buffer: Buffer<ArrayBuffer>,\n options: UploadAssetsOptions,\n config: ConfigWithDefaults,\n): Promise<string> {\n const { project } = config;\n const { hash, logger } = options;\n\n // First we need to get the signed URL from Happo.\n const signedUrlRes = await makeHappoAPIRequest(\n {\n path: `/api/snap-requests/assets/${hash}/signed-url`,\n method: 'GET',\n json: true,\n },\n config,\n { retryCount: 3 },\n );\n\n if (!signedUrlRes) {\n throw new Error('Failed to get signed URL');\n }\n\n if ('path' in signedUrlRes) {\n // If the asset has already been uploaded the response will have a path and\n // we can return it now.\n const { path: signedUrlPath } = signedUrlRes;\n\n logger.info(`${logTag(project)}Reusing existing assets at ${signedUrlPath}`);\n return typeof signedUrlPath === 'string' ? signedUrlPath : String(signedUrlPath);\n }\n\n if (!('signedUrl' in signedUrlRes)) {\n throw new Error(\n `Signed URL response does not have path or signedUrl. Response: ${JSON.stringify(signedUrlRes, null, 2)}`,\n );\n }\n\n const { signedUrl } = signedUrlRes;\n\n // Upload the assets to the signed URL using node's built-in fetch with\n // retries\n await retry(\n async (bail: (error: Error) => void) => {\n const res = await fetch(String(signedUrl), {\n method: 'PUT',\n body: buffer,\n headers: {\n 'Content-Type': 'application/zip',\n },\n });\n\n if (!res.ok) {\n const error = new Error(\n `Failed to upload assets to S3 signed URL: ${res.status} ${res.statusText}`,\n );\n\n if (res.status < 500 || res.status >= 600) {\n // If it's not a 5xx error, bail immediately instead of retrying\n bail(error);\n return;\n }\n\n throw error;\n }\n\n return res;\n },\n {\n retries: 3,\n onRetry: (error: Error, attempt: number) => {\n logger.warn(\n `${logTag(project)}PUT request attempt ${attempt} failed: ${error.message}. Retrying...`,\n );\n },\n },\n );\n\n // Finally, we need to tell Happo that we've uploaded the assets.\n const finalizeRes = await makeHappoAPIRequest(\n {\n path: `/api/snap-requests/assets/${hash}/signed-url/finalize`,\n method: 'POST',\n json: true,\n },\n config,\n { retryCount: 3 },\n );\n\n if (!finalizeRes) {\n throw new Error('Failed to finalize assets');\n }\n\n if (!('path' in finalizeRes)) {\n throw new Error('Finalize response is missing path');\n }\n\n const { path: finalizedPath } = finalizeRes;\n\n return typeof finalizedPath === 'string' ? finalizedPath : String(finalizedPath);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fs", "path", "fs", "path", "fs", "path", "HAPPO_DEBUG", "fs", "path", "fs", "path", "path", "fs", "path", "fs"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  makeHappoAPIRequest
3
- } from "./chunk-HCMCNDII.js";
4
- import "./chunk-MQN57GVD.js";
3
+ } from "./chunk-AK57NWGE.js";
4
+ import "./chunk-RWJCN6TI.js";
5
5
 
6
6
  // src/network/startJob.ts
7
7
  function assertResultIsStartJobResult(result) {
@@ -36,4 +36,4 @@ async function startJob(config, { beforeSha, afterSha, link, message }, logger)
36
36
  export {
37
37
  startJob as default
38
38
  };
39
- //# sourceMappingURL=startJob-4EQXSOMD.js.map
39
+ //# sourceMappingURL=startJob-3MAGI2AV.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createAsyncComparison
3
- } from "./chunk-33S3P2UT.js";
3
+ } from "./chunk-SCCWUPCL.js";
4
4
  import {
5
5
  makeHappoAPIRequest
6
- } from "./chunk-HCMCNDII.js";
7
- import "./chunk-MQN57GVD.js";
6
+ } from "./chunk-AK57NWGE.js";
7
+ import "./chunk-RWJCN6TI.js";
8
8
 
9
9
  // src/e2e/wrapper.ts
10
10
  import { spawn } from "node:child_process";
@@ -370,4 +370,4 @@ export {
370
370
  runWithWrapper as default,
371
371
  finalizeAll
372
372
  };
373
- //# sourceMappingURL=wrapper-GHIE52PM.js.map
373
+ //# sourceMappingURL=wrapper-RNK4FFFV.js.map
@@ -67,7 +67,7 @@ import asyncRetry from "async-retry";
67
67
  // package.json
68
68
  var package_default = {
69
69
  name: "happo",
70
- version: "6.0.0-beta.7",
70
+ version: "6.0.0-beta.8",
71
71
  description: "Visual regression testing and accessibility testing",
72
72
  license: "MIT",
73
73
  repository: {
@@ -704,12 +704,11 @@ async function deterministicArchive(dirsAndFiles, contentToArchive = []) {
704
704
  }
705
705
  }
706
706
  for (const file of contentToArchiveSorted) {
707
- const zipEntryName = path.basename(file.name);
708
- if (!seenFiles.has(zipEntryName)) {
707
+ if (!seenFiles.has(file.name)) {
709
708
  const data = await contentToUint8Array(file.content);
710
- entryDataList.push({ name: zipEntryName, data });
711
- entries.push({ name: zipEntryName, size: data.length });
712
- seenFiles.add(zipEntryName);
709
+ entryDataList.push({ name: file.name, data });
710
+ entries.push({ name: file.name, size: data.length });
711
+ seenFiles.add(file.name);
713
712
  }
714
713
  }
715
714
  entryDataList.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);