happo 6.10.0 → 6.10.2

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 (49) hide show
  1. package/dist/cli/cancelJob-DQ3TD7VC.js +10 -0
  2. package/dist/cli/{chunk-JJOM7NVS.js → chunk-2CCKQG4B.js} +2 -2
  3. package/dist/cli/{chunk-AJQL27KK.js → chunk-5GCRDC6E.js} +2 -2
  4. package/dist/cli/{chunk-V2ULNFYX.js → chunk-BJXCKTWI.js} +3 -3
  5. package/dist/cli/{chunk-WUYZIKHR.js → chunk-LGXU3JNM.js} +2 -2
  6. package/dist/cli/{chunk-JIRDD3RO.js → chunk-P4CGDKZS.js} +2 -2
  7. package/dist/cli/{chunk-KTUIEOPK.js → chunk-Z32R7CJB.js} +2 -2
  8. package/dist/cli/{chunk-KTUIEOPK.js.map → chunk-Z32R7CJB.js.map} +1 -1
  9. package/dist/cli/createAsyncComparison-P277GZ47.js +10 -0
  10. package/dist/cli/{createAsyncReport-QFCSVMAO.js → createAsyncReport-4XB6OU6P.js} +4 -4
  11. package/dist/cli/{createExtendsReportSnapRequest-X2DLPLP5.js → createExtendsReportSnapRequest-L2XBZPJ3.js} +4 -4
  12. package/dist/cli/{findBaselineReport-N4AUOVXP.js → findBaselineReport-K4JN4ZMB.js} +4 -4
  13. package/dist/cli/{getFlakes-M2LSXSTW.js → getFlakes-6GNOYD2U.js} +4 -4
  14. package/dist/cli/index.d.ts.map +1 -1
  15. package/dist/cli/main.js +24 -17
  16. package/dist/cli/main.js.map +2 -2
  17. package/dist/cli/package-UABOUH2S.js +7 -0
  18. package/dist/cli/parseOptions.d.ts +3 -0
  19. package/dist/cli/parseOptions.d.ts.map +1 -1
  20. package/dist/cli/{prepareSnapRequests-RINWFSWA.js → prepareSnapRequests-KMVRPKIT.js} +4 -4
  21. package/dist/cli/startJob-TUFOU2O5.js +10 -0
  22. package/dist/cli/{wrapper-YYNZLEMW.js → wrapper-XUOTVPDW.js} +7 -7
  23. package/dist/cypress/task.js +1 -1
  24. package/dist/cypress/task.js.map +1 -1
  25. package/dist/playwright/index.js +1 -1
  26. package/dist/playwright/index.js.map +1 -1
  27. package/dist/storybook/browser/register.d.ts.map +1 -1
  28. package/dist/storybook/browser/register.js +12 -10
  29. package/dist/storybook/browser/register.js.map +2 -2
  30. package/package.json +1 -1
  31. package/dist/cli/cancelJob-PHMDAIJB.js +0 -10
  32. package/dist/cli/createAsyncComparison-D525PJCA.js +0 -10
  33. package/dist/cli/package-3UUMFV7J.js +0 -7
  34. package/dist/cli/startJob-JAVHOIR6.js +0 -10
  35. /package/dist/cli/{cancelJob-PHMDAIJB.js.map → cancelJob-DQ3TD7VC.js.map} +0 -0
  36. /package/dist/cli/{chunk-JJOM7NVS.js.map → chunk-2CCKQG4B.js.map} +0 -0
  37. /package/dist/cli/{chunk-AJQL27KK.js.map → chunk-5GCRDC6E.js.map} +0 -0
  38. /package/dist/cli/{chunk-V2ULNFYX.js.map → chunk-BJXCKTWI.js.map} +0 -0
  39. /package/dist/cli/{chunk-WUYZIKHR.js.map → chunk-LGXU3JNM.js.map} +0 -0
  40. /package/dist/cli/{chunk-JIRDD3RO.js.map → chunk-P4CGDKZS.js.map} +0 -0
  41. /package/dist/cli/{createAsyncComparison-D525PJCA.js.map → createAsyncComparison-P277GZ47.js.map} +0 -0
  42. /package/dist/cli/{createAsyncReport-QFCSVMAO.js.map → createAsyncReport-4XB6OU6P.js.map} +0 -0
  43. /package/dist/cli/{createExtendsReportSnapRequest-X2DLPLP5.js.map → createExtendsReportSnapRequest-L2XBZPJ3.js.map} +0 -0
  44. /package/dist/cli/{findBaselineReport-N4AUOVXP.js.map → findBaselineReport-K4JN4ZMB.js.map} +0 -0
  45. /package/dist/cli/{getFlakes-M2LSXSTW.js.map → getFlakes-6GNOYD2U.js.map} +0 -0
  46. /package/dist/cli/{package-3UUMFV7J.js.map → package-UABOUH2S.js.map} +0 -0
  47. /package/dist/cli/{prepareSnapRequests-RINWFSWA.js.map → prepareSnapRequests-KMVRPKIT.js.map} +0 -0
  48. /package/dist/cli/{startJob-JAVHOIR6.js.map → startJob-TUFOU2O5.js.map} +0 -0
  49. /package/dist/cli/{wrapper-YYNZLEMW.js.map → wrapper-XUOTVPDW.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/cli/index.ts", "../../src/config/loadConfig.ts", "../../src/config/openBrowser.ts", "../../src/config/promptUser.ts", "../../src/config/getShortLivedAPIToken.ts", "../../src/environment/index.ts", "../../src/isomorphic/parseOnly.ts", "../../src/cli/parseOptions.ts", "../../src/cli/telemetry.ts", "../../src/cli/main.ts"],
4
- "sourcesContent": ["import path from 'node:path';\nimport { parseArgs } from 'node:util';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport { findConfigFile, loadConfigFile } from '../config/loadConfig.ts';\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport resolveEnvironment from '../environment/index.ts';\nimport { validateOnly } from '../isomorphic/parseOnly.ts';\nimport { validateSkip } from '../isomorphic/parseSkip.ts';\nimport type { Logger, OnlyItem, SkipItem } from '../isomorphic/types.ts';\nimport type { ParsedCLIArgs } from './parseOptions.ts';\nimport { parseOptions } from './parseOptions.ts';\nimport type { Reporter } from './telemetry.ts';\nimport { createReporter } from './telemetry.ts';\n\nasync function getVersion() {\n const packageJson = await import('../../package.json', {\n with: { type: 'json' },\n });\n return packageJson.default.version;\n}\n\nfunction parseDashdashCommandParts(\n rawArgs: Array<string>,\n): Array<string> | undefined {\n const dashdashIndex = rawArgs.indexOf('--');\n if (dashdashIndex === -1) {\n return undefined;\n }\n return rawArgs.slice(dashdashIndex + 1);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const n = b.length;\n const row = Array.from({ length: n + 1 }, (_, j) => j);\n\n for (let i = 1; i <= a.length; i++) {\n let prev = row[0]!;\n row[0] = i;\n for (let j = 1; j <= n; j++) {\n const temp = row[j]!;\n row[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, temp, row[j - 1]!);\n prev = temp;\n }\n }\n\n return row[n]!;\n}\n\nfunction findClosestOption(\n unknownName: string,\n knownNames: ReadonlyArray<string>,\n): string | undefined {\n let bestMatch: string | undefined;\n let bestDistance = Infinity;\n\n for (const known of knownNames) {\n const distance = levenshtein(unknownName, known);\n const threshold = Math.floor(Math.max(unknownName.length, known.length) / 3);\n if (distance <= threshold && distance < bestDistance) {\n bestDistance = distance;\n bestMatch = known;\n }\n }\n\n return bestMatch;\n}\n\nfunction parseRawArgs(rawArgs: Array<string>) {\n try {\n const parsedArgs = parseArgs({\n args: rawArgs,\n options: parseOptions,\n allowPositionals: true,\n });\n\n return {\n ...parsedArgs,\n dashdashCommandParts: parseDashdashCommandParts(rawArgs),\n };\n } catch (error) {\n if (\n error instanceof Error &&\n 'code' in error &&\n error.code === 'ERR_PARSE_ARGS_UNKNOWN_OPTION'\n ) {\n const match = error.message.match(/^Unknown option '(--[^']+)'/);\n\n if (match && match[1]) {\n const unknownOption = match[1];\n const suggestion = findClosestOption(\n unknownOption.slice(2),\n Object.keys(parseOptions),\n );\n\n if (suggestion !== undefined) {\n throw new TypeError(\n `Unknown option: '${unknownOption}'. Did you mean '--${suggestion}'?`,\n { cause: error },\n );\n }\n }\n }\n throw error;\n }\n}\n\nconst helpText = `Happo ${await getVersion()}\nUsage: happo [options]\n\nCommands:\n <default> Run happo tests\n finalize Finalize happo report for Cypress/Playwright tests running in parallel\n flake List reported flakes for a project\n\nOptions:\n --config Path to happo config file\n --version Show version number\n --help Show help text\n --baseBranch <branch> Base branch to use for comparison (default: 'origin/main')\n --link <url> URL to contextualize the comparison (default: auto-detected from CI environment)\n --message <message> Message to associate with the comparison (default: auto-detected from CI environment)\n --authorEmail <email> Email address of the author of the comparison (default: auto-detected from CI environment)\n --afterSha <sha> \"After\" SHA to use for comparison (default: auto-detected from CI environment, or HEAD SHA if not set)\n --beforeSha <sha> \"Before\" SHA to use for comparison (default: auto-detected from CI environment)\n --beforeShaTagMatcher <matcher> git tag matcher to use for \"before\" SHA resolution\n --fallbackShas <shas> Space-, newline- or comma-separated list of fallback shas for compare calls (default: auto-detected from CI environment)\n --fallbackShasCount <count> Number of fallback shas to use for compare calls (default: 50)\n --notify <emails> One or more (comma-separated) email addresses to notify with results\n --nonce <nonce> Nonce to use for Cypress/Playwright comparison\n --githubToken <token> GitHub token to use for posting Happo statuses as comments. Use in combination with the \\`githubApiUrl\\` configuration option. (default: auto-detected from environment)\n --skip <json> JSON array of {component, variant} objects to skip in this run and borrow from the nearest baseline report instead\n --only <json> JSON array of {component} or {storyFile} objects to include in this run (all other stories are skipped); only supported for the Storybook integration\n\nFlake command options:\n --allProjects List flakes across all projects (default: current project)\n --format <format> Output format for flake command (default: \"human\", use \"json\" for raw output)\n --project <name> Project to filter flakes for (default: project from config)\n --limit <number> Limit flake results (default: 100, max: 1000)\n --page <number> Page number for flakes (default: 1)\n --component <name> Filter flakes by component name\n --variant <name> Filter flakes by variant name\n --target <name> Filter flakes by target name\n --sha <sha> Filter flakes by before/after sha\n\nExamples:\n happo\n\n happo --config path/to/happo.config.ts\n happo --baseBranch origin/long-lived-branch\n happo --link https://github.com/happo/happo/pull/123\n happo --message \"Add new feature\"\n happo --notify me@example.com,you@example.com\n happo --nonce my-unique-nonce\n happo --githubToken {{ secrets.GITHUB_TOKEN }}\n\n happo --version\n happo --help\n\n happo -- playwright test\n\n happo --skip '[{\"component\":\"Button\",\"variant\":\"Primary\"}]'\n happo --only '[{\"component\":\"Button\"},{\"storyFile\":\"./src/Input.stories.tsx\"}]'\n\n happo finalize\n happo finalize --nonce my-unique-nonce\n happo finalize --skip '[{\"component\":\"Button\",\"variant\":\"primary\",\"target\":\"chrome\"}]'\n\n happo flake\n happo flake --allProjects\n happo flake --format=json\n happo flake --project=test-project --limit=10 --page=2\n happo flake --component=button --variant=primary --target=chrome\n happo flake --sha=ff2df74c1730341240840010c7518b2c1f4b55cb\n `;\n\nfunction makeAbsolute(configFilePath: string): string {\n if (configFilePath.startsWith('.')) {\n return path.resolve(process.cwd(), configFilePath);\n }\n return configFilePath;\n}\n\nfunction installErrorHandlers(reporter: Reporter, logger: Logger) {\n const unhandledRejectionHandler: NodeJS.UnhandledRejectionListener = (reason) => {\n if (reason instanceof Error) {\n reporter.captureException(reason);\n logger.error(reason.stack || reason.message || String(reason));\n } else {\n reporter.captureException(reason);\n logger.error(`Unhandled rejection (non-Error value): ${String(reason)}`);\n }\n\n process.exitCode = 1;\n return;\n };\n\n const uncaughtExceptionHandler: NodeJS.UncaughtExceptionListener = (error) => {\n reporter.captureException(error);\n logger.error(error.stack || error.message || String(error));\n process.exitCode = 1;\n };\n\n process.on('unhandledRejection', unhandledRejectionHandler);\n process.on('uncaughtException', uncaughtExceptionHandler);\n\n return () => {\n process.removeListener('unhandledRejection', unhandledRejectionHandler);\n process.removeListener('uncaughtException', uncaughtExceptionHandler);\n };\n}\n\nexport async function main(\n rawArgs: Array<string> = process.argv,\n logger: Logger = console,\n): Promise<void> {\n const reporter = createReporter();\n const uninstallErrorHandlers = installErrorHandlers(reporter, logger);\n\n try {\n const args = parseRawArgs(rawArgs.slice(2));\n\n if (args.values.version) {\n // --version\n logger.log(await getVersion());\n return;\n }\n\n if (args.values.help) {\n // --help\n logger.log(helpText);\n return;\n }\n\n const environment = await resolveEnvironment(args.values);\n\n // Get config file path (use --config if provided, otherwise find default)\n const configFilePath = makeAbsolute(args.values.config || findConfigFile());\n const config = await loadConfigFile(configFilePath, environment, logger);\n\n if (args.values.project !== undefined) {\n config.project = args.values.project;\n }\n\n // Handle positional arguments (commands)\n const command = args.positionals[0];\n\n if (args.dashdashCommandParts) {\n let validatedSkipJSON: string | undefined;\n if (environment.skip) {\n try {\n validateSkip(environment.skip);\n } catch (e) {\n logger.error(\n '[HAPPO] Invalid --skip:',\n e instanceof Error ? e.message : String(e),\n );\n process.exitCode = 1;\n return;\n }\n validatedSkipJSON = environment.skip;\n }\n await handleE2ECommand(\n config,\n environment,\n args.dashdashCommandParts,\n configFilePath,\n logger,\n validatedSkipJSON,\n );\n return;\n }\n\n if (command === 'finalize') {\n await handleFinalizeCommand(config, environment, logger);\n return;\n }\n\n if (command === 'flake') {\n const flakeOptions: FlakeCommandOptions = {};\n if (args.values.allProjects !== undefined) {\n flakeOptions.allProjects = args.values.allProjects;\n }\n if (args.values.format !== undefined) {\n flakeOptions.format = args.values.format;\n }\n if (args.values.project !== undefined) {\n flakeOptions.project = args.values.project;\n }\n if (args.values.limit !== undefined) {\n flakeOptions.limit = args.values.limit;\n }\n if (args.values.page !== undefined) {\n flakeOptions.page = args.values.page;\n }\n if (args.values.component !== undefined) {\n flakeOptions.component = args.values.component;\n }\n if (args.values.variant !== undefined) {\n flakeOptions.variant = args.values.variant;\n }\n if (args.values.target !== undefined) {\n flakeOptions.target = args.values.target;\n }\n if (args.values.sha !== undefined) {\n flakeOptions.sha = args.values.sha;\n }\n await handleFlakeCommand(config, flakeOptions, logger);\n return;\n }\n\n if (command === undefined) {\n await handleDefaultCommand(config, environment, logger);\n return;\n }\n\n logger.error(`Unknown command: ${command}\\n`);\n logger.error(helpText);\n process.exitCode = 1;\n } catch (error) {\n await reporter.captureException(error);\n logger.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n } finally {\n uninstallErrorHandlers();\n }\n}\n\nasync function handleDefaultCommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n logger: Logger,\n): Promise<void> {\n logger.log('Running happo tests...');\n\n const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] =\n await Promise.all([\n (await import('../network/startJob.ts')).default,\n (await import('../network/createAsyncComparison.ts')).default,\n (await import('../network/createAsyncReport.ts')).default,\n (await import('../network/prepareSnapRequests.ts')).default,\n ]);\n\n // Tell Happo that we are about to run a job\n await startJob(config, environment, logger);\n\n try {\n // When --skip is set, first resolve the baseline SHA. If no\n // baseline is found we fall back to a full run (no skipping).\n let skip: Array<SkipItem> | undefined;\n let baselineSha: string | undefined;\n\n if (environment.skip) {\n const supportedTypes = ['storybook', 'custom'];\n if (!supportedTypes.includes(config.integration.type)) {\n logger.error(\n `[HAPPO] --skip is not supported for integration type '${config.integration.type}'. Supported types: ${supportedTypes.join(', ')}`,\n );\n process.exitCode = 1;\n return;\n }\n\n try {\n skip = validateSkip(environment.skip);\n } catch (e) {\n logger.error(\n '[HAPPO] Invalid --skip:',\n e instanceof Error ? e.message : String(e),\n );\n process.exitCode = 1;\n return;\n }\n\n if (\n config.integration.type !== 'storybook' &&\n skip.some((item) => 'storyFile' in item)\n ) {\n logger.error(\n `[HAPPO] storyFile items in --skip are only supported for the storybook integration (current integration: '${config.integration.type}')`,\n );\n process.exitCode = 1;\n return;\n }\n\n const findBaselineReport = (\n await import('../network/findBaselineReport.ts')\n ).default;\n baselineSha = await findBaselineReport(environment, config, logger);\n if (!baselineSha) {\n logger.log(\n '[HAPPO] No baseline report found for --skip run. Generating a full report instead.',\n );\n skip = undefined;\n }\n }\n\n // When --only is set, validate and apply it (storybook only).\n let only: Array<OnlyItem> | undefined;\n\n if (environment.only) {\n if (config.integration.type !== 'storybook') {\n logger.error(\n `[HAPPO] --only is not supported for integration type '${config.integration.type}'. Supported types: storybook`,\n );\n process.exitCode = 1;\n return;\n }\n\n try {\n only = validateOnly(environment.only);\n } catch (e) {\n logger.error(\n '[HAPPO] Invalid --only:',\n e instanceof Error ? e.message : String(e),\n );\n process.exitCode = 1;\n return;\n }\n\n // Find a baseline to borrow the excluded stories from, unless --skip\n // already resolved one.\n if (!baselineSha) {\n const findBaselineReport = (\n await import('../network/findBaselineReport.ts')\n ).default;\n baselineSha = await findBaselineReport(environment, config, logger);\n if (!baselineSha) {\n logger.log(\n '[HAPPO] No baseline report found for --only run. Excluded stories will not be borrowed from a baseline.',\n );\n }\n }\n }\n\n // Prepare the snap requests for the job. This includes bundling static\n // assets and uploading them. Only pass the skip list when we have a\n // baseline to borrow the skipped examples from.\n const { snapRequestIds, resolvedSkip } = await prepareSnapRequests(config, skip, only);\n\n let allSnapRequestIds = snapRequestIds;\n\n if (skip && baselineSha) {\n const createExtendsReportSnapRequest = (\n await import('../network/createExtendsReportSnapRequest.ts')\n ).default;\n // Use storybook-resolved skip (storyFile items expanded to component names)\n // if available, otherwise fall back to the raw skip list.\n const extendsRequestId = await createExtendsReportSnapRequest(\n baselineSha,\n resolvedSkip ?? skip,\n config,\n );\n allSnapRequestIds = [...snapRequestIds, extendsRequestId];\n } else if (only && baselineSha && resolvedSkip && resolvedSkip.length > 0) {\n const createExtendsReportSnapRequest = (\n await import('../network/createExtendsReportSnapRequest.ts')\n ).default;\n // resolvedSkip here is the complement of the only list \u2014 all components\n // that were excluded and should be borrowed from the baseline.\n const extendsRequestId = await createExtendsReportSnapRequest(\n baselineSha,\n resolvedSkip,\n config,\n );\n allSnapRequestIds = [...snapRequestIds, extendsRequestId];\n }\n\n // Put together a report from the snap requests.\n const asyncReport = await createAsyncReport(\n allSnapRequestIds,\n config,\n environment,\n logger,\n );\n\n // Create an async comparison.\n logger.log(`[HAPPO] Async report URL: ${asyncReport.url}`);\n if (environment.beforeSha !== environment.afterSha) {\n const asyncComparison = await createAsyncComparison(\n config,\n environment,\n logger,\n );\n logger.log(`[HAPPO] Async comparison URL: ${asyncComparison.compareUrl}`);\n\n if (environment.link && environment.githubToken && config.githubApiUrl) {\n // githubToken and githubApiUrl are set which means that we should post\n // a comment to the PR.\n // https://docs.happo.io/docs/continuous-integration#posting-statuses-without-installing-the-happo-github-app\n const postGitHubComment = (await import('../network/postGitHubComment.ts'))\n .default;\n await postGitHubComment({\n authToken: environment.githubToken,\n link: environment.link,\n statusImageUrl: asyncComparison.statusImageUrl,\n compareUrl: asyncComparison.compareUrl,\n githubApiUrl: config.githubApiUrl,\n });\n }\n }\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n logger.error(`${config.integration.type} run failed: ${message}`, e);\n const cancelJob = (await import('../network/cancelJob.ts')).default;\n await cancelJob('failure', message, config, environment, logger);\n process.exitCode = 1;\n return;\n }\n}\n\nasync function handleFinalizeCommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n logger: Logger,\n): Promise<void> {\n logger.log('Finalizing happo report...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n\n try {\n const finalizeAll = (await import('../e2e/wrapper.ts')).finalizeAll;\n await finalizeAll({ happoConfig: config, environment, logger });\n } catch (e) {\n logger.error(e instanceof Error ? e.message : String(e), e);\n process.exitCode = 1;\n return;\n }\n process.exitCode = 0;\n return;\n}\n\ntype FlakeCommandOptions = Pick<\n ParsedCLIArgs,\n | 'allProjects'\n | 'format'\n | 'project'\n | 'limit'\n | 'page'\n | 'component'\n | 'variant'\n | 'target'\n | 'sha'\n>;\n\nasync function handleFlakeCommand(\n config: ConfigWithDefaults,\n {\n allProjects,\n format,\n project: projectOverride,\n limit,\n page,\n component,\n variant,\n target,\n sha,\n }: FlakeCommandOptions,\n logger: Logger,\n): Promise<void> {\n if (format && format !== 'json' && format !== 'human') {\n logger.error(\n `Unsupported format: ${format}. Use --format=json for raw JSON output or --format=human for human-readable output.`,\n );\n process.exitCode = 1;\n return;\n }\n\n const { default: getFlakes, formatFlakeOutput } =\n await import('../network/getFlakes.ts');\n const project = allProjects ? undefined : (projectOverride ?? config.project);\n const flakes = await getFlakes(\n {\n project,\n limit,\n page,\n component,\n variant,\n target,\n sha,\n },\n config,\n logger,\n );\n\n if (format === 'json') {\n logger.log(JSON.stringify(flakes, null, 2));\n process.exitCode = 0;\n return;\n }\n\n logger.log(formatFlakeOutput(flakes));\n process.exitCode = 0;\n}\n\nconst E2E_INTEGRATION_TYPES = ['cypress', 'playwright'];\n\nasync function handleE2ECommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n dashdashCommandParts: Array<string>,\n configFilePath: string,\n logger: Logger,\n skipJSON?: string,\n): Promise<void> {\n if (!E2E_INTEGRATION_TYPES.includes(config.integration.type)) {\n logger.error(\n `Unsupported integration type used for e2e command: ${config.integration.type}. Supported integration types for e2e are: ${E2E_INTEGRATION_TYPES.join(', ')}`,\n );\n process.exitCode = 1;\n return;\n }\n\n if (!dashdashCommandParts || dashdashCommandParts.length === 0) {\n logger.error('Missing command for e2e action');\n logger.error(helpText);\n process.exitCode = 1;\n return;\n }\n\n logger.log('Setting up happo wrapper for Cypress and Playwright...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n logger.log('Dashdash command parts:', dashdashCommandParts);\n\n const runWithWrapper = (await import('../e2e/wrapper.ts')).default;\n const exitCode = await runWithWrapper(\n dashdashCommandParts,\n config,\n environment,\n logger,\n configFilePath,\n skipJSON,\n );\n process.exitCode = exitCode;\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { any as findAny } from 'empathic/find';\n\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport type { Logger } from '../isomorphic/types.ts';\nimport fetchWithRetry from '../network/fetchWithRetry.ts';\nimport getShortLivedAPIToken from './getShortLivedAPIToken.ts';\nimport type {\n ConfigWithDefaults,\n DeepCompareSettings,\n TargetWithDefaults,\n} from './index.ts';\n\nconst CONFIG_FILENAMES = [\n 'happo.config.js',\n 'happo.config.mjs',\n 'happo.config.cjs',\n 'happo.config.ts',\n 'happo.config.mts',\n 'happo.config.cts',\n];\n\nconst DEFAULT_ENDPOINT = 'https://happo.io';\n\nexport function findConfigFile(): string {\n if (process.env.HAPPO_CONFIG_FILE) {\n return process.env.HAPPO_CONFIG_FILE;\n }\n\n const configFilePath = findAny(CONFIG_FILENAMES, { cwd: process.cwd() });\n\n if (!configFilePath) {\n throw new Error(\n 'Happo config file could not be found. Please create a config file in the root of your project.',\n );\n }\n\n return configFilePath;\n}\n\nfunction assertIsPullRequestTokenResponse(\n response: unknown,\n): asserts response is { secret: string } {\n if (typeof response !== 'object' || response === null || !('secret' in response)) {\n throw new TypeError('Unexpected pull request token response');\n }\n}\n\nasync function getPullRequestSecret(\n endpoint: string,\n prUrl: string,\n logger: Logger,\n): Promise<string> {\n const url = new URL('/api/pull-request-token', endpoint);\n const res = await fetchWithRetry(\n url,\n {\n method: 'POST',\n body: { prUrl },\n retryCount: 3,\n },\n logger,\n );\n\n if (!res || !res.ok) {\n throw new Error(\n `Failed to get pull request secret: ${res.status} - ${await res.text()}`,\n );\n }\n\n const json = await res.json();\n assertIsPullRequestTokenResponse(json);\n\n return json.secret;\n}\n\nasync function getFallbackApiToken(\n endpoint: string,\n environment: Pick<EnvironmentResult, 'link' | 'ci'> | undefined,\n logger: Logger,\n): Promise<{ key: string; secret: string } | undefined> {\n if (environment?.link) {\n try {\n // Fetch pull request auth\n const pullRequestSecret = await getPullRequestSecret(\n endpoint,\n environment.link,\n logger,\n );\n return {\n key: environment.link,\n secret: pullRequestSecret,\n };\n } catch {\n logger.log(\n `Failed to obtain temporary pull-request token for URL: ${environment.link}`,\n );\n }\n }\n\n if (!environment?.ci) {\n const shortLivedApiToken = await getShortLivedAPIToken(endpoint, logger);\n return shortLivedApiToken ?? undefined;\n }\n return undefined;\n}\n\nfunction validateDeepCompareSettings(\n deepCompare: DeepCompareSettings,\n configFilePath: string,\n): asserts deepCompare is DeepCompareSettings {\n if (typeof deepCompare !== 'object' || Array.isArray(deepCompare)) {\n throw new TypeError(\n `Invalid \\`deepCompare\\` in config file ${configFilePath}: must be an object, got: ${Array.isArray(deepCompare) ? 'array' : typeof deepCompare}.`,\n );\n }\n\n const settings = deepCompare as DeepCompareSettings;\n\n if (!('compareThreshold' in settings) || settings.compareThreshold === undefined) {\n throw new TypeError(\n `Invalid \\`deepCompare\\` in config file ${configFilePath}: \\`compareThreshold\\` is required.`,\n );\n }\n\n if (\n typeof settings.compareThreshold !== 'number' ||\n settings.compareThreshold < 0 ||\n settings.compareThreshold > 1\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.compareThreshold\\` in config file ${configFilePath}: must be a number between 0 and 1, got: ${JSON.stringify(settings.compareThreshold)}.`,\n );\n }\n\n if (\n 'diffAlgorithm' in settings &&\n settings.diffAlgorithm !== undefined &&\n (typeof settings.diffAlgorithm !== 'string' ||\n (settings.diffAlgorithm !== 'color-delta' &&\n settings.diffAlgorithm !== 'ssim'))\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.diffAlgorithm\\` in config file ${configFilePath}: must be \"color-delta\" or \"ssim\", got: ${JSON.stringify(settings.diffAlgorithm)}.`,\n );\n }\n\n if (\n 'ignoreThreshold' in settings &&\n settings.ignoreThreshold !== undefined &&\n (typeof settings.ignoreThreshold !== 'number' ||\n settings.ignoreThreshold < 0 ||\n settings.ignoreThreshold > 1)\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.ignoreThreshold\\` in config file ${configFilePath}: must be a number between 0 and 1, got: ${JSON.stringify(settings.ignoreThreshold)}.`,\n );\n }\n\n if (\n 'ignoreWhitespace' in settings &&\n settings.ignoreWhitespace !== undefined &&\n typeof settings.ignoreWhitespace !== 'boolean'\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.ignoreWhitespace\\` in config file ${configFilePath}: must be a boolean, got: ${JSON.stringify(settings.ignoreWhitespace)}.`,\n );\n }\n\n if (\n 'applyBlur' in settings &&\n settings.applyBlur !== undefined &&\n typeof settings.applyBlur !== 'boolean'\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.applyBlur\\` in config file ${configFilePath}: must be a boolean, got: ${JSON.stringify(settings.applyBlur)}.`,\n );\n }\n}\n\nexport async function loadConfigFile(\n configFilePath: string,\n environment?: Pick<EnvironmentResult, 'link' | 'ci'>,\n logger: Logger = console,\n): Promise<ConfigWithDefaults> {\n try {\n const stats = await fs.promises.stat(configFilePath);\n if (!stats.isFile()) {\n throw new Error(`Happo config file path is not a file: ${configFilePath}`);\n }\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n throw new Error(`Happo config file could not be found: ${configFilePath}`, {\n cause: error,\n });\n }\n\n throw error;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: change this to unknown and add type assertions\n let config: any;\n try {\n config = (await import(pathToFileURL(configFilePath).href)).default;\n } catch (error) {\n if (\n error instanceof Error &&\n 'code' in error &&\n error.code === 'ERR_UNKNOWN_FILE_EXTENSION'\n ) {\n // Older versions of Node don't support .ts files natively, so let's throw\n // a more helpful error message.\n const extension = path.extname(configFilePath);\n throw new TypeError(\n `Your Happo config file ${configFilePath} is using an extension that is not supported by this version of Node.js (${extension}). Please use a newer version of Node.js (22.18.0+, 23.6.0+, or 24+).`,\n { cause: error },\n );\n }\n\n throw error;\n }\n\n if (config === null) {\n throw new TypeError(\n `Your Happo config file ${configFilePath} must have a default export that is an object, got: null.`,\n );\n }\n\n if (typeof config !== 'object') {\n throw new TypeError(\n `Your Happo config file ${configFilePath} must have a default export that is an object, got: ${typeof config}.`,\n );\n }\n\n if (Array.isArray(config)) {\n throw new TypeError(\n `Your Happo config file ${configFilePath} must have a default export that is an object, got: array.`,\n );\n }\n\n // We read these in here so that they can be passed along to the child process\n // in e2e/wrapper.ts. This allows us to use pull-request authentication\n // without having to make an additional HTTP request.\n if (!config.apiKey && process.env.HAPPO_API_KEY) {\n config.apiKey = process.env.HAPPO_API_KEY;\n }\n if (!config.apiSecret && process.env.HAPPO_API_SECRET) {\n config.apiSecret = process.env.HAPPO_API_SECRET;\n }\n\n if (!config.apiKey || !config.apiSecret) {\n const missing = [\n config.apiKey ? null : 'apiKey',\n config.apiSecret ? null : 'apiSecret',\n ]\n .filter(Boolean)\n .map((key) => `\\`${key}\\``)\n .join(' and ');\n\n logger.log(\n `Missing ${missing} in Happo config. Attempting alternative authentication.`,\n );\n const fallbackApiToken = await getFallbackApiToken(\n config.endpoint || DEFAULT_ENDPOINT,\n environment,\n logger,\n );\n if (!fallbackApiToken) {\n throw new Error(\n `Missing ${missing} in your Happo config. Reference yours at https://happo.io/settings`,\n );\n }\n config.apiKey = fallbackApiToken.key;\n config.apiSecret = fallbackApiToken.secret;\n }\n\n if (!config.targets) {\n config.targets = {\n chrome: {\n type: 'chrome',\n viewport: '1024x768',\n },\n };\n }\n\n if (!config.integration) {\n config.integration = {\n type: 'storybook',\n };\n }\n\n const allTargets = Object.values(config.targets);\n for (const target of allTargets as Array<TargetWithDefaults>) {\n target.viewport = target.viewport || '1024x768';\n target.freezeAnimations = target.freezeAnimations || 'last-frame';\n target.prefersReducedMotion = target.prefersReducedMotion ?? true;\n target.allowPointerEvents = target.allowPointerEvents ?? true;\n }\n\n // Validate deepCompare settings if present\n if (config.deepCompare !== undefined && config.deepCompare !== null) {\n validateDeepCompareSettings(config.deepCompare, configFilePath);\n // Set default diffAlgorithm if not provided\n if (!config.deepCompare.diffAlgorithm) {\n config.deepCompare.diffAlgorithm = 'color-delta';\n }\n }\n\n const configWithDefaults = {\n endpoint: DEFAULT_ENDPOINT,\n githubApiUrl: 'https://api.github.com',\n targets: allTargets,\n ...config,\n };\n\n return configWithDefaults;\n}\n", "import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport default function openBrowser(url: string): Promise<void> {\n const platform = process.platform;\n let command: string;\n\n if (platform === 'darwin') {\n command = `open \"${url}\"`;\n } else if (platform === 'win32') {\n command = `start \"\" \"${url}\"`;\n } else {\n // Linux and others\n command = `xdg-open \"${url}\"`;\n }\n\n return execAsync(command).then(() => {\n // Ignore errors - browser might not open, but that's okay\n });\n}\n", "import { createInterface } from 'node:readline';\n\nexport default function promptUser(message: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(message, (answer) => {\n rl.close();\n // Only proceed if Enter was pressed (empty string or newline)\n if (answer.trim() === '') {\n resolve();\n } else {\n reject(new Error('User cancelled authentication'));\n }\n });\n });\n}\n", "import type { Logger } from '../isomorphic/types.ts';\nimport startServer from '../network/startServer.ts';\nimport openBrowser from './openBrowser.ts';\nimport promptUser from './promptUser.ts';\n\nconst VALID_HEX_REGEX = /^[0-9a-fA-F]+$/;\n\nfunction createHTML(endpoint: string, phase: string): string {\n return `<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <title>Happo CLI Authentication</title>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script type=\"text/javascript\">\n const message = { type: 'happo-cli-auth', payload: { phase: '${phase}' } };\n // Use the exact origin of the parent page\n window.parent.postMessage(message, '${endpoint}'); \n </script>\n </head>\n <body>\n <main>\n <h1>Happo CLI Authentication</h1> \n <p>Authentication successful!</p>\n </main>\n </body>\n </html>`;\n}\n\nfunction validateKeyAndSecret(args: {\n key: string | null;\n secret: string | null;\n}): args is { key: string; secret: string } {\n const { key, secret } = args;\n if (!key) {\n return false;\n }\n if (!secret) {\n return false;\n }\n if (key.length < 10 || key.length > 64) {\n return false;\n }\n if (secret.length < 20 || secret.length > 256) {\n return false;\n }\n // validate that key and secret are valid hex strings\n if (!VALID_HEX_REGEX.test(key)) {\n return false;\n }\n if (!VALID_HEX_REGEX.test(secret)) {\n return false;\n }\n return true;\n}\n\nexport default async function getShortLivedAPIToken(\n endpoint: string,\n logger: Logger,\n): Promise<{ key: string; secret: string } | null> {\n if (!process.stdin.isTTY) {\n return null;\n }\n // Prompt user to press Enter only if in an interactive terminal\n await promptUser('Press <Enter> to authenticate in the browser');\n\n // Set up promise to wait for callback\n let resolveCallback: (value: { key: string; secret: string }) => void;\n let rejectCallback: (error: Error) => void;\n const callbackPromise = new Promise<{ key: string; secret: string }>(\n (resolve, reject) => {\n resolveCallback = resolve;\n rejectCallback = reject;\n },\n );\n\n // Start local server on auto port\n const serverInfo = await startServer((req, res) => {\n // Get port from the request socket\n const url = new URL(req.url ?? '', `http://localhost:${serverInfo.port}`);\n\n if (url.pathname === '/callback') {\n const token = {\n key: url.searchParams.get('key'),\n secret: url.searchParams.get('secret'),\n };\n const ping = url.searchParams.get('ping');\n\n if (ping) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(createHTML(endpoint, 'auth'));\n return;\n }\n if (validateKeyAndSecret(token)) {\n // Send success response\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(createHTML(endpoint, 'done'));\n\n // Resolve the promise with token and secret\n return resolveCallback(token);\n }\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end('Bad request');\n return rejectCallback(new Error('Missing key or secret in callback'));\n }\n\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n });\n\n const callbackUrl = `http://localhost:${serverInfo.port}/callback`;\n const authUrl = `${endpoint}/cli/auth?callbackUrl=${encodeURIComponent(callbackUrl)}`;\n\n try {\n // Open browser\n console.log(`Opening URL: ${authUrl}`);\n await openBrowser(authUrl);\n const result = await callbackPromise;\n return result;\n } catch (error) {\n logger.error(\n `Failed to authenticate: ${error instanceof Error ? error.message : String(error)}`,\n );\n return null;\n } finally {\n // Clean up server\n await serverInfo.close();\n }\n}\n", "import { spawnSync } from 'node:child_process';\nimport crypto, { randomBytes } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\n\nimport type { ParsedCLIArgs } from '../cli/parseOptions.ts';\n\nconst NUMBER_OF_COMMITS_TO_FETCH = 50;\nconst FULL_SHA_REGEX = /^[a-f0-9]{40}$/i;\n\ninterface GitHubEvent {\n pull_request?: {\n html_url: string;\n title: string;\n base: {\n sha: string;\n };\n head: {\n sha: string;\n };\n };\n head_commit?: {\n url: string;\n };\n merge_group?: {\n head_sha: string;\n base_sha: string;\n };\n repository?: {\n html_url: string;\n };\n before?: string;\n after?: string;\n}\n\nexport interface EnvironmentResult {\n link: string | undefined;\n message: string | undefined;\n authorEmail: string | undefined;\n beforeSha: string;\n afterSha: string;\n nonce: string | undefined;\n debugMode: boolean;\n notify: string | undefined;\n fallbackShas: Array<string> | undefined;\n githubToken: string | undefined;\n ci: boolean;\n skip: string | undefined;\n only: string | undefined;\n}\n\nconst envKeys: ReadonlyArray<string> = [\n 'BUILD_REPOSITORY_URI',\n 'BUILD_SOURCEVERSION',\n 'CIRCLE_PROJECT_REPONAME',\n 'CIRCLE_PROJECT_USERNAME',\n 'CIRCLE_SHA1',\n 'CI_PULL_REQUEST',\n 'GITHUB_EVENT_PATH',\n 'GITHUB_SERVER_URL',\n 'GITHUB_SHA',\n 'HAPPO_DEBUG',\n 'SYSTEM_PULLREQUEST_PULLREQUESTID',\n 'SYSTEM_PULLREQUEST_SOURCEBRANCH',\n 'SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI',\n 'SYSTEM_PULLREQUEST_TARGETBRANCH',\n 'TRAVIS_COMMIT',\n 'TRAVIS_COMMIT_RANGE',\n 'TRAVIS_PULL_REQUEST',\n 'TRAVIS_PULL_REQUEST_SHA',\n 'TRAVIS_REPO_SLUG',\n];\n\nasync function resolveGithubEvent(GITHUB_EVENT_PATH: string): Promise<GitHubEvent> {\n try {\n const fs = await import('node:fs/promises');\n const content = await fs.readFile(GITHUB_EVENT_PATH, 'utf8');\n return JSON.parse(content);\n } catch (e) {\n throw new Error(\n `Failed to load GitHub event from the GITHUB_EVENT_PATH environment variable: ${JSON.stringify(GITHUB_EVENT_PATH)}`,\n { cause: e },\n );\n }\n}\n\nasync function resolveLink(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n if (cliArgs.link) {\n // Validate the link\n let parsed: URL;\n try {\n parsed = new URL(cliArgs.link);\n } catch (e) {\n throw new TypeError(\n `link must be a valid http/https URL. Invalid URL: '${cliArgs.link}'`,\n { cause: e },\n );\n }\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new TypeError(\n `link must be a valid http/https URL. Invalid protocol: '${parsed.protocol}' (from '${cliArgs.link}')`,\n );\n }\n\n return cliArgs.link;\n }\n\n const {\n BUILD_REPOSITORY_URI,\n BUILD_SOURCEVERSION,\n\n // https://circleci.com/docs/reference/variables/\n CIRCLE_PROJECT_REPONAME,\n CIRCLE_PROJECT_USERNAME,\n CIRCLE_PULL_REQUEST,\n CIRCLE_SHA1,\n\n CI_PULL_REQUEST,\n\n // https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n\n SYSTEM_PULLREQUEST_PULLREQUESTID,\n SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI,\n\n // https://docs.travis-ci.com/user/environment-variables/#default-environment-variables\n TRAVIS_COMMIT,\n TRAVIS_PULL_REQUEST,\n TRAVIS_REPO_SLUG,\n } = env;\n\n if (CI_PULL_REQUEST) {\n // Circle CI\n return CI_PULL_REQUEST;\n }\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.html_url;\n }\n if (ghEvent.head_commit) {\n return ghEvent.head_commit.url;\n }\n if (ghEvent.merge_group && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${ghEvent.merge_group.head_sha}`;\n }\n if (GITHUB_SHA && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${GITHUB_SHA}`;\n }\n }\n\n if (SYSTEM_PULLREQUEST_PULLREQUESTID && SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI) {\n return `${SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI}/pullrequest/${SYSTEM_PULLREQUEST_PULLREQUESTID}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n if (BUILD_REPOSITORY_URI && BUILD_SOURCEVERSION) {\n return `${BUILD_REPOSITORY_URI}/commit/${BUILD_SOURCEVERSION}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n const githubBase = 'https://github.com';\n\n if (TRAVIS_REPO_SLUG && TRAVIS_PULL_REQUEST) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/pull/${TRAVIS_PULL_REQUEST}`;\n }\n\n if (TRAVIS_REPO_SLUG && TRAVIS_COMMIT) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/commit/${TRAVIS_COMMIT}`;\n }\n\n if (CIRCLE_PULL_REQUEST) {\n return CIRCLE_PULL_REQUEST;\n }\n\n if (CIRCLE_PROJECT_USERNAME && CIRCLE_PROJECT_REPONAME && CIRCLE_SHA1) {\n return `${githubBase}/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}`;\n }\n\n return undefined;\n}\n\nasync function resolveAuthorEmail(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n if (cliArgs.authorEmail) {\n return cliArgs.authorEmail;\n }\n\n const { GITHUB_EVENT_PATH } = env;\n\n if (GITHUB_EVENT_PATH) {\n // const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n // TODO: do something with the github event\n }\n\n const res = spawnSync('git', ['show', '-s', '--format=%ae'], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n return res.stdout.trim();\n}\n\nasync function resolveMessage(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n afterSha: string,\n): Promise<string | undefined> {\n if (cliArgs.message) {\n return cliArgs.message;\n }\n\n const { GITHUB_EVENT_PATH } = env;\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.title;\n }\n }\n\n const res = spawnSync('git', ['log', '-1', '--pretty=%s', afterSha], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n const message = res.stdout.split('\\n')[0];\n\n if (!message) {\n return undefined;\n }\n\n return message;\n}\n\nfunction resolveShaFromTagMatcher(tagMatcher: string): string | undefined {\n const res = spawnSync(\n 'git',\n ['tag', '--list', tagMatcher, '--sort', 'refname', '--no-contains'],\n {\n encoding: 'utf8',\n },\n );\n\n if (res.status !== 0) {\n throw new Error(\n `Failed to list git tags when matching against --beforeShaTagMatcher '${tagMatcher}'. Error: ${res.stderr}`,\n );\n }\n\n const rawAllTags = res.stdout.trim();\n if (!rawAllTags.length) {\n return undefined;\n }\n\n const allTags = rawAllTags.split('\\n');\n const tag = allTags.at(-1);\n\n if (!tag) {\n throw new Error('No tag found matching the pattern');\n }\n\n const commitRes = spawnSync('git', ['rev-list', '-n', '1', tag], {\n encoding: 'utf8',\n });\n\n if (commitRes.status !== 0) {\n throw new Error(\n `Failed to resolve commit sha from tag \"${tag}\". Error: ${res.stderr}`,\n );\n }\n\n return commitRes.stdout.trim();\n}\n\nfunction fetchMoreHistory(\n ref: string, // can be a full SHA or a ref/branch name\n numberOfCommitsToFetch: number,\n): boolean {\n const fetchRes = spawnSync(\n 'git',\n ['fetch', 'origin', ref, `--depth=${numberOfCommitsToFetch}`],\n {\n encoding: 'utf8',\n },\n );\n const success = fetchRes.status === 0;\n if (!success) {\n console.error(\n `[HAPPO] Failed to fetch more history (${numberOfCommitsToFetch} commits) for ${ref}. Error: ${fetchRes.stderr}`,\n );\n }\n return success;\n}\n\nfunction resolveMergeBase(\n baseRef: string, // can be a full SHA or a ref/branch name\n afterSha: string,\n debugMode: boolean,\n tryNumber: number = 1,\n): string | undefined {\n const res = spawnSync('git', ['merge-base', baseRef, afterSha], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n // In GitHub Actions, checkouts can be shallow and may not include the PR base\n // commit (or enough of its history) to compute a merge-base.\n //\n // - First attempt often fails with \"Not a valid commit name <sha>\".\n // - After fetching just the base commit, a subsequent attempt can still fail\n // with exit code 1 and empty stderr because history is still too shallow.\n //\n // When the base looks like a full SHA, we can try to fetch deeper history\n // and retry with increasing depth.\n if (FULL_SHA_REGEX.test(baseRef) && tryNumber <= 10) {\n if (debugMode) {\n console.error(\n `[HAPPO] When resolving the merge base between ${baseRef} and ${afterSha}, we failed to resolve the merge base. We'll try fetching more history (${tryNumber * NUMBER_OF_COMMITS_TO_FETCH} commits) and resolving the merge base again.`,\n );\n }\n if (fetchMoreHistory(baseRef, tryNumber * NUMBER_OF_COMMITS_TO_FETCH)) {\n return resolveMergeBase(baseRef, afterSha, debugMode, tryNumber + 1);\n }\n }\n console.error(\n `[HAPPO] Ignored error when resolving merge base between ${baseRef} and ${afterSha}: ${res.stderr}`,\n );\n return undefined;\n }\n\n const mergeBase = res.stdout.split('\\n')[0]?.trim();\n\n if (!mergeBase) {\n console.error(\n `[HAPPO] git merge-base stdout is empty when resolving merge base between ${baseRef} and ${afterSha}. stdout: ${res.stdout}\\nstderr: ${res.stderr}`,\n );\n return undefined;\n }\n\n return mergeBase;\n}\n\nasync function resolveBeforeSha(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n afterSha: string,\n debugMode: boolean,\n): Promise<string | undefined> {\n if (cliArgs.beforeSha) {\n return cliArgs.beforeSha;\n }\n\n if (cliArgs.beforeShaTagMatcher) {\n const resolvedSha = resolveShaFromTagMatcher(cliArgs.beforeShaTagMatcher);\n if (resolvedSha) {\n return resolvedSha;\n }\n }\n\n const { TRAVIS_COMMIT_RANGE, GITHUB_EVENT_PATH, SYSTEM_PULLREQUEST_TARGETBRANCH } =\n env;\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n\n if (ghEvent.pull_request) {\n const resolvedSha = resolveMergeBase(\n ghEvent.pull_request.base.sha,\n afterSha,\n debugMode,\n );\n\n if (resolvedSha) {\n return resolvedSha;\n } else {\n console.error(\n `[HAPPO] Failed to resolve merge base commit for GitHub event ${ghEvent.pull_request.base.sha} and ${afterSha}. Falling back to pull request base SHA.`,\n );\n return ghEvent.pull_request.base.sha;\n }\n }\n\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.base_sha;\n }\n\n return ghEvent.before;\n }\n\n if (TRAVIS_COMMIT_RANGE) {\n const [first] = TRAVIS_COMMIT_RANGE.split('...');\n return first;\n }\n\n let baseAzureBranch;\n if (SYSTEM_PULLREQUEST_TARGETBRANCH) {\n baseAzureBranch = [\n 'origin',\n SYSTEM_PULLREQUEST_TARGETBRANCH.split('/').toReversed()[0],\n ].join('/');\n }\n\n const baseBranch = cliArgs.baseBranch || baseAzureBranch || 'origin/main';\n return resolveMergeBase(baseBranch, afterSha, debugMode);\n}\n\nfunction getHeadShaWithLocalChanges(): {\n headSha: string;\n headShaWithLocalChanges: string;\n} {\n const randomSha = randomBytes(20).toString('hex');\n // Get the HEAD sha from the git repo, or if we have local changes, add them to the sha\n const res = spawnSync('git', ['rev-parse', 'HEAD'], {\n encoding: 'utf8',\n });\n if (res.status !== 0) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n const headSha = res.stdout.split('\\n')[0];\n if (!headSha) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n\n // Check for local changes\n const diffRes = spawnSync('git', ['diff', 'HEAD'], {\n encoding: 'utf8',\n });\n\n // If git diff fails, return HEAD sha\n if (diffRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const lsRes = spawnSync('git', ['ls-files', '--other', '--exclude-standard'], {\n encoding: 'utf8',\n });\n\n if (lsRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const localChanges = [diffRes.stdout.trim(), lsRes.stdout.trim()];\n\n // Get contents of untracked files\n const untrackedFiles = lsRes.stdout\n .trim()\n .split('\\n')\n .filter((file) => file.trim());\n\n for (const file of untrackedFiles) {\n try {\n const content = readFileSync(file, 'utf8');\n localChanges.push(content);\n } catch {\n // If we can't read the file, include just the filename\n localChanges.push(`${file}:<unreadable>`);\n }\n }\n\n const allChanges = localChanges.join('');\n\n if (!allChanges.trim()) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n // If there are local changes, create a hash that includes both HEAD and the changes\n const headShaWithLocalChanges = crypto\n .createHash('sha256')\n .update(headSha)\n .update(allChanges)\n .digest('hex')\n .slice(0, 40);\n\n return { headSha, headShaWithLocalChanges };\n}\n\nasync function resolveAfterSha(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n): Promise<string | { headSha: string; headShaWithLocalChanges: string }> {\n if (cliArgs.afterSha) {\n return cliArgs.afterSha;\n }\n\n const {\n CIRCLE_SHA1,\n TRAVIS_PULL_REQUEST_SHA,\n TRAVIS_COMMIT,\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n BUILD_SOURCEVERSION,\n SYSTEM_PULLREQUEST_SOURCEBRANCH,\n CI,\n } = env;\n\n const sha = CIRCLE_SHA1 || TRAVIS_PULL_REQUEST_SHA || TRAVIS_COMMIT;\n\n if (sha) {\n return sha;\n }\n\n if (SYSTEM_PULLREQUEST_SOURCEBRANCH) {\n // azure pull request\n const rawBranchName = SYSTEM_PULLREQUEST_SOURCEBRANCH.split('/').toReversed()[0];\n const res = spawnSync('git', ['rev-parse', `origin/${rawBranchName}`], {\n encoding: 'utf8',\n });\n if (res.status === 0 && res.stdout) {\n const sha = res.stdout.split('\\n')[0];\n if (sha) {\n return sha;\n }\n }\n }\n if (BUILD_SOURCEVERSION) {\n // azure master job\n return BUILD_SOURCEVERSION;\n }\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.head.sha;\n }\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.head_sha;\n }\n if (ghEvent.after) {\n return ghEvent.after;\n }\n if (GITHUB_SHA) {\n return GITHUB_SHA;\n }\n }\n const headShaWithLocalChanges = getHeadShaWithLocalChanges();\n if (CI) {\n return headShaWithLocalChanges.headSha;\n }\n return headShaWithLocalChanges;\n}\n\nfunction resolveFallbackShas(\n cliArgs: ParsedCLIArgs,\n beforeSha: string | undefined,\n): Array<string> | undefined {\n if (cliArgs.fallbackShas) {\n return cliArgs.fallbackShas.split(/[,\\s]+/).filter(Boolean);\n }\n\n const fallbackShasCount = cliArgs.fallbackShasCount\n ? Number.parseInt(cliArgs.fallbackShasCount, 10)\n : 50;\n\n if (Number.isNaN(fallbackShasCount)) {\n throw new TypeError(\n `fallbackShasCount must be a number. Invalid value: '${cliArgs.fallbackShasCount}'`,\n );\n }\n\n const res = spawnSync(\n 'git',\n [\n 'log',\n '--format=%H',\n '--first-parent',\n `--max-count=${fallbackShasCount}`,\n `${beforeSha}^`,\n ],\n {\n encoding: 'utf8',\n },\n );\n\n if (res.status !== 0) {\n return undefined;\n }\n\n return res.stdout.split('\\n').filter(Boolean);\n}\n\nfunction getRawEnv(\n env: Record<string, string | undefined>,\n): Record<string, string | undefined> {\n const res: Record<string, string | undefined> = {};\n for (const key of envKeys) {\n res[key] = env[key];\n }\n return res;\n}\n\nexport default async function resolveEnvironment(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined> = process.env,\n): Promise<EnvironmentResult> {\n const debugMode = !!env.HAPPO_DEBUG;\n const afterSha = await resolveAfterSha(cliArgs, env);\n\n const realAfterSha = typeof afterSha === 'string' ? afterSha : afterSha.headSha;\n const afterShaWithLocalChanges =\n typeof afterSha === 'string' ? afterSha : afterSha.headShaWithLocalChanges;\n\n // Resolve the before SHA with the true HEAD SHA\n const [beforeSha, link, authorEmail, message] = await Promise.all([\n resolveBeforeSha(cliArgs, env, realAfterSha, debugMode),\n resolveLink(cliArgs, env),\n resolveAuthorEmail(cliArgs, env),\n\n // Resolve message with the SHA that includes local changes\n resolveMessage(cliArgs, env, afterShaWithLocalChanges),\n ]);\n\n const nonNullBeforeSha = beforeSha || afterShaWithLocalChanges;\n\n const result = {\n link,\n authorEmail,\n message,\n beforeSha: nonNullBeforeSha,\n afterSha: afterShaWithLocalChanges,\n nonce: cliArgs.nonce,\n debugMode,\n notify: cliArgs.notify,\n fallbackShas: resolveFallbackShas(cliArgs, nonNullBeforeSha),\n githubToken: cliArgs.githubToken,\n ci: !!env.CI,\n skip: cliArgs.skip,\n only: cliArgs.only,\n };\n\n if (debugMode) {\n console.log('[HAPPO] Raw environment', getRawEnv(env));\n console.log('[HAPPO] Resolved environment', result);\n }\n\n return result;\n}\n", "import type { OnlyItem } from './types.ts';\n\nfunction isOnlyItem(item: unknown): item is OnlyItem {\n if (typeof item !== 'object' || item === null) return false;\n const record = item as Record<string, unknown>;\n const hasComponent = typeof record['component'] === 'string';\n const hasStoryFile = typeof record['storyFile'] === 'string';\n if (hasComponent && hasStoryFile) return false;\n if (hasStoryFile) return record['variant'] === undefined;\n if (hasComponent) return record['variant'] === undefined;\n return false;\n}\n\n/**\n * Parses and validates a JSON string, returning an array of OnlyItems.\n * Throws a TypeError if the JSON is invalid or not an array of OnlyItems.\n *\n * Note: `variant` is not supported in `--only` items because variants cannot\n * be resolved statically from the Storybook built files.\n */\nexport function validateOnly(json: string): Array<OnlyItem> {\n const parsed: unknown = JSON.parse(json);\n if (!Array.isArray(parsed) || !parsed.every(isOnlyItem)) {\n throw new TypeError(\n '--only must be a JSON array of {component} or {storyFile} objects (variant is not supported)',\n );\n }\n return parsed;\n}\n\n/**\n * Parses a JSON string into an array of OnlyItems. Returns an empty array on\n * any parse error or if the value is not a valid array of OnlyItems.\n */\nexport function parseOnly(json?: string): Array<OnlyItem> {\n if (!json) return [];\n try {\n return validateOnly(json);\n } catch {\n return [];\n }\n}\n", "import { parseArgs } from 'node:util';\n\nexport const parseOptions = {\n version: {\n type: 'boolean',\n short: 'v',\n },\n\n help: {\n type: 'boolean',\n short: 'h',\n },\n\n config: {\n type: 'string',\n short: 'c',\n },\n\n baseBranch: {\n type: 'string',\n },\n\n link: {\n type: 'string',\n },\n\n message: {\n type: 'string',\n },\n\n authorEmail: {\n type: 'string',\n },\n\n afterSha: {\n type: 'string',\n },\n\n beforeSha: {\n type: 'string',\n },\n\n beforeShaTagMatcher: {\n type: 'string',\n },\n\n fallbackShas: {\n type: 'string',\n },\n\n fallbackShasCount: {\n type: 'string',\n },\n\n notify: {\n type: 'string',\n },\n\n nonce: {\n type: 'string',\n },\n\n githubToken: {\n type: 'string',\n },\n\n // Flake command options\n allProjects: {\n type: 'boolean',\n },\n\n format: {\n type: 'string',\n },\n\n project: {\n type: 'string',\n },\n\n limit: {\n type: 'string',\n },\n\n page: {\n type: 'string',\n },\n\n component: {\n type: 'string',\n },\n\n variant: {\n type: 'string',\n },\n\n target: {\n type: 'string',\n },\n\n sha: {\n type: 'string',\n },\n\n skip: {\n type: 'string',\n },\n\n only: {\n type: 'string',\n },\n} as const;\n\nexport type ParsedCLIArgs = ReturnType<\n typeof parseArgs<{ options: typeof parseOptions; allowPositionals: true }>\n>['values'];\n", "import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { createInterface } from 'node:readline';\n\nimport { up as findPackage } from 'empathic/package';\n\nimport pkg from '../../package.json' with { type: 'json' };\n\n/**\n * Happo's PUBLIC DSN. Safe to ship.\n */\nconst SENTRY_DSN =\n 'https://3a495ff2101313edb024de73b005398f@o108341.ingest.us.sentry.io/4510341337645056';\n\nconst MAX_STACK_FRAMES = 50;\nconst MAX_FUNCTION_NAME_LENGTH = 120;\n\ntype CI =\n | 'github'\n | 'circleci'\n | 'travis'\n | 'azure'\n | 'buildkite'\n | 'jenkins'\n | 'gitlab'\n | 'bitbucket'\n | 'appveyor'\n | 'drone'\n | 'ci'\n | 'unknown';\n\ntype ErrorPayload = {\n pkg: {\n name: string;\n version: string;\n };\n\n error: {\n name: string;\n message: string;\n stack?: string;\n };\n\n env: string;\n\n /** Detected CI vendor if any */\n ci: CI;\n\n nodeVersion: string;\n platform: string;\n};\n\nexport type ReporterOptions = {\n maxPerMinute?: number; // default 10\n env?: string;\n};\n\nexport interface Reporter {\n captureException(e: unknown): Promise<void>;\n}\n\nexport function detectCI(env: Record<string, string | undefined> = process.env): CI {\n if (env.GITHUB_ACTIONS) {\n return 'github';\n }\n\n if (env.CIRCLECI) {\n return 'circleci';\n }\n\n if (env.TRAVIS) {\n return 'travis';\n }\n\n if (env.TF_BUILD) {\n return 'azure';\n }\n\n if (env.BUILDKITE) {\n return 'buildkite';\n }\n\n if (env.JENKINS_URL) {\n return 'jenkins';\n }\n\n if (env.GITLAB_CI) {\n return 'gitlab';\n }\n\n if (env.BITBUCKET_BUILD_NUMBER) {\n return 'bitbucket';\n }\n\n if (env.APPVEYOR) {\n return 'appveyor';\n }\n\n if (env.DRONE) {\n return 'drone';\n }\n\n if (env.CI) {\n return 'ci';\n }\n\n return 'unknown';\n}\n\nexport function parseDsn(dsn: string): {\n host: string;\n projectId: string;\n key: string;\n protocol: string;\n} | null {\n try {\n // https://{PUBLIC_KEY}@{host}/{project_id}\n const u = new URL(dsn);\n const projectId = u.pathname.replace(/^\\//, '');\n const key = u.username; // public key\n const host = u.host; // includes subdomain + port\n return {\n host,\n projectId,\n key,\n protocol: u.protocol.replace(':', ''),\n };\n } catch {\n return null;\n }\n}\n\nasync function sendToSentry(payload: ErrorPayload) {\n const dsn = parseDsn(SENTRY_DSN);\n\n if (!dsn) {\n return;\n }\n\n // Sentry envelope: https://develop.sentry.dev/sdk/envelopes/\n const now = Date.now();\n\n // Hexadecimal string representing a uuid4 value. The length is exactly 32\n // characters. Dashes are not allowed. Has to be lowercase.\n const eventId = crypto.randomUUID().replaceAll('-', '');\n\n const url = `https://${dsn.host}/api/${dsn.projectId}/envelope/`;\n\n const httpHeaders = {\n 'content-type': 'application/x-sentry-envelope',\n 'x-sentry-auth': [\n 'Sentry sentry_version=7',\n `sentry_key=${dsn.key}`,\n `sentry_client=${pkg.name}@${pkg.version}`,\n ].join(', '),\n };\n\n const memoryInfo = process.memoryUsage();\n\n // Minimal event; we keep fields lean & sanitized\n // https://develop.sentry.dev/sdk/data-model/event-payloads/#required-attributes\n const event = {\n event_id: eventId,\n\n // RFC 3339 format\n timestamp: new Date(now).toISOString(),\n\n // A string representing the platform the SDK is submitting from. This will\n // be used by the Sentry interface to customize various components in the\n // interface.\n platform: 'node',\n\n // Possible values: fatal, error, warning, info, debug\n level: 'error',\n\n logger: 'happo.telemetry.cli',\n\n environment: payload.env ?? 'unknown',\n\n // Release versions must be unique across all projects in the organization.\n release: `${payload.pkg.name}@${payload.pkg.version}`,\n\n tags: {\n ci: payload.ci ?? '',\n },\n\n contexts: {\n runtime: {\n type: 'runtime',\n name: 'node',\n version: payload.nodeVersion ?? '',\n },\n os: {\n type: 'os',\n name: payload.platform ?? '',\n },\n memory_info: {\n type: 'memory_info',\n ...memoryInfo,\n },\n },\n\n exception: {\n values: [\n {\n type: payload.error.name || 'Error',\n value: payload.error.message,\n\n // https://develop.sentry.dev/sdk/data-model/event-payloads/stacktrace/\n stacktrace: payload.error.stack\n ? {\n frames: await parseFrames(payload.error.stack),\n }\n : undefined,\n },\n ],\n },\n };\n\n /**\n * Envelope is ndjson-like chunks\n *\n * Envelope = Headers { \"\\n\" Item } [ \"\\n\" ] ;\n * Item = Headers \"\\n\" Payload ;\n * Payload = { * } ;\n *\n * @see https://develop.sentry.dev/sdk/data-model/envelopes/#headers\n */\n const envelopeHeader = JSON.stringify({\n event_id: eventId,\n dsn: SENTRY_DSN,\n sent_at: new Date(now).toISOString(),\n });\n\n // https://develop.sentry.dev/sdk/data-model/envelopes/#items\n const item = JSON.stringify(event);\n const itemHeader = JSON.stringify({ type: 'event', length: item.length });\n\n const body = [envelopeHeader, itemHeader, item].join('\\n');\n\n try {\n await fetch(url, { method: 'POST', headers: httpHeaders, body });\n } catch {\n // swallow; never throw in library code\n }\n}\n\ninterface SentryFrame {\n function: string;\n raw_function: string;\n abs_path: string | undefined;\n filename: string | undefined;\n lineno: number | undefined;\n colno: number | undefined;\n context_line?: string;\n pre_context?: Array<string>;\n post_context?: Array<string>;\n}\n\n/**\n * Get the package root directory\n */\nfunction getPackageRoot(): string {\n const packageJsonPath = findPackage({ cwd: import.meta.dirname });\n\n if (!packageJsonPath) {\n // Fallback to relative path if empathic can't find it\n return path.resolve(import.meta.dirname, '../..');\n }\n\n return path.dirname(packageJsonPath);\n}\n\n/**\n * Check if a file path is part of this package\n */\nfunction isFileInThisPackage(filePath: string): boolean {\n // Skip node: internal modules\n if (filePath.startsWith('node:')) {\n return false;\n }\n\n try {\n const packageRoot = getPackageRoot();\n // Remove file:// prefix if present\n const cleanPath = filePath.replace(/^file:\\/\\//, '');\n const resolvedPath = path.resolve(cleanPath);\n return resolvedPath.startsWith(packageRoot + path.sep);\n } catch {\n return false;\n }\n}\n\n/**\n * Read context lines from a source file around a given line number\n * Only reads files that are part of this package\n */\nasync function readContextLines(\n filePath: string,\n lineNumber: number,\n contextLines: number = 5,\n): Promise<{\n context_line?: string;\n pre_context?: Array<string>;\n post_context?: Array<string>;\n}> {\n // Only read context for files in this package. This is to avoid reading\n // context from external files that may contain sensitive information.\n if (!isFileInThisPackage(filePath)) {\n return {};\n }\n\n try {\n // Remove file:// prefix if present\n const cleanPath = filePath.replace(/^file:\\/\\//, '');\n\n // Line numbers are 1-indexed in stack traces, but arrays are 0-indexed\n const lineIndex = lineNumber - 1;\n\n if (lineIndex < 0) {\n return {};\n }\n\n const startLine = Math.max(0, lineIndex - contextLines);\n const endLine = lineIndex + contextLines + 1;\n\n const pre_context: Array<string> = [];\n let context_line: string | undefined;\n const post_context: Array<string> = [];\n\n const fileStream = fs.createReadStream(cleanPath, { encoding: 'utf8' });\n const rl = createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n let currentLine = 0;\n\n for await (const line of rl) {\n if (currentLine < startLine) {\n // Skip lines before our context window\n currentLine++;\n continue;\n }\n\n if (currentLine === lineIndex) {\n context_line = line;\n } else if (currentLine < lineIndex) {\n pre_context.push(line);\n } else if (currentLine < endLine) {\n post_context.push(line);\n } else {\n // We've read all the lines we need\n break;\n }\n\n currentLine++;\n }\n\n // Check if we found the target line\n if (context_line === undefined) {\n return {};\n }\n\n const result: {\n context_line: string;\n pre_context?: Array<string>;\n post_context?: Array<string>;\n } = {\n context_line,\n };\n\n if (pre_context.length > 0) {\n result.pre_context = pre_context;\n }\n\n if (post_context.length > 0) {\n result.post_context = post_context;\n }\n\n return result;\n } catch {\n // File might not exist, might not be readable, etc. Best-effort only.\n return {};\n }\n}\n\n/**\n * Convert an error stack to Sentry frames (best-effort)\n */\nexport async function parseFrames(\n stack: string,\n cwd: string = process.cwd(),\n): Promise<Array<SentryFrame>> {\n // Node stack lines like: \" at func (file:///absolute/path/to/file.js:10:5)\"\n const stackLines = stack.split('\\n').slice(0, MAX_STACK_FRAMES);\n\n const frames = [];\n\n for (const stackLine of stackLines) {\n const match = stackLine.match(\n /\\s+at\\s+(?<functionName>.*?)\\s+\\((?:file:\\/\\/)?(?<absPath>.+?):(?<lineno>\\d+):(?<colno>\\d+)\\)/,\n );\n\n if (!match || !match.groups) {\n // We didn't match a stack line, so skip it. This could cause some stack\n // lines to be dropped.\n continue;\n }\n\n const rawAbsPath = match.groups.absPath ?? '';\n\n const absPath = rawAbsPath.startsWith('node:')\n ? rawAbsPath\n : path.relative(cwd, rawAbsPath);\n const filename = rawAbsPath.startsWith('node:')\n ? rawAbsPath\n : path.basename(rawAbsPath);\n\n const functionName = match.groups.functionName ?? '';\n\n const lineno = match.groups.lineno\n ? Number.parseInt(match.groups.lineno, 10)\n : undefined;\n\n // Read context lines from the source file (only for package files)\n const context =\n rawAbsPath && lineno ? await readContextLines(rawAbsPath, lineno) : {};\n\n // https://develop.sentry.dev/sdk/data-model/event-payloads/stacktrace/#frame-attributes\n const frame: SentryFrame = {\n function: functionName.slice(0, MAX_FUNCTION_NAME_LENGTH),\n raw_function: functionName,\n\n abs_path: absPath,\n filename,\n\n lineno,\n\n colno: match.groups.colno\n ? Number.parseInt(match.groups.colno, 10)\n : undefined,\n\n ...context,\n };\n\n frames.push(frame);\n }\n\n // Sentry expects most recent frame last\n return frames.toReversed();\n}\n\nfunction isTestEnv(\n env: Record<string, string | undefined> = process.env,\n): boolean {\n return env.NODE_ENV === 'test' || Boolean(env.JEST_WORKER_ID);\n}\n\n/**\n * Create a reporter with rate limiting\n */\nexport function createReporter(opts: ReporterOptions = {}): Reporter {\n if (isTestEnv()) {\n return {\n async captureException() {\n // Never emit telemetry during tests.\n },\n };\n }\n\n const maxPerMinute = Math.max(1, opts.maxPerMinute ?? 10);\n let sentThisMinute = 0;\n let minuteTick = Date.now();\n\n function isRateLimitExceeded(): boolean {\n const now = Date.now();\n\n if (now - minuteTick >= 60_000) {\n minuteTick = now;\n sentThisMinute = 0;\n }\n\n if (sentThisMinute >= maxPerMinute) {\n return true;\n }\n\n sentThisMinute++;\n\n return false;\n }\n\n const ci = detectCI(process.env);\n const nodeVersion = process.version;\n const platform = process.platform;\n\n return {\n async captureException(e: unknown) {\n if (isRateLimitExceeded()) {\n return;\n }\n\n const err = e instanceof Error ? e : new Error(String(e));\n const message = err.message ?? 'Error';\n const stack = err.stack;\n\n const payload: ErrorPayload = {\n pkg,\n env: opts.env ?? process.env.NODE_ENV ?? 'unknown',\n ci,\n nodeVersion,\n platform,\n\n error: {\n name: err.name || 'Error',\n message,\n stack: stack ?? '',\n },\n };\n\n await sendToSentry(payload);\n },\n };\n}\n", "#!/usr/bin/env node\n\nimport { main } from './index.ts';\n\nawait main();\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'node:path';\nimport { parseArgs } from 'node:util';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport { findConfigFile, loadConfigFile } from '../config/loadConfig.ts';\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport resolveEnvironment from '../environment/index.ts';\nimport { validateOnly } from '../isomorphic/parseOnly.ts';\nimport { validateSkip } from '../isomorphic/parseSkip.ts';\nimport type { Logger, OnlyItem, SkipItem } from '../isomorphic/types.ts';\nimport type { ParsedCLIArgs } from './parseOptions.ts';\nimport { parseOptions } from './parseOptions.ts';\nimport type { Reporter } from './telemetry.ts';\nimport { createReporter } from './telemetry.ts';\n\nasync function getVersion() {\n const packageJson = await import('../../package.json', {\n with: { type: 'json' },\n });\n return packageJson.default.version;\n}\n\nfunction parseDashdashCommandParts(\n rawArgs: Array<string>,\n): Array<string> | undefined {\n const dashdashIndex = rawArgs.indexOf('--');\n if (dashdashIndex === -1) {\n return undefined;\n }\n return rawArgs.slice(dashdashIndex + 1);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const n = b.length;\n const row = Array.from({ length: n + 1 }, (_, j) => j);\n\n for (let i = 1; i <= a.length; i++) {\n let prev = row[0]!;\n row[0] = i;\n for (let j = 1; j <= n; j++) {\n const temp = row[j]!;\n row[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, temp, row[j - 1]!);\n prev = temp;\n }\n }\n\n return row[n]!;\n}\n\nfunction findClosestOption(\n unknownName: string,\n knownNames: ReadonlyArray<string>,\n): string | undefined {\n let bestMatch: string | undefined;\n let bestDistance = Infinity;\n\n for (const known of knownNames) {\n const distance = levenshtein(unknownName, known);\n const threshold = Math.floor(Math.max(unknownName.length, known.length) / 3);\n if (distance <= threshold && distance < bestDistance) {\n bestDistance = distance;\n bestMatch = known;\n }\n }\n\n return bestMatch;\n}\n\nfunction parseRawArgs(rawArgs: Array<string>) {\n try {\n const parsedArgs = parseArgs({\n args: rawArgs,\n options: parseOptions,\n allowPositionals: true,\n });\n\n return {\n ...parsedArgs,\n dashdashCommandParts: parseDashdashCommandParts(rawArgs),\n };\n } catch (error) {\n if (\n error instanceof Error &&\n 'code' in error &&\n error.code === 'ERR_PARSE_ARGS_UNKNOWN_OPTION'\n ) {\n const match = error.message.match(/^Unknown option '(--[^']+)'/);\n\n if (match && match[1]) {\n const unknownOption = match[1];\n const suggestion = findClosestOption(\n unknownOption.slice(2),\n Object.keys(parseOptions),\n );\n\n if (suggestion !== undefined) {\n throw new TypeError(\n `Unknown option: '${unknownOption}'. Did you mean '--${suggestion}'?`,\n { cause: error },\n );\n }\n }\n }\n throw error;\n }\n}\n\nconst helpText = `Happo ${await getVersion()}\nUsage: happo [options]\n\nCommands:\n <default> Run happo tests\n finalize Finalize happo report for Cypress/Playwright tests running in parallel\n flake List reported flakes for a project\n\nOptions:\n --config Path to happo config file\n --version Show version number\n --help Show help text\n --baseBranch <branch> Base branch to use for comparison (default: 'origin/main')\n --link <url> URL to contextualize the comparison (default: auto-detected from CI environment)\n --message <message> Message to associate with the comparison (default: auto-detected from CI environment)\n --authorEmail <email> Email address of the author of the comparison (default: auto-detected from CI environment)\n --afterSha <sha> \"After\" SHA to use for comparison (default: auto-detected from CI environment, or HEAD SHA if not set)\n --beforeSha <sha> \"Before\" SHA to use for comparison (default: auto-detected from CI environment)\n --beforeShaTagMatcher <matcher> git tag matcher to use for \"before\" SHA resolution\n --fallbackShas <shas> Space-, newline- or comma-separated list of fallback shas for compare calls (default: auto-detected from CI environment)\n --fallbackShasCount <count> Number of fallback shas to use for compare calls (default: 50)\n --notify <emails> One or more (comma-separated) email addresses to notify with results\n --nonce <nonce> Nonce to use for Cypress/Playwright comparison\n --githubToken <token> GitHub token to use for posting Happo statuses as comments. Use in combination with the \\`githubApiUrl\\` configuration option. (default: auto-detected from environment)\n --skip <json> JSON array of {component, variant} objects to skip in this run and borrow from the nearest baseline report instead\n --only <json> JSON array of {component} or {storyFile} objects to include in this run (all other stories are skipped); only supported for the Storybook integration\n\nFinalize command options:\n --skippedExamples <json> JSON array of {component, variant, target} objects to skip when finalizing; borrowed from the nearest baseline report\n\nFlake command options:\n --allProjects List flakes across all projects (default: current project)\n --format <format> Output format for flake command (default: \"human\", use \"json\" for raw output)\n --project <name> Project to filter flakes for (default: project from config)\n --limit <number> Limit flake results (default: 100, max: 1000)\n --page <number> Page number for flakes (default: 1)\n --component <name> Filter flakes by component name\n --variant <name> Filter flakes by variant name\n --target <name> Filter flakes by target name\n --sha <sha> Filter flakes by before/after sha\n\nExamples:\n happo\n\n happo --config path/to/happo.config.ts\n happo --baseBranch origin/long-lived-branch\n happo --link https://github.com/happo/happo/pull/123\n happo --message \"Add new feature\"\n happo --notify me@example.com,you@example.com\n happo --nonce my-unique-nonce\n happo --githubToken {{ secrets.GITHUB_TOKEN }}\n\n happo --version\n happo --help\n\n happo -- playwright test\n\n happo --skip '[{\"component\":\"Button\",\"variant\":\"Primary\"}]'\n happo --only '[{\"component\":\"Button\"},{\"storyFile\":\"./src/Input.stories.tsx\"}]'\n\n happo finalize\n happo finalize --nonce my-unique-nonce\n happo finalize --skippedExamples '[{\"component\":\"Button\",\"variant\":\"primary\",\"target\":\"chrome\"}]'\n\n happo flake\n happo flake --allProjects\n happo flake --format=json\n happo flake --project=test-project --limit=10 --page=2\n happo flake --component=button --variant=primary --target=chrome\n happo flake --sha=ff2df74c1730341240840010c7518b2c1f4b55cb\n `;\n\nfunction makeAbsolute(configFilePath: string): string {\n if (configFilePath.startsWith('.')) {\n return path.resolve(process.cwd(), configFilePath);\n }\n return configFilePath;\n}\n\nfunction installErrorHandlers(reporter: Reporter, logger: Logger) {\n const unhandledRejectionHandler: NodeJS.UnhandledRejectionListener = (reason) => {\n if (reason instanceof Error) {\n reporter.captureException(reason);\n logger.error(reason.stack || reason.message || String(reason));\n } else {\n reporter.captureException(reason);\n logger.error(`Unhandled rejection (non-Error value): ${String(reason)}`);\n }\n\n process.exitCode = 1;\n return;\n };\n\n const uncaughtExceptionHandler: NodeJS.UncaughtExceptionListener = (error) => {\n reporter.captureException(error);\n logger.error(error.stack || error.message || String(error));\n process.exitCode = 1;\n };\n\n process.on('unhandledRejection', unhandledRejectionHandler);\n process.on('uncaughtException', uncaughtExceptionHandler);\n\n return () => {\n process.removeListener('unhandledRejection', unhandledRejectionHandler);\n process.removeListener('uncaughtException', uncaughtExceptionHandler);\n };\n}\n\nexport async function main(\n rawArgs: Array<string> = process.argv,\n logger: Logger = console,\n): Promise<void> {\n const reporter = createReporter();\n const uninstallErrorHandlers = installErrorHandlers(reporter, logger);\n\n try {\n const args = parseRawArgs(rawArgs.slice(2));\n\n if (args.values.version) {\n // --version\n logger.log(await getVersion());\n return;\n }\n\n if (args.values.help) {\n // --help\n logger.log(helpText);\n return;\n }\n\n const environment = await resolveEnvironment(args.values);\n\n // Get config file path (use --config if provided, otherwise find default)\n const configFilePath = makeAbsolute(args.values.config || findConfigFile());\n const config = await loadConfigFile(configFilePath, environment, logger);\n\n if (args.values.project !== undefined) {\n config.project = args.values.project;\n }\n\n // Handle positional arguments (commands)\n const command = args.positionals[0];\n\n if (args.dashdashCommandParts) {\n let validatedSkipJSON: string | undefined;\n if (environment.skip) {\n try {\n validateSkip(environment.skip);\n } catch (e) {\n logger.error(\n '[HAPPO] Invalid --skip:',\n e instanceof Error ? e.message : String(e),\n );\n process.exitCode = 1;\n return;\n }\n validatedSkipJSON = environment.skip;\n }\n await handleE2ECommand(\n config,\n environment,\n args.dashdashCommandParts,\n configFilePath,\n logger,\n validatedSkipJSON,\n );\n return;\n }\n\n if (command === 'finalize') {\n const finalizeEnvironment = args.values.skippedExamples\n ? { ...environment, skip: args.values.skippedExamples }\n : environment;\n await handleFinalizeCommand(config, finalizeEnvironment, logger);\n return;\n }\n\n if (command === 'flake') {\n const flakeOptions: FlakeCommandOptions = {};\n if (args.values.allProjects !== undefined) {\n flakeOptions.allProjects = args.values.allProjects;\n }\n if (args.values.format !== undefined) {\n flakeOptions.format = args.values.format;\n }\n if (args.values.project !== undefined) {\n flakeOptions.project = args.values.project;\n }\n if (args.values.limit !== undefined) {\n flakeOptions.limit = args.values.limit;\n }\n if (args.values.page !== undefined) {\n flakeOptions.page = args.values.page;\n }\n if (args.values.component !== undefined) {\n flakeOptions.component = args.values.component;\n }\n if (args.values.variant !== undefined) {\n flakeOptions.variant = args.values.variant;\n }\n if (args.values.target !== undefined) {\n flakeOptions.target = args.values.target;\n }\n if (args.values.sha !== undefined) {\n flakeOptions.sha = args.values.sha;\n }\n await handleFlakeCommand(config, flakeOptions, logger);\n return;\n }\n\n if (command === undefined) {\n await handleDefaultCommand(config, environment, logger);\n return;\n }\n\n logger.error(`Unknown command: ${command}\\n`);\n logger.error(helpText);\n process.exitCode = 1;\n } catch (error) {\n await reporter.captureException(error);\n logger.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n } finally {\n uninstallErrorHandlers();\n }\n}\n\nasync function handleDefaultCommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n logger: Logger,\n): Promise<void> {\n logger.log('Running happo tests...');\n\n const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] =\n await Promise.all([\n (await import('../network/startJob.ts')).default,\n (await import('../network/createAsyncComparison.ts')).default,\n (await import('../network/createAsyncReport.ts')).default,\n (await import('../network/prepareSnapRequests.ts')).default,\n ]);\n\n // Tell Happo that we are about to run a job\n await startJob(config, environment, logger);\n\n try {\n // When --skip is set, first resolve the baseline SHA. If no\n // baseline is found we fall back to a full run (no skipping).\n let skip: Array<SkipItem> | undefined;\n let baselineSha: string | undefined;\n\n if (environment.skip) {\n const supportedTypes = ['storybook', 'custom'];\n if (!supportedTypes.includes(config.integration.type)) {\n logger.error(\n `[HAPPO] --skip is not supported for integration type '${config.integration.type}'. Supported types: ${supportedTypes.join(', ')}`,\n );\n process.exitCode = 1;\n return;\n }\n\n try {\n skip = validateSkip(environment.skip);\n } catch (e) {\n logger.error(\n '[HAPPO] Invalid --skip:',\n e instanceof Error ? e.message : String(e),\n );\n process.exitCode = 1;\n return;\n }\n\n if (\n config.integration.type !== 'storybook' &&\n skip.some((item) => 'storyFile' in item)\n ) {\n logger.error(\n `[HAPPO] storyFile items in --skip are only supported for the storybook integration (current integration: '${config.integration.type}')`,\n );\n process.exitCode = 1;\n return;\n }\n\n const findBaselineReport = (\n await import('../network/findBaselineReport.ts')\n ).default;\n baselineSha = await findBaselineReport(environment, config, logger);\n if (!baselineSha) {\n logger.log(\n '[HAPPO] No baseline report found for --skip run. Generating a full report instead.',\n );\n skip = undefined;\n }\n }\n\n // When --only is set, validate and apply it (storybook only).\n let only: Array<OnlyItem> | undefined;\n\n if (environment.only) {\n if (config.integration.type !== 'storybook') {\n logger.error(\n `[HAPPO] --only is not supported for integration type '${config.integration.type}'. Supported types: storybook`,\n );\n process.exitCode = 1;\n return;\n }\n\n try {\n only = validateOnly(environment.only);\n } catch (e) {\n logger.error(\n '[HAPPO] Invalid --only:',\n e instanceof Error ? e.message : String(e),\n );\n process.exitCode = 1;\n return;\n }\n\n // Find a baseline to borrow the excluded stories from, unless --skip\n // already resolved one.\n if (!baselineSha) {\n const findBaselineReport = (\n await import('../network/findBaselineReport.ts')\n ).default;\n baselineSha = await findBaselineReport(environment, config, logger);\n if (!baselineSha) {\n logger.log(\n '[HAPPO] No baseline report found for --only run. Excluded stories will not be borrowed from a baseline.',\n );\n }\n }\n }\n\n // Prepare the snap requests for the job. This includes bundling static\n // assets and uploading them. Only pass the skip list when we have a\n // baseline to borrow the skipped examples from.\n const { snapRequestIds, resolvedSkip } = await prepareSnapRequests(config, skip, only);\n\n let allSnapRequestIds = snapRequestIds;\n\n if (skip && baselineSha) {\n const createExtendsReportSnapRequest = (\n await import('../network/createExtendsReportSnapRequest.ts')\n ).default;\n // Use storybook-resolved skip (storyFile items expanded to component names)\n // if available, otherwise fall back to the raw skip list.\n const extendsRequestId = await createExtendsReportSnapRequest(\n baselineSha,\n resolvedSkip ?? skip,\n config,\n );\n allSnapRequestIds = [...snapRequestIds, extendsRequestId];\n } else if (only && baselineSha && resolvedSkip && resolvedSkip.length > 0) {\n const createExtendsReportSnapRequest = (\n await import('../network/createExtendsReportSnapRequest.ts')\n ).default;\n // resolvedSkip here is the complement of the only list \u2014 all components\n // that were excluded and should be borrowed from the baseline.\n const extendsRequestId = await createExtendsReportSnapRequest(\n baselineSha,\n resolvedSkip,\n config,\n );\n allSnapRequestIds = [...snapRequestIds, extendsRequestId];\n }\n\n // Put together a report from the snap requests.\n const asyncReport = await createAsyncReport(\n allSnapRequestIds,\n config,\n environment,\n logger,\n );\n\n // Create an async comparison.\n logger.log(`[HAPPO] Async report URL: ${asyncReport.url}`);\n if (environment.beforeSha !== environment.afterSha) {\n const asyncComparison = await createAsyncComparison(\n config,\n environment,\n logger,\n );\n logger.log(`[HAPPO] Async comparison URL: ${asyncComparison.compareUrl}`);\n\n if (environment.link && environment.githubToken && config.githubApiUrl) {\n // githubToken and githubApiUrl are set which means that we should post\n // a comment to the PR.\n // https://docs.happo.io/docs/continuous-integration#posting-statuses-without-installing-the-happo-github-app\n const postGitHubComment = (await import('../network/postGitHubComment.ts'))\n .default;\n await postGitHubComment({\n authToken: environment.githubToken,\n link: environment.link,\n statusImageUrl: asyncComparison.statusImageUrl,\n compareUrl: asyncComparison.compareUrl,\n githubApiUrl: config.githubApiUrl,\n });\n }\n }\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n logger.error(`${config.integration.type} run failed: ${message}`, e);\n const cancelJob = (await import('../network/cancelJob.ts')).default;\n await cancelJob('failure', message, config, environment, logger);\n process.exitCode = 1;\n return;\n }\n}\n\nasync function handleFinalizeCommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n logger: Logger,\n): Promise<void> {\n logger.log('Finalizing happo report...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n\n try {\n const finalizeAll = (await import('../e2e/wrapper.ts')).finalizeAll;\n await finalizeAll({ happoConfig: config, environment, logger });\n } catch (e) {\n logger.error(e instanceof Error ? e.message : String(e), e);\n process.exitCode = 1;\n return;\n }\n process.exitCode = 0;\n return;\n}\n\ntype FlakeCommandOptions = Pick<\n ParsedCLIArgs,\n | 'allProjects'\n | 'format'\n | 'project'\n | 'limit'\n | 'page'\n | 'component'\n | 'variant'\n | 'target'\n | 'sha'\n>;\n\nasync function handleFlakeCommand(\n config: ConfigWithDefaults,\n {\n allProjects,\n format,\n project: projectOverride,\n limit,\n page,\n component,\n variant,\n target,\n sha,\n }: FlakeCommandOptions,\n logger: Logger,\n): Promise<void> {\n if (format && format !== 'json' && format !== 'human') {\n logger.error(\n `Unsupported format: ${format}. Use --format=json for raw JSON output or --format=human for human-readable output.`,\n );\n process.exitCode = 1;\n return;\n }\n\n const { default: getFlakes, formatFlakeOutput } =\n await import('../network/getFlakes.ts');\n const project = allProjects ? undefined : (projectOverride ?? config.project);\n const flakes = await getFlakes(\n {\n project,\n limit,\n page,\n component,\n variant,\n target,\n sha,\n },\n config,\n logger,\n );\n\n if (format === 'json') {\n logger.log(JSON.stringify(flakes, null, 2));\n process.exitCode = 0;\n return;\n }\n\n logger.log(formatFlakeOutput(flakes));\n process.exitCode = 0;\n}\n\nconst E2E_INTEGRATION_TYPES = ['cypress', 'playwright'];\n\nasync function handleE2ECommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n dashdashCommandParts: Array<string>,\n configFilePath: string,\n logger: Logger,\n skipJSON?: string,\n): Promise<void> {\n if (!E2E_INTEGRATION_TYPES.includes(config.integration.type)) {\n logger.error(\n `Unsupported integration type used for e2e command: ${config.integration.type}. Supported integration types for e2e are: ${E2E_INTEGRATION_TYPES.join(', ')}`,\n );\n process.exitCode = 1;\n return;\n }\n\n if (!dashdashCommandParts || dashdashCommandParts.length === 0) {\n logger.error('Missing command for e2e action');\n logger.error(helpText);\n process.exitCode = 1;\n return;\n }\n\n logger.log('Setting up happo wrapper for Cypress and Playwright...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n logger.log('Dashdash command parts:', dashdashCommandParts);\n\n const runWithWrapper = (await import('../e2e/wrapper.ts')).default;\n const exitCode = await runWithWrapper(\n dashdashCommandParts,\n config,\n environment,\n logger,\n configFilePath,\n skipJSON,\n );\n process.exitCode = exitCode;\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { any as findAny } from 'empathic/find';\n\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport type { Logger } from '../isomorphic/types.ts';\nimport fetchWithRetry from '../network/fetchWithRetry.ts';\nimport getShortLivedAPIToken from './getShortLivedAPIToken.ts';\nimport type {\n ConfigWithDefaults,\n DeepCompareSettings,\n TargetWithDefaults,\n} from './index.ts';\n\nconst CONFIG_FILENAMES = [\n 'happo.config.js',\n 'happo.config.mjs',\n 'happo.config.cjs',\n 'happo.config.ts',\n 'happo.config.mts',\n 'happo.config.cts',\n];\n\nconst DEFAULT_ENDPOINT = 'https://happo.io';\n\nexport function findConfigFile(): string {\n if (process.env.HAPPO_CONFIG_FILE) {\n return process.env.HAPPO_CONFIG_FILE;\n }\n\n const configFilePath = findAny(CONFIG_FILENAMES, { cwd: process.cwd() });\n\n if (!configFilePath) {\n throw new Error(\n 'Happo config file could not be found. Please create a config file in the root of your project.',\n );\n }\n\n return configFilePath;\n}\n\nfunction assertIsPullRequestTokenResponse(\n response: unknown,\n): asserts response is { secret: string } {\n if (typeof response !== 'object' || response === null || !('secret' in response)) {\n throw new TypeError('Unexpected pull request token response');\n }\n}\n\nasync function getPullRequestSecret(\n endpoint: string,\n prUrl: string,\n logger: Logger,\n): Promise<string> {\n const url = new URL('/api/pull-request-token', endpoint);\n const res = await fetchWithRetry(\n url,\n {\n method: 'POST',\n body: { prUrl },\n retryCount: 3,\n },\n logger,\n );\n\n if (!res || !res.ok) {\n throw new Error(\n `Failed to get pull request secret: ${res.status} - ${await res.text()}`,\n );\n }\n\n const json = await res.json();\n assertIsPullRequestTokenResponse(json);\n\n return json.secret;\n}\n\nasync function getFallbackApiToken(\n endpoint: string,\n environment: Pick<EnvironmentResult, 'link' | 'ci'> | undefined,\n logger: Logger,\n): Promise<{ key: string; secret: string } | undefined> {\n if (environment?.link) {\n try {\n // Fetch pull request auth\n const pullRequestSecret = await getPullRequestSecret(\n endpoint,\n environment.link,\n logger,\n );\n return {\n key: environment.link,\n secret: pullRequestSecret,\n };\n } catch {\n logger.log(\n `Failed to obtain temporary pull-request token for URL: ${environment.link}`,\n );\n }\n }\n\n if (!environment?.ci) {\n const shortLivedApiToken = await getShortLivedAPIToken(endpoint, logger);\n return shortLivedApiToken ?? undefined;\n }\n return undefined;\n}\n\nfunction validateDeepCompareSettings(\n deepCompare: DeepCompareSettings,\n configFilePath: string,\n): asserts deepCompare is DeepCompareSettings {\n if (typeof deepCompare !== 'object' || Array.isArray(deepCompare)) {\n throw new TypeError(\n `Invalid \\`deepCompare\\` in config file ${configFilePath}: must be an object, got: ${Array.isArray(deepCompare) ? 'array' : typeof deepCompare}.`,\n );\n }\n\n const settings = deepCompare as DeepCompareSettings;\n\n if (!('compareThreshold' in settings) || settings.compareThreshold === undefined) {\n throw new TypeError(\n `Invalid \\`deepCompare\\` in config file ${configFilePath}: \\`compareThreshold\\` is required.`,\n );\n }\n\n if (\n typeof settings.compareThreshold !== 'number' ||\n settings.compareThreshold < 0 ||\n settings.compareThreshold > 1\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.compareThreshold\\` in config file ${configFilePath}: must be a number between 0 and 1, got: ${JSON.stringify(settings.compareThreshold)}.`,\n );\n }\n\n if (\n 'diffAlgorithm' in settings &&\n settings.diffAlgorithm !== undefined &&\n (typeof settings.diffAlgorithm !== 'string' ||\n (settings.diffAlgorithm !== 'color-delta' &&\n settings.diffAlgorithm !== 'ssim'))\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.diffAlgorithm\\` in config file ${configFilePath}: must be \"color-delta\" or \"ssim\", got: ${JSON.stringify(settings.diffAlgorithm)}.`,\n );\n }\n\n if (\n 'ignoreThreshold' in settings &&\n settings.ignoreThreshold !== undefined &&\n (typeof settings.ignoreThreshold !== 'number' ||\n settings.ignoreThreshold < 0 ||\n settings.ignoreThreshold > 1)\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.ignoreThreshold\\` in config file ${configFilePath}: must be a number between 0 and 1, got: ${JSON.stringify(settings.ignoreThreshold)}.`,\n );\n }\n\n if (\n 'ignoreWhitespace' in settings &&\n settings.ignoreWhitespace !== undefined &&\n typeof settings.ignoreWhitespace !== 'boolean'\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.ignoreWhitespace\\` in config file ${configFilePath}: must be a boolean, got: ${JSON.stringify(settings.ignoreWhitespace)}.`,\n );\n }\n\n if (\n 'applyBlur' in settings &&\n settings.applyBlur !== undefined &&\n typeof settings.applyBlur !== 'boolean'\n ) {\n throw new TypeError(\n `Invalid \\`deepCompare.applyBlur\\` in config file ${configFilePath}: must be a boolean, got: ${JSON.stringify(settings.applyBlur)}.`,\n );\n }\n}\n\nexport async function loadConfigFile(\n configFilePath: string,\n environment?: Pick<EnvironmentResult, 'link' | 'ci'>,\n logger: Logger = console,\n): Promise<ConfigWithDefaults> {\n try {\n const stats = await fs.promises.stat(configFilePath);\n if (!stats.isFile()) {\n throw new Error(`Happo config file path is not a file: ${configFilePath}`);\n }\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n throw new Error(`Happo config file could not be found: ${configFilePath}`, {\n cause: error,\n });\n }\n\n throw error;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: change this to unknown and add type assertions\n let config: any;\n try {\n config = (await import(pathToFileURL(configFilePath).href)).default;\n } catch (error) {\n if (\n error instanceof Error &&\n 'code' in error &&\n error.code === 'ERR_UNKNOWN_FILE_EXTENSION'\n ) {\n // Older versions of Node don't support .ts files natively, so let's throw\n // a more helpful error message.\n const extension = path.extname(configFilePath);\n throw new TypeError(\n `Your Happo config file ${configFilePath} is using an extension that is not supported by this version of Node.js (${extension}). Please use a newer version of Node.js (22.18.0+, 23.6.0+, or 24+).`,\n { cause: error },\n );\n }\n\n throw error;\n }\n\n if (config === null) {\n throw new TypeError(\n `Your Happo config file ${configFilePath} must have a default export that is an object, got: null.`,\n );\n }\n\n if (typeof config !== 'object') {\n throw new TypeError(\n `Your Happo config file ${configFilePath} must have a default export that is an object, got: ${typeof config}.`,\n );\n }\n\n if (Array.isArray(config)) {\n throw new TypeError(\n `Your Happo config file ${configFilePath} must have a default export that is an object, got: array.`,\n );\n }\n\n // We read these in here so that they can be passed along to the child process\n // in e2e/wrapper.ts. This allows us to use pull-request authentication\n // without having to make an additional HTTP request.\n if (!config.apiKey && process.env.HAPPO_API_KEY) {\n config.apiKey = process.env.HAPPO_API_KEY;\n }\n if (!config.apiSecret && process.env.HAPPO_API_SECRET) {\n config.apiSecret = process.env.HAPPO_API_SECRET;\n }\n\n if (!config.apiKey || !config.apiSecret) {\n const missing = [\n config.apiKey ? null : 'apiKey',\n config.apiSecret ? null : 'apiSecret',\n ]\n .filter(Boolean)\n .map((key) => `\\`${key}\\``)\n .join(' and ');\n\n logger.log(\n `Missing ${missing} in Happo config. Attempting alternative authentication.`,\n );\n const fallbackApiToken = await getFallbackApiToken(\n config.endpoint || DEFAULT_ENDPOINT,\n environment,\n logger,\n );\n if (!fallbackApiToken) {\n throw new Error(\n `Missing ${missing} in your Happo config. Reference yours at https://happo.io/settings`,\n );\n }\n config.apiKey = fallbackApiToken.key;\n config.apiSecret = fallbackApiToken.secret;\n }\n\n if (!config.targets) {\n config.targets = {\n chrome: {\n type: 'chrome',\n viewport: '1024x768',\n },\n };\n }\n\n if (!config.integration) {\n config.integration = {\n type: 'storybook',\n };\n }\n\n const allTargets = Object.values(config.targets);\n for (const target of allTargets as Array<TargetWithDefaults>) {\n target.viewport = target.viewport || '1024x768';\n target.freezeAnimations = target.freezeAnimations || 'last-frame';\n target.prefersReducedMotion = target.prefersReducedMotion ?? true;\n target.allowPointerEvents = target.allowPointerEvents ?? true;\n }\n\n // Validate deepCompare settings if present\n if (config.deepCompare !== undefined && config.deepCompare !== null) {\n validateDeepCompareSettings(config.deepCompare, configFilePath);\n // Set default diffAlgorithm if not provided\n if (!config.deepCompare.diffAlgorithm) {\n config.deepCompare.diffAlgorithm = 'color-delta';\n }\n }\n\n const configWithDefaults = {\n endpoint: DEFAULT_ENDPOINT,\n githubApiUrl: 'https://api.github.com',\n targets: allTargets,\n ...config,\n };\n\n return configWithDefaults;\n}\n", "import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport default function openBrowser(url: string): Promise<void> {\n const platform = process.platform;\n let command: string;\n\n if (platform === 'darwin') {\n command = `open \"${url}\"`;\n } else if (platform === 'win32') {\n command = `start \"\" \"${url}\"`;\n } else {\n // Linux and others\n command = `xdg-open \"${url}\"`;\n }\n\n return execAsync(command).then(() => {\n // Ignore errors - browser might not open, but that's okay\n });\n}\n", "import { createInterface } from 'node:readline';\n\nexport default function promptUser(message: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(message, (answer) => {\n rl.close();\n // Only proceed if Enter was pressed (empty string or newline)\n if (answer.trim() === '') {\n resolve();\n } else {\n reject(new Error('User cancelled authentication'));\n }\n });\n });\n}\n", "import type { Logger } from '../isomorphic/types.ts';\nimport startServer from '../network/startServer.ts';\nimport openBrowser from './openBrowser.ts';\nimport promptUser from './promptUser.ts';\n\nconst VALID_HEX_REGEX = /^[0-9a-fA-F]+$/;\n\nfunction createHTML(endpoint: string, phase: string): string {\n return `<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <title>Happo CLI Authentication</title>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script type=\"text/javascript\">\n const message = { type: 'happo-cli-auth', payload: { phase: '${phase}' } };\n // Use the exact origin of the parent page\n window.parent.postMessage(message, '${endpoint}'); \n </script>\n </head>\n <body>\n <main>\n <h1>Happo CLI Authentication</h1> \n <p>Authentication successful!</p>\n </main>\n </body>\n </html>`;\n}\n\nfunction validateKeyAndSecret(args: {\n key: string | null;\n secret: string | null;\n}): args is { key: string; secret: string } {\n const { key, secret } = args;\n if (!key) {\n return false;\n }\n if (!secret) {\n return false;\n }\n if (key.length < 10 || key.length > 64) {\n return false;\n }\n if (secret.length < 20 || secret.length > 256) {\n return false;\n }\n // validate that key and secret are valid hex strings\n if (!VALID_HEX_REGEX.test(key)) {\n return false;\n }\n if (!VALID_HEX_REGEX.test(secret)) {\n return false;\n }\n return true;\n}\n\nexport default async function getShortLivedAPIToken(\n endpoint: string,\n logger: Logger,\n): Promise<{ key: string; secret: string } | null> {\n if (!process.stdin.isTTY) {\n return null;\n }\n // Prompt user to press Enter only if in an interactive terminal\n await promptUser('Press <Enter> to authenticate in the browser');\n\n // Set up promise to wait for callback\n let resolveCallback: (value: { key: string; secret: string }) => void;\n let rejectCallback: (error: Error) => void;\n const callbackPromise = new Promise<{ key: string; secret: string }>(\n (resolve, reject) => {\n resolveCallback = resolve;\n rejectCallback = reject;\n },\n );\n\n // Start local server on auto port\n const serverInfo = await startServer((req, res) => {\n // Get port from the request socket\n const url = new URL(req.url ?? '', `http://localhost:${serverInfo.port}`);\n\n if (url.pathname === '/callback') {\n const token = {\n key: url.searchParams.get('key'),\n secret: url.searchParams.get('secret'),\n };\n const ping = url.searchParams.get('ping');\n\n if (ping) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(createHTML(endpoint, 'auth'));\n return;\n }\n if (validateKeyAndSecret(token)) {\n // Send success response\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(createHTML(endpoint, 'done'));\n\n // Resolve the promise with token and secret\n return resolveCallback(token);\n }\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end('Bad request');\n return rejectCallback(new Error('Missing key or secret in callback'));\n }\n\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n });\n\n const callbackUrl = `http://localhost:${serverInfo.port}/callback`;\n const authUrl = `${endpoint}/cli/auth?callbackUrl=${encodeURIComponent(callbackUrl)}`;\n\n try {\n // Open browser\n console.log(`Opening URL: ${authUrl}`);\n await openBrowser(authUrl);\n const result = await callbackPromise;\n return result;\n } catch (error) {\n logger.error(\n `Failed to authenticate: ${error instanceof Error ? error.message : String(error)}`,\n );\n return null;\n } finally {\n // Clean up server\n await serverInfo.close();\n }\n}\n", "import { spawnSync } from 'node:child_process';\nimport crypto, { randomBytes } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\n\nimport type { ParsedCLIArgs } from '../cli/parseOptions.ts';\n\nconst NUMBER_OF_COMMITS_TO_FETCH = 50;\nconst FULL_SHA_REGEX = /^[a-f0-9]{40}$/i;\n\ninterface GitHubEvent {\n pull_request?: {\n html_url: string;\n title: string;\n base: {\n sha: string;\n };\n head: {\n sha: string;\n };\n };\n head_commit?: {\n url: string;\n };\n merge_group?: {\n head_sha: string;\n base_sha: string;\n };\n repository?: {\n html_url: string;\n };\n before?: string;\n after?: string;\n}\n\nexport interface EnvironmentResult {\n link: string | undefined;\n message: string | undefined;\n authorEmail: string | undefined;\n beforeSha: string;\n afterSha: string;\n nonce: string | undefined;\n debugMode: boolean;\n notify: string | undefined;\n fallbackShas: Array<string> | undefined;\n githubToken: string | undefined;\n ci: boolean;\n skip: string | undefined;\n only: string | undefined;\n}\n\nconst envKeys: ReadonlyArray<string> = [\n 'BUILD_REPOSITORY_URI',\n 'BUILD_SOURCEVERSION',\n 'CIRCLE_PROJECT_REPONAME',\n 'CIRCLE_PROJECT_USERNAME',\n 'CIRCLE_SHA1',\n 'CI_PULL_REQUEST',\n 'GITHUB_EVENT_PATH',\n 'GITHUB_SERVER_URL',\n 'GITHUB_SHA',\n 'HAPPO_DEBUG',\n 'SYSTEM_PULLREQUEST_PULLREQUESTID',\n 'SYSTEM_PULLREQUEST_SOURCEBRANCH',\n 'SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI',\n 'SYSTEM_PULLREQUEST_TARGETBRANCH',\n 'TRAVIS_COMMIT',\n 'TRAVIS_COMMIT_RANGE',\n 'TRAVIS_PULL_REQUEST',\n 'TRAVIS_PULL_REQUEST_SHA',\n 'TRAVIS_REPO_SLUG',\n];\n\nasync function resolveGithubEvent(GITHUB_EVENT_PATH: string): Promise<GitHubEvent> {\n try {\n const fs = await import('node:fs/promises');\n const content = await fs.readFile(GITHUB_EVENT_PATH, 'utf8');\n return JSON.parse(content);\n } catch (e) {\n throw new Error(\n `Failed to load GitHub event from the GITHUB_EVENT_PATH environment variable: ${JSON.stringify(GITHUB_EVENT_PATH)}`,\n { cause: e },\n );\n }\n}\n\nasync function resolveLink(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n if (cliArgs.link) {\n // Validate the link\n let parsed: URL;\n try {\n parsed = new URL(cliArgs.link);\n } catch (e) {\n throw new TypeError(\n `link must be a valid http/https URL. Invalid URL: '${cliArgs.link}'`,\n { cause: e },\n );\n }\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new TypeError(\n `link must be a valid http/https URL. Invalid protocol: '${parsed.protocol}' (from '${cliArgs.link}')`,\n );\n }\n\n return cliArgs.link;\n }\n\n const {\n BUILD_REPOSITORY_URI,\n BUILD_SOURCEVERSION,\n\n // https://circleci.com/docs/reference/variables/\n CIRCLE_PROJECT_REPONAME,\n CIRCLE_PROJECT_USERNAME,\n CIRCLE_PULL_REQUEST,\n CIRCLE_SHA1,\n\n CI_PULL_REQUEST,\n\n // https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n\n SYSTEM_PULLREQUEST_PULLREQUESTID,\n SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI,\n\n // https://docs.travis-ci.com/user/environment-variables/#default-environment-variables\n TRAVIS_COMMIT,\n TRAVIS_PULL_REQUEST,\n TRAVIS_REPO_SLUG,\n } = env;\n\n if (CI_PULL_REQUEST) {\n // Circle CI\n return CI_PULL_REQUEST;\n }\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.html_url;\n }\n if (ghEvent.head_commit) {\n return ghEvent.head_commit.url;\n }\n if (ghEvent.merge_group && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${ghEvent.merge_group.head_sha}`;\n }\n if (GITHUB_SHA && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${GITHUB_SHA}`;\n }\n }\n\n if (SYSTEM_PULLREQUEST_PULLREQUESTID && SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI) {\n return `${SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI}/pullrequest/${SYSTEM_PULLREQUEST_PULLREQUESTID}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n if (BUILD_REPOSITORY_URI && BUILD_SOURCEVERSION) {\n return `${BUILD_REPOSITORY_URI}/commit/${BUILD_SOURCEVERSION}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n const githubBase = 'https://github.com';\n\n if (TRAVIS_REPO_SLUG && TRAVIS_PULL_REQUEST) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/pull/${TRAVIS_PULL_REQUEST}`;\n }\n\n if (TRAVIS_REPO_SLUG && TRAVIS_COMMIT) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/commit/${TRAVIS_COMMIT}`;\n }\n\n if (CIRCLE_PULL_REQUEST) {\n return CIRCLE_PULL_REQUEST;\n }\n\n if (CIRCLE_PROJECT_USERNAME && CIRCLE_PROJECT_REPONAME && CIRCLE_SHA1) {\n return `${githubBase}/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}`;\n }\n\n return undefined;\n}\n\nasync function resolveAuthorEmail(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n if (cliArgs.authorEmail) {\n return cliArgs.authorEmail;\n }\n\n const { GITHUB_EVENT_PATH } = env;\n\n if (GITHUB_EVENT_PATH) {\n // const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n // TODO: do something with the github event\n }\n\n const res = spawnSync('git', ['show', '-s', '--format=%ae'], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n return res.stdout.trim();\n}\n\nasync function resolveMessage(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n afterSha: string,\n): Promise<string | undefined> {\n if (cliArgs.message) {\n return cliArgs.message;\n }\n\n const { GITHUB_EVENT_PATH } = env;\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.title;\n }\n }\n\n const res = spawnSync('git', ['log', '-1', '--pretty=%s', afterSha], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n const message = res.stdout.split('\\n')[0];\n\n if (!message) {\n return undefined;\n }\n\n return message;\n}\n\nfunction resolveShaFromTagMatcher(tagMatcher: string): string | undefined {\n const res = spawnSync(\n 'git',\n ['tag', '--list', tagMatcher, '--sort', 'refname', '--no-contains'],\n {\n encoding: 'utf8',\n },\n );\n\n if (res.status !== 0) {\n throw new Error(\n `Failed to list git tags when matching against --beforeShaTagMatcher '${tagMatcher}'. Error: ${res.stderr}`,\n );\n }\n\n const rawAllTags = res.stdout.trim();\n if (!rawAllTags.length) {\n return undefined;\n }\n\n const allTags = rawAllTags.split('\\n');\n const tag = allTags.at(-1);\n\n if (!tag) {\n throw new Error('No tag found matching the pattern');\n }\n\n const commitRes = spawnSync('git', ['rev-list', '-n', '1', tag], {\n encoding: 'utf8',\n });\n\n if (commitRes.status !== 0) {\n throw new Error(\n `Failed to resolve commit sha from tag \"${tag}\". Error: ${res.stderr}`,\n );\n }\n\n return commitRes.stdout.trim();\n}\n\nfunction fetchMoreHistory(\n ref: string, // can be a full SHA or a ref/branch name\n numberOfCommitsToFetch: number,\n): boolean {\n const fetchRes = spawnSync(\n 'git',\n ['fetch', 'origin', ref, `--depth=${numberOfCommitsToFetch}`],\n {\n encoding: 'utf8',\n },\n );\n const success = fetchRes.status === 0;\n if (!success) {\n console.error(\n `[HAPPO] Failed to fetch more history (${numberOfCommitsToFetch} commits) for ${ref}. Error: ${fetchRes.stderr}`,\n );\n }\n return success;\n}\n\nfunction resolveMergeBase(\n baseRef: string, // can be a full SHA or a ref/branch name\n afterSha: string,\n debugMode: boolean,\n tryNumber: number = 1,\n): string | undefined {\n const res = spawnSync('git', ['merge-base', baseRef, afterSha], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n // In GitHub Actions, checkouts can be shallow and may not include the PR base\n // commit (or enough of its history) to compute a merge-base.\n //\n // - First attempt often fails with \"Not a valid commit name <sha>\".\n // - After fetching just the base commit, a subsequent attempt can still fail\n // with exit code 1 and empty stderr because history is still too shallow.\n //\n // When the base looks like a full SHA, we can try to fetch deeper history\n // and retry with increasing depth.\n if (FULL_SHA_REGEX.test(baseRef) && tryNumber <= 10) {\n if (debugMode) {\n console.error(\n `[HAPPO] When resolving the merge base between ${baseRef} and ${afterSha}, we failed to resolve the merge base. We'll try fetching more history (${tryNumber * NUMBER_OF_COMMITS_TO_FETCH} commits) and resolving the merge base again.`,\n );\n }\n if (fetchMoreHistory(baseRef, tryNumber * NUMBER_OF_COMMITS_TO_FETCH)) {\n return resolveMergeBase(baseRef, afterSha, debugMode, tryNumber + 1);\n }\n }\n console.error(\n `[HAPPO] Ignored error when resolving merge base between ${baseRef} and ${afterSha}: ${res.stderr}`,\n );\n return undefined;\n }\n\n const mergeBase = res.stdout.split('\\n')[0]?.trim();\n\n if (!mergeBase) {\n console.error(\n `[HAPPO] git merge-base stdout is empty when resolving merge base between ${baseRef} and ${afterSha}. stdout: ${res.stdout}\\nstderr: ${res.stderr}`,\n );\n return undefined;\n }\n\n return mergeBase;\n}\n\nasync function resolveBeforeSha(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n afterSha: string,\n debugMode: boolean,\n): Promise<string | undefined> {\n if (cliArgs.beforeSha) {\n return cliArgs.beforeSha;\n }\n\n if (cliArgs.beforeShaTagMatcher) {\n const resolvedSha = resolveShaFromTagMatcher(cliArgs.beforeShaTagMatcher);\n if (resolvedSha) {\n return resolvedSha;\n }\n }\n\n const { TRAVIS_COMMIT_RANGE, GITHUB_EVENT_PATH, SYSTEM_PULLREQUEST_TARGETBRANCH } =\n env;\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n\n if (ghEvent.pull_request) {\n const resolvedSha = resolveMergeBase(\n ghEvent.pull_request.base.sha,\n afterSha,\n debugMode,\n );\n\n if (resolvedSha) {\n return resolvedSha;\n } else {\n console.error(\n `[HAPPO] Failed to resolve merge base commit for GitHub event ${ghEvent.pull_request.base.sha} and ${afterSha}. Falling back to pull request base SHA.`,\n );\n return ghEvent.pull_request.base.sha;\n }\n }\n\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.base_sha;\n }\n\n return ghEvent.before;\n }\n\n if (TRAVIS_COMMIT_RANGE) {\n const [first] = TRAVIS_COMMIT_RANGE.split('...');\n return first;\n }\n\n let baseAzureBranch;\n if (SYSTEM_PULLREQUEST_TARGETBRANCH) {\n baseAzureBranch = [\n 'origin',\n SYSTEM_PULLREQUEST_TARGETBRANCH.split('/').toReversed()[0],\n ].join('/');\n }\n\n const baseBranch = cliArgs.baseBranch || baseAzureBranch || 'origin/main';\n return resolveMergeBase(baseBranch, afterSha, debugMode);\n}\n\nfunction getHeadShaWithLocalChanges(): {\n headSha: string;\n headShaWithLocalChanges: string;\n} {\n const randomSha = randomBytes(20).toString('hex');\n // Get the HEAD sha from the git repo, or if we have local changes, add them to the sha\n const res = spawnSync('git', ['rev-parse', 'HEAD'], {\n encoding: 'utf8',\n });\n if (res.status !== 0) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n const headSha = res.stdout.split('\\n')[0];\n if (!headSha) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n\n // Check for local changes\n const diffRes = spawnSync('git', ['diff', 'HEAD'], {\n encoding: 'utf8',\n });\n\n // If git diff fails, return HEAD sha\n if (diffRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const lsRes = spawnSync('git', ['ls-files', '--other', '--exclude-standard'], {\n encoding: 'utf8',\n });\n\n if (lsRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const localChanges = [diffRes.stdout.trim(), lsRes.stdout.trim()];\n\n // Get contents of untracked files\n const untrackedFiles = lsRes.stdout\n .trim()\n .split('\\n')\n .filter((file) => file.trim());\n\n for (const file of untrackedFiles) {\n try {\n const content = readFileSync(file, 'utf8');\n localChanges.push(content);\n } catch {\n // If we can't read the file, include just the filename\n localChanges.push(`${file}:<unreadable>`);\n }\n }\n\n const allChanges = localChanges.join('');\n\n if (!allChanges.trim()) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n // If there are local changes, create a hash that includes both HEAD and the changes\n const headShaWithLocalChanges = crypto\n .createHash('sha256')\n .update(headSha)\n .update(allChanges)\n .digest('hex')\n .slice(0, 40);\n\n return { headSha, headShaWithLocalChanges };\n}\n\nasync function resolveAfterSha(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined>,\n): Promise<string | { headSha: string; headShaWithLocalChanges: string }> {\n if (cliArgs.afterSha) {\n return cliArgs.afterSha;\n }\n\n const {\n CIRCLE_SHA1,\n TRAVIS_PULL_REQUEST_SHA,\n TRAVIS_COMMIT,\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n BUILD_SOURCEVERSION,\n SYSTEM_PULLREQUEST_SOURCEBRANCH,\n CI,\n } = env;\n\n const sha = CIRCLE_SHA1 || TRAVIS_PULL_REQUEST_SHA || TRAVIS_COMMIT;\n\n if (sha) {\n return sha;\n }\n\n if (SYSTEM_PULLREQUEST_SOURCEBRANCH) {\n // azure pull request\n const rawBranchName = SYSTEM_PULLREQUEST_SOURCEBRANCH.split('/').toReversed()[0];\n const res = spawnSync('git', ['rev-parse', `origin/${rawBranchName}`], {\n encoding: 'utf8',\n });\n if (res.status === 0 && res.stdout) {\n const sha = res.stdout.split('\\n')[0];\n if (sha) {\n return sha;\n }\n }\n }\n if (BUILD_SOURCEVERSION) {\n // azure master job\n return BUILD_SOURCEVERSION;\n }\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.head.sha;\n }\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.head_sha;\n }\n if (ghEvent.after) {\n return ghEvent.after;\n }\n if (GITHUB_SHA) {\n return GITHUB_SHA;\n }\n }\n const headShaWithLocalChanges = getHeadShaWithLocalChanges();\n if (CI) {\n return headShaWithLocalChanges.headSha;\n }\n return headShaWithLocalChanges;\n}\n\nfunction resolveFallbackShas(\n cliArgs: ParsedCLIArgs,\n beforeSha: string | undefined,\n): Array<string> | undefined {\n if (cliArgs.fallbackShas) {\n return cliArgs.fallbackShas.split(/[,\\s]+/).filter(Boolean);\n }\n\n const fallbackShasCount = cliArgs.fallbackShasCount\n ? Number.parseInt(cliArgs.fallbackShasCount, 10)\n : 50;\n\n if (Number.isNaN(fallbackShasCount)) {\n throw new TypeError(\n `fallbackShasCount must be a number. Invalid value: '${cliArgs.fallbackShasCount}'`,\n );\n }\n\n const res = spawnSync(\n 'git',\n [\n 'log',\n '--format=%H',\n '--first-parent',\n `--max-count=${fallbackShasCount}`,\n `${beforeSha}^`,\n ],\n {\n encoding: 'utf8',\n },\n );\n\n if (res.status !== 0) {\n return undefined;\n }\n\n return res.stdout.split('\\n').filter(Boolean);\n}\n\nfunction getRawEnv(\n env: Record<string, string | undefined>,\n): Record<string, string | undefined> {\n const res: Record<string, string | undefined> = {};\n for (const key of envKeys) {\n res[key] = env[key];\n }\n return res;\n}\n\nexport default async function resolveEnvironment(\n cliArgs: ParsedCLIArgs,\n env: Record<string, string | undefined> = process.env,\n): Promise<EnvironmentResult> {\n const debugMode = !!env.HAPPO_DEBUG;\n const afterSha = await resolveAfterSha(cliArgs, env);\n\n const realAfterSha = typeof afterSha === 'string' ? afterSha : afterSha.headSha;\n const afterShaWithLocalChanges =\n typeof afterSha === 'string' ? afterSha : afterSha.headShaWithLocalChanges;\n\n // Resolve the before SHA with the true HEAD SHA\n const [beforeSha, link, authorEmail, message] = await Promise.all([\n resolveBeforeSha(cliArgs, env, realAfterSha, debugMode),\n resolveLink(cliArgs, env),\n resolveAuthorEmail(cliArgs, env),\n\n // Resolve message with the SHA that includes local changes\n resolveMessage(cliArgs, env, afterShaWithLocalChanges),\n ]);\n\n const nonNullBeforeSha = beforeSha || afterShaWithLocalChanges;\n\n const result = {\n link,\n authorEmail,\n message,\n beforeSha: nonNullBeforeSha,\n afterSha: afterShaWithLocalChanges,\n nonce: cliArgs.nonce,\n debugMode,\n notify: cliArgs.notify,\n fallbackShas: resolveFallbackShas(cliArgs, nonNullBeforeSha),\n githubToken: cliArgs.githubToken,\n ci: !!env.CI,\n skip: cliArgs.skip,\n only: cliArgs.only,\n };\n\n if (debugMode) {\n console.log('[HAPPO] Raw environment', getRawEnv(env));\n console.log('[HAPPO] Resolved environment', result);\n }\n\n return result;\n}\n", "import type { OnlyItem } from './types.ts';\n\nfunction isOnlyItem(item: unknown): item is OnlyItem {\n if (typeof item !== 'object' || item === null) return false;\n const record = item as Record<string, unknown>;\n const hasComponent = typeof record['component'] === 'string';\n const hasStoryFile = typeof record['storyFile'] === 'string';\n if (hasComponent && hasStoryFile) return false;\n if (hasStoryFile) return record['variant'] === undefined;\n if (hasComponent) return record['variant'] === undefined;\n return false;\n}\n\n/**\n * Parses and validates a JSON string, returning an array of OnlyItems.\n * Throws a TypeError if the JSON is invalid or not an array of OnlyItems.\n *\n * Note: `variant` is not supported in `--only` items because variants cannot\n * be resolved statically from the Storybook built files.\n */\nexport function validateOnly(json: string): Array<OnlyItem> {\n const parsed: unknown = JSON.parse(json);\n if (!Array.isArray(parsed) || !parsed.every(isOnlyItem)) {\n throw new TypeError(\n '--only must be a JSON array of {component} or {storyFile} objects (variant is not supported)',\n );\n }\n return parsed;\n}\n\n/**\n * Parses a JSON string into an array of OnlyItems. Returns an empty array on\n * any parse error or if the value is not a valid array of OnlyItems.\n */\nexport function parseOnly(json?: string): Array<OnlyItem> {\n if (!json) return [];\n try {\n return validateOnly(json);\n } catch {\n return [];\n }\n}\n", "import { parseArgs } from 'node:util';\n\nexport const parseOptions = {\n version: {\n type: 'boolean',\n short: 'v',\n },\n\n help: {\n type: 'boolean',\n short: 'h',\n },\n\n config: {\n type: 'string',\n short: 'c',\n },\n\n baseBranch: {\n type: 'string',\n },\n\n link: {\n type: 'string',\n },\n\n message: {\n type: 'string',\n },\n\n authorEmail: {\n type: 'string',\n },\n\n afterSha: {\n type: 'string',\n },\n\n beforeSha: {\n type: 'string',\n },\n\n beforeShaTagMatcher: {\n type: 'string',\n },\n\n fallbackShas: {\n type: 'string',\n },\n\n fallbackShasCount: {\n type: 'string',\n },\n\n notify: {\n type: 'string',\n },\n\n nonce: {\n type: 'string',\n },\n\n githubToken: {\n type: 'string',\n },\n\n // Flake command options\n allProjects: {\n type: 'boolean',\n },\n\n format: {\n type: 'string',\n },\n\n project: {\n type: 'string',\n },\n\n limit: {\n type: 'string',\n },\n\n page: {\n type: 'string',\n },\n\n component: {\n type: 'string',\n },\n\n variant: {\n type: 'string',\n },\n\n target: {\n type: 'string',\n },\n\n sha: {\n type: 'string',\n },\n\n skip: {\n type: 'string',\n },\n\n skippedExamples: {\n type: 'string',\n },\n\n only: {\n type: 'string',\n },\n} as const;\n\nexport type ParsedCLIArgs = ReturnType<\n typeof parseArgs<{ options: typeof parseOptions; allowPositionals: true }>\n>['values'];\n", "import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { createInterface } from 'node:readline';\n\nimport { up as findPackage } from 'empathic/package';\n\nimport pkg from '../../package.json' with { type: 'json' };\n\n/**\n * Happo's PUBLIC DSN. Safe to ship.\n */\nconst SENTRY_DSN =\n 'https://3a495ff2101313edb024de73b005398f@o108341.ingest.us.sentry.io/4510341337645056';\n\nconst MAX_STACK_FRAMES = 50;\nconst MAX_FUNCTION_NAME_LENGTH = 120;\n\ntype CI =\n | 'github'\n | 'circleci'\n | 'travis'\n | 'azure'\n | 'buildkite'\n | 'jenkins'\n | 'gitlab'\n | 'bitbucket'\n | 'appveyor'\n | 'drone'\n | 'ci'\n | 'unknown';\n\ntype ErrorPayload = {\n pkg: {\n name: string;\n version: string;\n };\n\n error: {\n name: string;\n message: string;\n stack?: string;\n };\n\n env: string;\n\n /** Detected CI vendor if any */\n ci: CI;\n\n nodeVersion: string;\n platform: string;\n};\n\nexport type ReporterOptions = {\n maxPerMinute?: number; // default 10\n env?: string;\n};\n\nexport interface Reporter {\n captureException(e: unknown): Promise<void>;\n}\n\nexport function detectCI(env: Record<string, string | undefined> = process.env): CI {\n if (env.GITHUB_ACTIONS) {\n return 'github';\n }\n\n if (env.CIRCLECI) {\n return 'circleci';\n }\n\n if (env.TRAVIS) {\n return 'travis';\n }\n\n if (env.TF_BUILD) {\n return 'azure';\n }\n\n if (env.BUILDKITE) {\n return 'buildkite';\n }\n\n if (env.JENKINS_URL) {\n return 'jenkins';\n }\n\n if (env.GITLAB_CI) {\n return 'gitlab';\n }\n\n if (env.BITBUCKET_BUILD_NUMBER) {\n return 'bitbucket';\n }\n\n if (env.APPVEYOR) {\n return 'appveyor';\n }\n\n if (env.DRONE) {\n return 'drone';\n }\n\n if (env.CI) {\n return 'ci';\n }\n\n return 'unknown';\n}\n\nexport function parseDsn(dsn: string): {\n host: string;\n projectId: string;\n key: string;\n protocol: string;\n} | null {\n try {\n // https://{PUBLIC_KEY}@{host}/{project_id}\n const u = new URL(dsn);\n const projectId = u.pathname.replace(/^\\//, '');\n const key = u.username; // public key\n const host = u.host; // includes subdomain + port\n return {\n host,\n projectId,\n key,\n protocol: u.protocol.replace(':', ''),\n };\n } catch {\n return null;\n }\n}\n\nasync function sendToSentry(payload: ErrorPayload) {\n const dsn = parseDsn(SENTRY_DSN);\n\n if (!dsn) {\n return;\n }\n\n // Sentry envelope: https://develop.sentry.dev/sdk/envelopes/\n const now = Date.now();\n\n // Hexadecimal string representing a uuid4 value. The length is exactly 32\n // characters. Dashes are not allowed. Has to be lowercase.\n const eventId = crypto.randomUUID().replaceAll('-', '');\n\n const url = `https://${dsn.host}/api/${dsn.projectId}/envelope/`;\n\n const httpHeaders = {\n 'content-type': 'application/x-sentry-envelope',\n 'x-sentry-auth': [\n 'Sentry sentry_version=7',\n `sentry_key=${dsn.key}`,\n `sentry_client=${pkg.name}@${pkg.version}`,\n ].join(', '),\n };\n\n const memoryInfo = process.memoryUsage();\n\n // Minimal event; we keep fields lean & sanitized\n // https://develop.sentry.dev/sdk/data-model/event-payloads/#required-attributes\n const event = {\n event_id: eventId,\n\n // RFC 3339 format\n timestamp: new Date(now).toISOString(),\n\n // A string representing the platform the SDK is submitting from. This will\n // be used by the Sentry interface to customize various components in the\n // interface.\n platform: 'node',\n\n // Possible values: fatal, error, warning, info, debug\n level: 'error',\n\n logger: 'happo.telemetry.cli',\n\n environment: payload.env ?? 'unknown',\n\n // Release versions must be unique across all projects in the organization.\n release: `${payload.pkg.name}@${payload.pkg.version}`,\n\n tags: {\n ci: payload.ci ?? '',\n },\n\n contexts: {\n runtime: {\n type: 'runtime',\n name: 'node',\n version: payload.nodeVersion ?? '',\n },\n os: {\n type: 'os',\n name: payload.platform ?? '',\n },\n memory_info: {\n type: 'memory_info',\n ...memoryInfo,\n },\n },\n\n exception: {\n values: [\n {\n type: payload.error.name || 'Error',\n value: payload.error.message,\n\n // https://develop.sentry.dev/sdk/data-model/event-payloads/stacktrace/\n stacktrace: payload.error.stack\n ? {\n frames: await parseFrames(payload.error.stack),\n }\n : undefined,\n },\n ],\n },\n };\n\n /**\n * Envelope is ndjson-like chunks\n *\n * Envelope = Headers { \"\\n\" Item } [ \"\\n\" ] ;\n * Item = Headers \"\\n\" Payload ;\n * Payload = { * } ;\n *\n * @see https://develop.sentry.dev/sdk/data-model/envelopes/#headers\n */\n const envelopeHeader = JSON.stringify({\n event_id: eventId,\n dsn: SENTRY_DSN,\n sent_at: new Date(now).toISOString(),\n });\n\n // https://develop.sentry.dev/sdk/data-model/envelopes/#items\n const item = JSON.stringify(event);\n const itemHeader = JSON.stringify({ type: 'event', length: item.length });\n\n const body = [envelopeHeader, itemHeader, item].join('\\n');\n\n try {\n await fetch(url, { method: 'POST', headers: httpHeaders, body });\n } catch {\n // swallow; never throw in library code\n }\n}\n\ninterface SentryFrame {\n function: string;\n raw_function: string;\n abs_path: string | undefined;\n filename: string | undefined;\n lineno: number | undefined;\n colno: number | undefined;\n context_line?: string;\n pre_context?: Array<string>;\n post_context?: Array<string>;\n}\n\n/**\n * Get the package root directory\n */\nfunction getPackageRoot(): string {\n const packageJsonPath = findPackage({ cwd: import.meta.dirname });\n\n if (!packageJsonPath) {\n // Fallback to relative path if empathic can't find it\n return path.resolve(import.meta.dirname, '../..');\n }\n\n return path.dirname(packageJsonPath);\n}\n\n/**\n * Check if a file path is part of this package\n */\nfunction isFileInThisPackage(filePath: string): boolean {\n // Skip node: internal modules\n if (filePath.startsWith('node:')) {\n return false;\n }\n\n try {\n const packageRoot = getPackageRoot();\n // Remove file:// prefix if present\n const cleanPath = filePath.replace(/^file:\\/\\//, '');\n const resolvedPath = path.resolve(cleanPath);\n return resolvedPath.startsWith(packageRoot + path.sep);\n } catch {\n return false;\n }\n}\n\n/**\n * Read context lines from a source file around a given line number\n * Only reads files that are part of this package\n */\nasync function readContextLines(\n filePath: string,\n lineNumber: number,\n contextLines: number = 5,\n): Promise<{\n context_line?: string;\n pre_context?: Array<string>;\n post_context?: Array<string>;\n}> {\n // Only read context for files in this package. This is to avoid reading\n // context from external files that may contain sensitive information.\n if (!isFileInThisPackage(filePath)) {\n return {};\n }\n\n try {\n // Remove file:// prefix if present\n const cleanPath = filePath.replace(/^file:\\/\\//, '');\n\n // Line numbers are 1-indexed in stack traces, but arrays are 0-indexed\n const lineIndex = lineNumber - 1;\n\n if (lineIndex < 0) {\n return {};\n }\n\n const startLine = Math.max(0, lineIndex - contextLines);\n const endLine = lineIndex + contextLines + 1;\n\n const pre_context: Array<string> = [];\n let context_line: string | undefined;\n const post_context: Array<string> = [];\n\n const fileStream = fs.createReadStream(cleanPath, { encoding: 'utf8' });\n const rl = createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n let currentLine = 0;\n\n for await (const line of rl) {\n if (currentLine < startLine) {\n // Skip lines before our context window\n currentLine++;\n continue;\n }\n\n if (currentLine === lineIndex) {\n context_line = line;\n } else if (currentLine < lineIndex) {\n pre_context.push(line);\n } else if (currentLine < endLine) {\n post_context.push(line);\n } else {\n // We've read all the lines we need\n break;\n }\n\n currentLine++;\n }\n\n // Check if we found the target line\n if (context_line === undefined) {\n return {};\n }\n\n const result: {\n context_line: string;\n pre_context?: Array<string>;\n post_context?: Array<string>;\n } = {\n context_line,\n };\n\n if (pre_context.length > 0) {\n result.pre_context = pre_context;\n }\n\n if (post_context.length > 0) {\n result.post_context = post_context;\n }\n\n return result;\n } catch {\n // File might not exist, might not be readable, etc. Best-effort only.\n return {};\n }\n}\n\n/**\n * Convert an error stack to Sentry frames (best-effort)\n */\nexport async function parseFrames(\n stack: string,\n cwd: string = process.cwd(),\n): Promise<Array<SentryFrame>> {\n // Node stack lines like: \" at func (file:///absolute/path/to/file.js:10:5)\"\n const stackLines = stack.split('\\n').slice(0, MAX_STACK_FRAMES);\n\n const frames = [];\n\n for (const stackLine of stackLines) {\n const match = stackLine.match(\n /\\s+at\\s+(?<functionName>.*?)\\s+\\((?:file:\\/\\/)?(?<absPath>.+?):(?<lineno>\\d+):(?<colno>\\d+)\\)/,\n );\n\n if (!match || !match.groups) {\n // We didn't match a stack line, so skip it. This could cause some stack\n // lines to be dropped.\n continue;\n }\n\n const rawAbsPath = match.groups.absPath ?? '';\n\n const absPath = rawAbsPath.startsWith('node:')\n ? rawAbsPath\n : path.relative(cwd, rawAbsPath);\n const filename = rawAbsPath.startsWith('node:')\n ? rawAbsPath\n : path.basename(rawAbsPath);\n\n const functionName = match.groups.functionName ?? '';\n\n const lineno = match.groups.lineno\n ? Number.parseInt(match.groups.lineno, 10)\n : undefined;\n\n // Read context lines from the source file (only for package files)\n const context =\n rawAbsPath && lineno ? await readContextLines(rawAbsPath, lineno) : {};\n\n // https://develop.sentry.dev/sdk/data-model/event-payloads/stacktrace/#frame-attributes\n const frame: SentryFrame = {\n function: functionName.slice(0, MAX_FUNCTION_NAME_LENGTH),\n raw_function: functionName,\n\n abs_path: absPath,\n filename,\n\n lineno,\n\n colno: match.groups.colno\n ? Number.parseInt(match.groups.colno, 10)\n : undefined,\n\n ...context,\n };\n\n frames.push(frame);\n }\n\n // Sentry expects most recent frame last\n return frames.toReversed();\n}\n\nfunction isTestEnv(\n env: Record<string, string | undefined> = process.env,\n): boolean {\n return env.NODE_ENV === 'test' || Boolean(env.JEST_WORKER_ID);\n}\n\n/**\n * Create a reporter with rate limiting\n */\nexport function createReporter(opts: ReporterOptions = {}): Reporter {\n if (isTestEnv()) {\n return {\n async captureException() {\n // Never emit telemetry during tests.\n },\n };\n }\n\n const maxPerMinute = Math.max(1, opts.maxPerMinute ?? 10);\n let sentThisMinute = 0;\n let minuteTick = Date.now();\n\n function isRateLimitExceeded(): boolean {\n const now = Date.now();\n\n if (now - minuteTick >= 60_000) {\n minuteTick = now;\n sentThisMinute = 0;\n }\n\n if (sentThisMinute >= maxPerMinute) {\n return true;\n }\n\n sentThisMinute++;\n\n return false;\n }\n\n const ci = detectCI(process.env);\n const nodeVersion = process.version;\n const platform = process.platform;\n\n return {\n async captureException(e: unknown) {\n if (isRateLimitExceeded()) {\n return;\n }\n\n const err = e instanceof Error ? e : new Error(String(e));\n const message = err.message ?? 'Error';\n const stack = err.stack;\n\n const payload: ErrorPayload = {\n pkg,\n env: opts.env ?? process.env.NODE_ENV ?? 'unknown',\n ci,\n nodeVersion,\n platform,\n\n error: {\n name: err.name || 'Error',\n message,\n stack: stack ?? '',\n },\n };\n\n await sendToSentry(payload);\n },\n };\n}\n", "#!/usr/bin/env node\n\nimport { main } from './index.ts';\n\nawait main();\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "fs", "sha", "crypto", "fs", "path", "createInterface", "crypto", "path", "fs", "createInterface", "path"]
7
7
  }
@@ -0,0 +1,7 @@
1
+ import {
2
+ package_default
3
+ } from "./chunk-Z32R7CJB.js";
4
+ export {
5
+ package_default as default
6
+ };
7
+ //# sourceMappingURL=package-UABOUH2S.js.map
@@ -78,6 +78,9 @@ export declare const parseOptions: {
78
78
  readonly skip: {
79
79
  readonly type: "string";
80
80
  };
81
+ readonly skippedExamples: {
82
+ readonly type: "string";
83
+ };
81
84
  readonly only: {
82
85
  readonly type: "string";
83
86
  };
@@ -1 +1 @@
1
- {"version":3,"file":"parseOptions.d.ts","sourceRoot":"","sources":["../../src/cli/parseOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Gf,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,UAAU,CACpC,OAAO,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,YAAY,CAAC;IAAC,gBAAgB,EAAE,IAAI,CAAA;CAAE,CAAC,CAC3E,CAAC,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"parseOptions.d.ts","sourceRoot":"","sources":["../../src/cli/parseOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgHf,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,UAAU,CACpC,OAAO,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,YAAY,CAAC;IAAC,gBAAgB,EAAE,IAAI,CAAA;CAAE,CAAC,CAC3E,CAAC,QAAQ,CAAC,CAAC"}
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-ML3Z5Z22.js";
5
5
  import {
6
6
  makeHappoAPIRequest
7
- } from "./chunk-JJOM7NVS.js";
7
+ } from "./chunk-2CCKQG4B.js";
8
8
  import {
9
9
  ErrorWithStatusCode
10
- } from "./chunk-WUYZIKHR.js";
11
- import "./chunk-KTUIEOPK.js";
10
+ } from "./chunk-LGXU3JNM.js";
11
+ import "./chunk-Z32R7CJB.js";
12
12
 
13
13
  // src/network/prepareSnapRequests.ts
14
14
  import fs5 from "node:fs";
@@ -973,4 +973,4 @@ async function prepareSnapRequests(config, skip, only) {
973
973
  export {
974
974
  prepareSnapRequests as default
975
975
  };
976
- //# sourceMappingURL=prepareSnapRequests-RINWFSWA.js.map
976
+ //# sourceMappingURL=prepareSnapRequests-KMVRPKIT.js.map
@@ -0,0 +1,10 @@
1
+ import {
2
+ startJob
3
+ } from "./chunk-5GCRDC6E.js";
4
+ import "./chunk-2CCKQG4B.js";
5
+ import "./chunk-LGXU3JNM.js";
6
+ import "./chunk-Z32R7CJB.js";
7
+ export {
8
+ startJob as default
9
+ };
10
+ //# sourceMappingURL=startJob-TUFOU2O5.js.map