UNPKG

cypress-cloud

Version:
1,615 lines (1,579 loc) 320 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var cypress_cloud_exports = {}; __export(cypress_cloud_exports, { run: () => run2 }); module.exports = __toCommonJS(cypress_cloud_exports); // ../../node_modules/tsup/assets/cjs_shims.js var getImportMetaUrl = () => typeof document === "undefined" ? new URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href; var importMetaUrl = /* @__PURE__ */ getImportMetaUrl(); // index.ts var import_register = require("source-map-support/register.js"); // lib/require.ts var import_module = require("module"); var require2 = (0, import_module.createRequire)(importMetaUrl); // lib/stdout.ts var import_child_process = __toESM(require("child_process")); var orginal = import_child_process.default.spawn; import_child_process.default.spawn = function(command, args, options) { if (command.match(/Cypress/)) { const process2 = orginal(command, args, { ...options, // using pipe enables capturing stdout and stderr stdio: ["pipe", "pipe", "pipe"] }); return process2; } return orginal(command, args, options); }; // lib/ws/ws.ts var import_debug = __toESM(require("debug")); var import_http = __toESM(require("http")); var import_lil_http_terminator = __toESM(require("lil-http-terminator")); var import_ts_pattern = require("ts-pattern"); var WebSocket = __toESM(require("ws")); // lib/pubsub.ts var import_events = __toESM(require("events")); var pubsub = new import_events.default(); // lib/ws/ws.ts var debug = (0, import_debug.default)("currents:ws"); var server = null; var wss = null; var httpTerminator = null; var getWSSPort = () => (0, import_ts_pattern.match)(server?.address()).with({ port: import_ts_pattern.P.number }, (address) => address.port).otherwise(() => 0); var stopWSS = async () => { debug("terminating wss server: %d", getWSSPort()); if (!httpTerminator) { debug("no wss server"); return; } const { success, code, message, error: error2 } = await httpTerminator.terminate(); if (!success) { if (code === "TIMED_OUT") error2(message); if (code === "SERVER_ERROR") error2(message, error2); if (code === "INTERNAL_ERROR") error2(message, error2); } debug("terminated wss server: %d", getWSSPort()); }; var startWSS = () => { if (wss) { return; } server = import_http.default.createServer().on("listening", () => { if (!server) { throw new Error("Server not initialized"); } wss = new WebSocket.WebSocketServer({ server }); debug("starting wss on port %d", getWSSPort()); wss.on("connection", function connection(ws) { ws.on("message", function incoming(event) { const message = JSON.parse(event.toString()); pubsub.emit(message.type, message.payload); }); }); }).listen(); httpTerminator = (0, import_lil_http_terminator.default)({ server }); }; // lib/capture.ts var import_debug2 = __toESM(require("debug")); var debug2 = (0, import_debug2.default)("currents:capture"); var _write = process.stdout.write; var _log = process.log; var restore = function() { process.stdout.write = _write; process.log = _log; }; var stdout = function() { debug2("capturing stdout"); let logs = []; const { write } = process.stdout; const { log: log2 } = process; if (log2) { process.log = function(str) { logs.push(str); return log2.apply(this, arguments); }; } process.stdout.write = function(str) { logs.push(str); return write.apply(this, arguments); }; return { toString() { return logs.join(""); }, data: logs, restore, reset: () => { debug2("resetting captured stdout"); logs = []; } }; }; var initialOutput = ""; var capturedOutput = null; var initCapture = () => capturedOutput = stdout(); var cutInitialOutput = () => { if (!capturedOutput) throw new Error("capturedOutput is null"); initialOutput = capturedOutput.toString(); capturedOutput.reset(); }; var resetCapture = () => { if (!capturedOutput) throw new Error("capturedOutput is null"); capturedOutput.reset(); }; var getCapturedOutput = () => { if (!capturedOutput) throw new Error("capturedOutput is null"); return capturedOutput.toString(); }; var getInitialOutput = () => initialOutput; // lib/httpClient/config.ts var import_axios = require("axios"); var isRetriableError = (err) => { if (err.code === "ECONNABORTED") { return true; } if (err.code === "ECONNREFUSED") { return true; } if (err.code === "ETIMEDOUT") { return true; } if (!(0, import_axios.isAxiosError)(err)) { return false; } return !!(err?.response?.status && 500 <= err.response.status && err.response.status < 600); }; var getDelay = (i) => [5 * 1e3, 10 * 1e3, 30 * 1e3][i - 1]; var baseURL = "https://cy.currents.dev"; var getAPIBaseUrl = () => baseURL ?? "https://cy.currents.dev"; var setAPIBaseUrl = (url) => baseURL = url ?? "https://cy.currents.dev"; // lib/httpClient/httpClient.ts var import_axios2 = __toESM(require("axios")); var import_axios_retry = __toESM(require("axios-retry")); var import_debug7 = __toESM(require("debug")); var import_lodash5 = __toESM(require("lodash")); var import_pretty_ms = __toESM(require("pretty-ms")); // lib/config/config.ts var import_debug5 = __toESM(require("debug")); var import_ts_pattern2 = require("ts-pattern"); // lib/bootstrap/bootstrap.ts var import_cy2 = require("cy2"); var import_debug4 = __toESM(require("debug")); var import_execa = __toESM(require("execa")); var import_fs = __toESM(require("fs")); // lib/errors.ts var ValidationError = class extends Error { constructor(message) { super(message); this.name = ""; } }; // lib/fs.ts var import_tmp_promise = require("tmp-promise"); var createTempFile = async () => { const { path: path4 } = await (0, import_tmp_promise.file)(); return path4; }; // lib/log.ts var import_chalk = __toESM(require("chalk")); var import_util = __toESM(require("util")); var log = (...args) => console.log(import_util.default.format(...args)); var info = log; var format = import_util.default.format; var withError = (msg) => import_chalk.default.bgRed.white(" ERROR ") + " " + msg; var withWarning = (msg) => import_chalk.default.bgYellow.black(" WARNING ") + " " + msg; var warn = (...args) => log(withWarning(import_util.default.format(...args))); var error = (...args) => log(withError(import_util.default.format(...args)) + "\n"); var title = (color, ...args) => info("\n " + import_chalk.default[color].bold(import_util.default.format(...args)) + " \n"); var divider = () => console.log("\n" + import_chalk.default.gray(Array(100).fill("=").join("")) + "\n"); var spacer = (n = 0) => console.log(Array(n).fill("").join("\n")); var cyan = import_chalk.default.cyan; var blue = import_chalk.default.blueBright; var red = import_chalk.default.red; var green = import_chalk.default.greenBright; var gray = import_chalk.default.gray; var white = import_chalk.default.white; var magenta = import_chalk.default.magenta; var bold = import_chalk.default.bold; var yellow = import_chalk.default.yellow; var dim = import_chalk.default.dim; // lib/bootstrap/serializer.ts var import_debug3 = __toESM(require("debug")); var import_lodash = __toESM(require("lodash")); var import_nanoid = require("nanoid"); var debug3 = (0, import_debug3.default)("currents:boot"); var getDummySpec = (0, import_nanoid.customAlphabet)("abcdefghijklmnopqrstuvwxyz", 10); function getBootstrapArgs({ params, tempFilePath }) { return import_lodash.default.chain(getCypressCLIParams(params)).thru((opts) => ({ ...opts, // merge the env with the currents specific env variables env: { ...opts.env ?? {}, currents_temp_file: tempFilePath, currents_debug_enabled: process.env.DEBUG?.includes("currents:") ? true : false } })).tap((opts) => { debug3("cypress bootstrap params: %o", opts); }).thru(serializeOptions).tap((opts) => { debug3("cypress bootstrap serialized params: %o", opts); }).thru((args) => { return [ ...args, "--spec", getDummySpec(), params.testingType === "component" ? "--component" : "--e2e" ]; }).value(); } function getCypressCLIParams(params) { const result = getCypressRunAPIParams(params); const testingType = result.testingType === "component" ? { component: true } : {}; return { ...import_lodash.default.omit(result, "testingType"), ...testingType }; } function serializeOptions(options) { return Object.entries(options).flatMap(([key, value]) => { const _key = dashed(key); if (typeof value === "boolean") { return value === true ? [`--${_key}`] : [`--${_key}`, false]; } if (import_lodash.default.isObject(value)) { return [`--${_key}`, serializeComplexParam(value)]; } return [`--${_key}`, value.toString()]; }); } function serializeComplexParam(param) { return JSON.stringify(param); } var dashed = (v) => v.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()); // lib/bootstrap/bootstrap.ts var debug4 = (0, import_debug4.default)("currents:boot"); var bootCypress = async (params) => { debug4("booting cypress..."); const tempFilePath = await createTempFile(); const cypressBin = await (0, import_cy2.getBinPath)(require2.resolve("cypress")); debug4("cypress executable location: %s", cypressBin); const args = getBootstrapArgs({ tempFilePath, params }); debug4("booting cypress with args: %o", args); const { stdout: stdout2, stderr } = await execCypress(cypressBin, args); if (!import_fs.default.existsSync(tempFilePath)) { throw new Error( `Cannot resolve cypress configuration from ${tempFilePath}. Please report the issue.` ); } try { const f = import_fs.default.readFileSync(tempFilePath, "utf-8"); if (!f) { throw new Error("Is cypress-cloud/plugin installed?"); } debug4("cypress config '%s': '%s'", tempFilePath, f); return JSON.parse(f); } catch (err) { debug4("read config temp file failed: %o", err); info(bold("Cypress stdout:\n"), stdout2); info(bold("Cypress stderr:\n"), stderr); throw new ValidationError(`Unable to resolve cypress configuration - make sure that 'cypress-cloud/plugin' is installed - report the issue together with cypress stdout and stderr `); } }; async function execCypress(cypressBin, args) { let stdout2 = ""; let stderr = ""; try { await (0, import_execa.default)(cypressBin, ["run", ...args], { stdio: "pipe", env: { ...process.env, // prevent warnings about recording mode CYPRESS_RECORD_KEY: void 0, CYPRESS_PROJECT_ID: void 0 } }); } catch (err) { debug4("exec cypress failed (certain failures are expected): %o", err); stdout2 = err.stdout; stderr = err.stderr; } return { stdout: stdout2, stderr }; } // lib/config/path.ts var import_is_absolute = __toESM(require("is-absolute")); var import_lodash2 = __toESM(require("lodash")); var import_path = __toESM(require("path")); var defaultFilenames = [ "currents.config.js", "currents.config.cjs", "currents.config.mjs" ]; function getConfigFilePath(projectRoot = null, explicitConfigFilePath) { const prefix = projectRoot ?? process.cwd(); if (import_lodash2.default.isString(explicitConfigFilePath) && (0, import_is_absolute.default)(explicitConfigFilePath)) { return [explicitConfigFilePath]; } if (import_lodash2.default.isString(explicitConfigFilePath)) { return [normalizePath(prefix, explicitConfigFilePath)]; } return defaultFilenames.map((p) => normalizePath(prefix, p)); } function normalizePath(prefix, filename) { return `file://${import_path.default.resolve(prefix, filename)}`; } // lib/config/config.ts var debug5 = (0, import_debug5.default)("currents:config"); var _config = null; var defaultConfig = { e2e: { batchSize: 3 }, component: { batchSize: 5 }, cloudServiceUrl: "https://cy.currents.dev", networkHeaders: void 0 }; async function getCurrentsConfig(projectRoot, explicitConfigFilePath) { if (_config) { return _config; } const configFilePath = getConfigFilePath(projectRoot, explicitConfigFilePath); for (const filepath of configFilePath) { const config = (0, import_ts_pattern2.match)(await loadConfigFile(filepath)).with({ default: import_ts_pattern2.P.not(import_ts_pattern2.P.nullish) }, (c) => c.default).with(import_ts_pattern2.P.not(import_ts_pattern2.P.nullish), (c) => c).otherwise(() => null); if (config) { debug5("loaded currents config from '%s'\n%O", filepath, config); info("Using config file: '%s'", filepath); _config = { ...defaultConfig, ...config }; return _config; } } warn( "Failed to load config file, falling back to the default config. Attempted locations: %s", configFilePath ); _config = defaultConfig; return _config; } async function loadConfigFile(filepath) { try { debug5("loading currents config file from '%s'", filepath); return await import(filepath); } catch (e) { debug5("failed loading config file from: %s", e); return null; } } async function getMergedConfig(params) { debug5("resolving cypress config"); const cypressResolvedConfig = await bootCypress(params); debug5("cypress resolvedConfig: %O", cypressResolvedConfig); const rawE2EPattern = cypressResolvedConfig.rawJson?.e2e?.specPattern; let additionalIgnorePattern = []; if (params.testingType === "component" && rawE2EPattern) { additionalIgnorePattern = rawE2EPattern; } const result = { projectRoot: cypressResolvedConfig?.projectRoot || process.cwd(), projectId: params.projectId, specPattern: cypressResolvedConfig?.specPattern || "**/*.*", excludeSpecPattern: ( // @ts-ignore cypressResolvedConfig?.resolved.excludeSpecPattern.value ?? [] ), additionalIgnorePattern, resolved: cypressResolvedConfig, experimentalCoverageRecording: params.experimentalCoverageRecording }; debug5("merged config: %O", result); return result; } // lib/config/params.ts var import_debug6 = __toESM(require("debug")); var import_lodash3 = __toESM(require("lodash")); var debug6 = (0, import_debug6.default)("currents:validateParams"); async function resolveCurrentsParams(params) { const configFromFile = await getCurrentsConfig( params.project, params.cloudConfigFile ); debug6("resolving currents params: %o", params); debug6("resolving currents config file: %o", configFromFile); const cloudServiceUrl = params.cloudServiceUrl ?? process.env.CURRENTS_API_URL ?? configFromFile.cloudServiceUrl; const recordKey = params.recordKey ?? process.env.CURRENTS_RECORD_KEY ?? configFromFile.recordKey; const projectId = params.projectId ?? process.env.CURRENTS_PROJECT_ID ?? configFromFile.projectId; const testingType = params.testingType ?? "e2e"; const batchSize = testingType === "e2e" ? configFromFile.e2e.batchSize : configFromFile.component.batchSize; return { ...params, cloudServiceUrl, recordKey, projectId, batchSize, testingType }; } var projectIdError = `Cannot resolve projectId. Please use one of the following: - provide it as a "projectId" property for "run" API method - set CURRENTS_PROJECT_ID environment variable - set "projectId" in "currents.config.{c}js" file`; var cloudServiceUrlError = `Cannot resolve cloud service URL. Please use one of the following: - provide it as a "cloudServiceUrl" property for "run" API method - set CURRENTS_API_URL environment variable - set "cloudServiceUrl" in "currents.config.{c}js" file`; var cloudServiceInvalidUrlError = `Invalid cloud service URL provided`; var recordKeyError = `Cannot resolve record key. Please use one of the following: - pass it as a CLI flag '-k, --key <record-key>' - provide it as a "recordKey" property for "run" API method - set CURRENTS_RECORD_KEY environment variable - set "recordKey" in "currents.config.{c}js" file `; async function validateParams(_params) { const params = await resolveCurrentsParams(_params); debug6("validating currents params: %o", params); if (!params.cloudServiceUrl) { throw new ValidationError(cloudServiceUrlError); } if (!params.projectId) { throw new ValidationError(projectIdError); } if (!params.recordKey) { throw new ValidationError(recordKeyError); } validateURL(params.cloudServiceUrl); const requiredParameters = [ "testingType", "batchSize", "projectId" ]; requiredParameters.forEach((key) => { if (typeof params[key] === "undefined") { error('Missing required parameter "%s"', key); throw new Error("Missing required parameter"); } }); params.tag = parseTags(params.tag); params.autoCancelAfterFailures = getAutoCancelValue( params.autoCancelAfterFailures ); debug6("validated currents params: %o", params); return params; } function getAutoCancelValue(value) { if (typeof value === "undefined") { return void 0; } if (typeof value === "boolean") { return value ? 1 : false; } if (typeof value === "number" && value > 0) { return value; } throw new ValidationError( `autoCancelAfterFailures: should be a positive integer or "false". Got: "${value}"` ); } function isOffline(params) { return params.record === false; } function parseTags(tagString) { if (!tagString) { return []; } if (Array.isArray(tagString)) { return tagString.filter(Boolean); } return tagString.split(",").map((tag) => tag.trim()).filter(Boolean); } function validateURL(url) { try { new URL(url); } catch (err) { throw new ValidationError(`${cloudServiceInvalidUrlError}: "${url}"`); } } function getCypressRunAPIParams(params) { return { ...import_lodash3.default.pickBy( import_lodash3.default.omit(params, [ "cloudDebug", "cloudConfigFile", "autoCancelAfterFailures", "cloudServiceUrl", "batchSize", "projectId", "key", "recordKey", "record", "group", "parallel", "tag", "ciBuildId", "spec", "exit", "headless", "experimentalCoverageRecording" ]), Boolean ), record: false }; } function preprocessParams(params) { return { ...params, spec: processSpecParam(params.spec) }; } function processSpecParam(spec) { if (!spec) { return void 0; } if (Array.isArray(spec)) { return import_lodash3.default.flatten(spec.map((i) => i.split(","))); } return spec.split(","); } // lib/httpClient/printErrors.ts var import_lodash4 = __toESM(require("lodash")); function maybePrintErrors(err) { if (!err.response?.data || !err.response?.status) { return; } const { message, errors } = err.response.data; switch (err.response.status) { case 401: warn("Received 401 Unauthorized"); break; case 422: spacer(1); warn(...formatGenericError(message, errors)); spacer(1); break; default: break; } } function formatGenericError(message, errors) { if (!import_lodash4.default.isString(message)) { return ["Unexpected error from the cloud service"]; } if (errors?.length === 0) { return [message]; } return [ message, ` ${(errors ?? []).map((e) => ` - ${e}`).join("\n")} ` ]; } // lib/httpClient/httpClient.ts var debug7 = (0, import_debug7.default)("currents:api"); var MAX_RETRIES = 3; var TIMEOUT_MS = 30 * 1e3; var _client = null; async function getClient() { if (_client) { return _client; } const currentsConfig = await getCurrentsConfig(); _client = import_axios2.default.create({ baseURL: getAPIBaseUrl(), timeout: TIMEOUT_MS }); _client.interceptors.request.use((config) => { const ccyVerson = _currentsVersion ?? "0.0.0"; const headers = { ...config.headers, // @ts-ignore "x-cypress-request-attempt": config["axios-retry"]?.retryCount ?? 0, "x-cypress-version": _cypressVersion ?? "0.0.0", "x-ccy-version": ccyVerson, "User-Agent": `cypress-cloud/${ccyVerson}` }; if (_runId) { headers["x-cypress-run-id"] = _runId; } if (!headers["Content-Type"]) { headers["Content-Type"] = "application/json"; } if (currentsConfig.networkHeaders) { const filteredHeaders = import_lodash5.default.omit(currentsConfig.networkHeaders, [ "x-cypress-request-attempt", "x-cypress-version", "x-ccy-version", "x-cypress-run-id", "Content-Type" ]); debug7("using custom network headers: %o", filteredHeaders); Object.assign(headers, filteredHeaders); } const req = { ...config, headers }; debug7("network request: %o", { ...import_lodash5.default.pick(req, "method", "url", "headers"), data: Buffer.isBuffer(req.data) ? "buffer" : req.data }); return req; }); (0, import_axios_retry.default)(_client, { retries: MAX_RETRIES, retryCondition: isRetriableError, retryDelay: getDelay, // @ts-ignore onRetry, shouldResetTimeout: true }); return _client; } var _runId = void 0; var setRunId = (runId) => { _runId = runId; }; var _cypressVersion = void 0; var setCypressVersion = (cypressVersion) => { _cypressVersion = cypressVersion; }; var _currentsVersion = void 0; var setCurrentsVersion = (v) => { _currentsVersion = v; }; function onRetry(retryCount, err, config) { warn( "Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).", `${config.method} ${config.url}`, err.message, (0, import_pretty_ms.default)(getDelay(retryCount)), retryCount, MAX_RETRIES ); } var makeRequest = async (config) => { return (await getClient())(config).then((res) => { debug7("network response: %o", import_lodash5.default.omit(res, "request", "config")); return res; }).catch((error2) => { maybePrintErrors(error2); throw new ValidationError(error2.message); }); }; // lib/init.ts var cypressPkg = require2("cypress/package.json"); var pkg = require2("cypress-cloud/package.json"); initCapture(); setCypressVersion(cypressPkg.version); setCurrentsVersion(pkg.version); // lib/run.ts var import_debug22 = __toESM(require("debug")); var import_plur = __toESM(require("plur")); // legal.ts function getLegalNotice() { return ` Copyright (C) ${(/* @__PURE__ */ new Date()).getFullYear()} Currents Software Inc https://currents.dev This is free software, and you are welcome to redistribute it under certain conditions. This program comes with no warranty. Parts of this program are MIT licensed. Refer to the license for details https://github.com/currents-dev/cypress-cloud/blob/main/LICENSE.md `; } // lib/api/warnings.ts var import_lodash6 = __toESM(require("lodash")); function printWarnings(warnings) { warn("Notice from cloud service:"); warnings.map((w) => { spacer(1); info(magenta.bold(w.message)); Object.entries(import_lodash6.default.omit(w, "message")).map(([key, value]) => { info("- %s: %s", key, value); }); spacer(1); }); } // lib/api/api.ts var createRun = async (payload) => { const response = await makeRequest({ method: "POST", url: "/runs", data: payload }); if ((response.data.warnings?.length ?? 0) > 0) { printWarnings(response.data.warnings); } return response.data; }; var createInstance = async ({ runId, groupId, machineId, platform: platform2 }) => { const response = await makeRequest({ method: "POST", url: `runs/${runId}/instances`, data: { runId, groupId, machineId, platform: platform2 } }); return response.data; }; var createBatchedInstances = async (data) => { const respone = await makeRequest({ method: "POST", url: `runs/${data.runId}/cy/instances`, data }); return respone.data; }; var setInstanceTests = (instanceId, payload) => makeRequest({ method: "POST", url: `instances/${instanceId}/tests`, data: payload }).then((result) => result.data); var updateInstanceResults = (instanceId, payload) => makeRequest({ method: "POST", url: `instances/${instanceId}/results`, data: payload }).then((result) => result.data); var reportInstanceResultsMerged = (instanceId, payload) => makeRequest({ method: "POST", url: `instances/${instanceId}/cy/results`, data: payload }).then((result) => result.data); var updateInstanceStdout = (instanceId, stdout2) => makeRequest({ method: "PUT", url: `instances/${instanceId}/stdout`, data: { stdout: stdout2 } }); // lib/ciProvider/ciProvider.ts var import_debug8 = __toESM(require("debug")); var import_lodash7 = __toESM(require("lodash")); var debug8 = (0, import_debug8.default)("currents:ci"); var join = (char, ...pieces) => { return import_lodash7.default.chain(pieces).compact().join(char).value(); }; var toCamelObject = (obj, key) => { return import_lodash7.default.set(obj, import_lodash7.default.camelCase(key), process.env[key]); }; var extract = (envKeys) => { return import_lodash7.default.transform(envKeys, toCamelObject, {}); }; var isTeamFoundation = () => { return process.env.TF_BUILD && process.env.TF_BUILD_BUILDNUMBER; }; var isAzureCi = () => { return process.env.TF_BUILD && process.env.AZURE_HTTP_USER_AGENT; }; var isAWSCodeBuild = () => { return import_lodash7.default.some(process.env, (val, key) => { return /^CODEBUILD_/.test(key); }); }; var isBamboo = () => { return process.env.bamboo_buildNumber; }; var isCodeshipBasic = () => { return process.env.CI_NAME && process.env.CI_NAME === "codeship" && process.env.CODESHIP; }; var isCodeshipPro = () => { return process.env.CI_NAME && process.env.CI_NAME === "codeship" && !process.env.CODESHIP; }; var isConcourse = () => { return import_lodash7.default.some(process.env, (val, key) => { return /^CONCOURSE_/.test(key); }); }; var isGitlab = () => { return process.env.GITLAB_CI || process.env.CI_SERVER_NAME && /^GitLab/.test(process.env.CI_SERVER_NAME); }; var isGoogleCloud = () => { return process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT; }; var isJenkins = () => { return process.env.JENKINS_URL || process.env.JENKINS_HOME || process.env.JENKINS_VERSION || process.env.HUDSON_URL || process.env.HUDSON_HOME; }; var isWercker = () => { return process.env.WERCKER || process.env.WERCKER_MAIN_PIPELINE_STARTED; }; var CI_PROVIDERS = { appveyor: "APPVEYOR", azure: isAzureCi, awsCodeBuild: isAWSCodeBuild, bamboo: isBamboo, bitbucket: "BITBUCKET_BUILD_NUMBER", buildkite: "BUILDKITE", circle: "CIRCLECI", codeshipBasic: isCodeshipBasic, codeshipPro: isCodeshipPro, concourse: isConcourse, codeFresh: "CF_BUILD_ID", drone: "DRONE", githubActions: "GITHUB_ACTIONS", gitlab: isGitlab, goCD: "GO_JOB_NAME", googleCloud: isGoogleCloud, jenkins: isJenkins, semaphore: "SEMAPHORE", shippable: "SHIPPABLE", teamcity: "TEAMCITY_VERSION", teamfoundation: isTeamFoundation, travis: "TRAVIS", wercker: isWercker, netlify: "NETLIFY", layerci: "LAYERCI" }; function _detectProviderName() { const { env } = process; return import_lodash7.default.findKey(CI_PROVIDERS, (value) => { if (import_lodash7.default.isString(value)) { return env[value]; } if (import_lodash7.default.isFunction(value)) { return value(); } }); } var _providerCiParams = () => { return { appveyor: extract([ "APPVEYOR_JOB_ID", "APPVEYOR_ACCOUNT_NAME", "APPVEYOR_PROJECT_SLUG", "APPVEYOR_BUILD_NUMBER", "APPVEYOR_BUILD_VERSION", "APPVEYOR_PULL_REQUEST_NUMBER", "APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH" ]), azure: extract([ "BUILD_BUILDID", "BUILD_BUILDNUMBER", "BUILD_CONTAINERID", "BUILD_REPOSITORY_URI" ]), awsCodeBuild: extract([ "CODEBUILD_BUILD_ID", "CODEBUILD_BUILD_NUMBER", "CODEBUILD_RESOLVED_SOURCE_VERSION", "CODEBUILD_SOURCE_REPO_URL", "CODEBUILD_SOURCE_VERSION" ]), bamboo: extract([ "bamboo_buildNumber", "bamboo_buildResultsUrl", "bamboo_planRepository_repositoryUrl", "bamboo_buildKey" ]), bitbucket: extract([ "BITBUCKET_REPO_SLUG", "BITBUCKET_REPO_OWNER", "BITBUCKET_BUILD_NUMBER", "BITBUCKET_PARALLEL_STEP", "BITBUCKET_STEP_RUN_NUMBER", // the PR variables are only set on pull request builds "BITBUCKET_PR_ID", "BITBUCKET_PR_DESTINATION_BRANCH", "BITBUCKET_PR_DESTINATION_COMMIT" ]), buildkite: extract([ "BUILDKITE_REPO", "BUILDKITE_SOURCE", "BUILDKITE_JOB_ID", "BUILDKITE_BUILD_ID", "BUILDKITE_BUILD_URL", "BUILDKITE_BUILD_NUMBER", "BUILDKITE_PULL_REQUEST", "BUILDKITE_PULL_REQUEST_REPO", "BUILDKITE_PULL_REQUEST_BASE_BRANCH" ]), circle: extract([ "CIRCLE_JOB", "CIRCLE_BUILD_NUM", "CIRCLE_BUILD_URL", "CIRCLE_PR_NUMBER", "CIRCLE_PR_REPONAME", "CIRCLE_PR_USERNAME", "CIRCLE_COMPARE_URL", "CIRCLE_WORKFLOW_ID", "CIRCLE_PULL_REQUEST", "CIRCLE_REPOSITORY_URL", "CI_PULL_REQUEST" ]), codeshipBasic: extract([ "CI_BUILD_ID", "CI_REPO_NAME", "CI_BUILD_URL", "CI_PROJECT_ID", "CI_BUILD_NUMBER", "CI_PULL_REQUEST" ]), // CodeshipPro provides very few CI variables // https://documentation.codeship.com/pro/builds-and-configuration/environment-variables/ codeshipPro: extract(["CI_BUILD_ID", "CI_REPO_NAME", "CI_PROJECT_ID"]), // https://concourse-ci.org/implementing-resource-types.html#resource-metadata concourse: extract([ "BUILD_ID", "BUILD_NAME", "BUILD_JOB_NAME", "BUILD_PIPELINE_NAME", "BUILD_TEAM_NAME", "ATC_EXTERNAL_URL" ]), // https://codefresh.io/docs/docs/codefresh-yaml/variables/ codeFresh: extract([ "CF_BUILD_ID", "CF_BUILD_URL", "CF_CURRENT_ATTEMPT", "CF_STEP_NAME", "CF_PIPELINE_NAME", "CF_PIPELINE_TRIGGER_ID", // variables added for pull requests "CF_PULL_REQUEST_ID", "CF_PULL_REQUEST_IS_FORK", "CF_PULL_REQUEST_NUMBER", "CF_PULL_REQUEST_TARGET" ]), drone: extract([ "DRONE_JOB_NUMBER", "DRONE_BUILD_LINK", "DRONE_BUILD_NUMBER", "DRONE_PULL_REQUEST" ]), // https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables githubActions: extract([ "GITHUB_WORKFLOW", "GITHUB_ACTION", "GITHUB_EVENT_NAME", "GITHUB_RUN_ID", "GITHUB_RUN_ATTEMPT", "GITHUB_REPOSITORY" ]), // see https://docs.gitlab.com/ee/ci/variables/ gitlab: extract([ // pipeline is common among all jobs "CI_PIPELINE_ID", "CI_PIPELINE_URL", // individual jobs "CI_BUILD_ID", // build id and job id are aliases "CI_JOB_ID", "CI_JOB_URL", "CI_JOB_NAME", // other information "GITLAB_HOST", "CI_PROJECT_ID", "CI_PROJECT_URL", "CI_REPOSITORY_URL", "CI_ENVIRONMENT_URL", "CI_DEFAULT_BRANCH" // for PRs: https://gitlab.com/gitlab-org/gitlab-ce/issues/23902 ]), // https://docs.gocd.org/current/faq/dev_use_current_revision_in_build.html#standard-gocd-environment-variables goCD: extract([ "GO_SERVER_URL", "GO_ENVIRONMENT_NAME", "GO_PIPELINE_NAME", "GO_PIPELINE_COUNTER", "GO_PIPELINE_LABEL", "GO_STAGE_NAME", "GO_STAGE_COUNTER", "GO_JOB_NAME", "GO_TRIGGER_USER", "GO_REVISION", "GO_TO_REVISION", "GO_FROM_REVISION", "GO_MATERIAL_HAS_CHANGED" ]), googleCloud: extract([ // individual jobs "BUILD_ID", "PROJECT_ID", // other information "REPO_NAME", "BRANCH_NAME", "TAG_NAME", "COMMIT_SHA", "SHORT_SHA" // https://cloud.google.com/cloud-build/docs/api/reference/rest/Shared.Types/Build ]), jenkins: extract(["BUILD_ID", "BUILD_URL", "BUILD_NUMBER", "ghprbPullId"]), // https://semaphoreci.com/docs/available-environment-variables.html // some come from v1, some from v2 of semaphore semaphore: extract([ "SEMAPHORE_BRANCH_ID", "SEMAPHORE_BUILD_NUMBER", "SEMAPHORE_CURRENT_JOB", "SEMAPHORE_CURRENT_THREAD", "SEMAPHORE_EXECUTABLE_UUID", "SEMAPHORE_GIT_BRANCH", "SEMAPHORE_GIT_DIR", "SEMAPHORE_GIT_REF", "SEMAPHORE_GIT_REF_TYPE", "SEMAPHORE_GIT_REPO_SLUG", "SEMAPHORE_GIT_SHA", "SEMAPHORE_GIT_URL", "SEMAPHORE_JOB_COUNT", "SEMAPHORE_JOB_ID", // v2 "SEMAPHORE_JOB_NAME", "SEMAPHORE_JOB_UUID", // v1 "SEMAPHORE_PIPELINE_ID", "SEMAPHORE_PLATFORM", "SEMAPHORE_PROJECT_DIR", "SEMAPHORE_PROJECT_HASH_ID", "SEMAPHORE_PROJECT_ID", // v2 "SEMAPHORE_PROJECT_NAME", "SEMAPHORE_PROJECT_UUID", // v1 "SEMAPHORE_REPO_SLUG", "SEMAPHORE_TRIGGER_SOURCE", "SEMAPHORE_WORKFLOW_ID", "PULL_REQUEST_NUMBER" // pull requests from forks ONLY ]), // see http://docs.shippable.com/ci/env-vars/ shippable: extract([ // build variables "SHIPPABLE_BUILD_ID", // "5b93354cabfabb07007f01fd" "SHIPPABLE_BUILD_NUMBER", // "4" "SHIPPABLE_COMMIT_RANGE", // "sha1...sha2" "SHIPPABLE_CONTAINER_NAME", // "c.exec.cypress-example-kitchensink.4.1" "SHIPPABLE_JOB_ID", // "1" "SHIPPABLE_JOB_NUMBER", // "1" "SHIPPABLE_REPO_SLUG", // "<username>/<repo>" // additional information that Shippable provides "IS_FORK", // "true" "IS_GIT_TAG", // "false" "IS_PRERELEASE", // "false" "IS_RELEASE", // "false" "REPOSITORY_URL", // "https://github.com/....git" "REPO_FULL_NAME", // "<username>/<repo>" "REPO_NAME", // "cypress-example-kitchensink" "BUILD_URL", // "https://app.shippable.com/github/<username>/<repo>/runs/1" // Pull request information "BASE_BRANCH", // Name of the target branch into which the pull request changes will be merged. "HEAD_BRANCH", // This is only set for pull requests and is the name of the branch the pull request was opened from. "IS_PULL_REQUEST", // "false" or "true" "PULL_REQUEST", // Pull request number if the job is a pull request. If not, this will be set to false. "PULL_REQUEST_BASE_BRANCH", // Name of the branch that the pull request will be merged into. It should be the same as BASE_BRANCH. "PULL_REQUEST_REPO_FULL_NAME" // Full name of the repository from where the pull request originated. ]), teamcity: null, teamfoundation: extract([ "BUILD_BUILDID", "BUILD_BUILDNUMBER", "BUILD_CONTAINERID" ]), travis: extract([ "TRAVIS_JOB_ID", "TRAVIS_BUILD_ID", "TRAVIS_BUILD_WEB_URL", "TRAVIS_REPO_SLUG", "TRAVIS_JOB_NUMBER", "TRAVIS_EVENT_TYPE", "TRAVIS_COMMIT_RANGE", "TRAVIS_BUILD_NUMBER", "TRAVIS_PULL_REQUEST", "TRAVIS_PULL_REQUEST_BRANCH", "TRAVIS_PULL_REQUEST_SHA" ]), wercker: null, // https://docs.netlify.com/configure-builds/environment-variables/#deploy-urls-and-metadata netlify: extract([ "BUILD_ID", "CONTEXT", "URL", "DEPLOY_URL", "DEPLOY_PRIME_URL", "DEPLOY_ID" ]), // https://layerci.com/docs/layerfile-reference/build-env layerci: extract([ "LAYERCI_JOB_ID", "LAYERCI_RUNNER_ID", "RETRY_INDEX", "LAYERCI_PULL_REQUEST", "LAYERCI_REPO_NAME", "LAYERCI_REPO_OWNER", "LAYERCI_BRANCH", "GIT_TAG" // short hex for commits ]) }; }; var _providerCommitParams = () => { const { env } = process; return { appveyor: { sha: env.APPVEYOR_REPO_COMMIT, // since APPVEYOR_REPO_BRANCH will be the target branch on a PR // we need to use PULL_REQUEST_HEAD_REPO_BRANCH if it exists. // e.g. if you have a PR: develop <- my-feature-branch // my-feature-branch is APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH // develop is APPVEYOR_REPO_BRANCH branch: env.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH || env.APPVEYOR_REPO_BRANCH, message: join( "\n", env.APPVEYOR_REPO_COMMIT_MESSAGE, env.APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED ), authorName: env.APPVEYOR_REPO_COMMIT_AUTHOR, authorEmail: env.APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL // remoteOrigin: ??? // defaultBranch: ??? }, awsCodeBuild: { sha: env.CODEBUILD_RESOLVED_SOURCE_VERSION, // branch: ???, // message: ??? // authorName: ??? // authorEmail: ??? remoteOrigin: env.CODEBUILD_SOURCE_REPO_URL // defaultBranch: ??? }, azure: { sha: env.BUILD_SOURCEVERSION, branch: env.BUILD_SOURCEBRANCHNAME, message: env.BUILD_SOURCEVERSIONMESSAGE, authorName: env.BUILD_SOURCEVERSIONAUTHOR, authorEmail: env.BUILD_REQUESTEDFOREMAIL }, bamboo: { sha: env.bamboo_planRepository_revision, branch: env.bamboo_planRepository_branch, // message: ??? authorName: env.bamboo_planRepository_username, // authorEmail: ??? remoteOrigin: env.bamboo_planRepository_repositoryURL // defaultBranch: ??? }, bitbucket: { sha: env.BITBUCKET_COMMIT, branch: env.BITBUCKET_BRANCH // message: ??? // authorName: ??? // authorEmail: ??? // remoteOrigin: ??? // defaultBranch: ??? }, buildkite: { sha: env.BUILDKITE_COMMIT, branch: env.BUILDKITE_BRANCH, message: env.BUILDKITE_MESSAGE, authorName: env.BUILDKITE_BUILD_CREATOR, authorEmail: env.BUILDKITE_BUILD_CREATOR_EMAIL, remoteOrigin: env.BUILDKITE_REPO, defaultBranch: env.BUILDKITE_PIPELINE_DEFAULT_BRANCH }, circle: { sha: env.CIRCLE_SHA1, branch: env.CIRCLE_BRANCH, // message: ??? authorName: env.CIRCLE_USERNAME, // authorEmail: ??? remoteOrigin: env.CIRCLE_REPOSITORY_URL // defaultBranch: ??? }, codeshipBasic: { sha: env.CI_COMMIT_ID, branch: env.CI_BRANCH, message: env.CI_COMMIT_MESSAGE, authorName: env.CI_COMMITTER_NAME, authorEmail: env.CI_COMMITTER_EMAIL // remoteOrigin: ??? // defaultBranch: ??? }, codeshipPro: { sha: env.CI_COMMIT_ID, branch: env.CI_BRANCH, message: env.CI_COMMIT_MESSAGE, authorName: env.CI_COMMITTER_NAME, authorEmail: env.CI_COMMITTER_EMAIL // remoteOrigin: ??? // defaultBranch: ??? }, codeFresh: { sha: env.CF_REVISION, branch: env.CF_BRANCH, message: env.CF_COMMIT_MESSAGE, authorName: env.CF_COMMIT_AUTHOR }, drone: { sha: env.DRONE_COMMIT_SHA, // https://docs.drone.io/pipeline/environment/reference/drone-source-branch/ branch: env.DRONE_SOURCE_BRANCH, message: env.DRONE_COMMIT_MESSAGE, authorName: env.DRONE_COMMIT_AUTHOR, authorEmail: env.DRONE_COMMIT_AUTHOR_EMAIL, remoteOrigin: env.DRONE_GIT_HTTP_URL, defaultBranch: env.DRONE_REPO_BRANCH }, githubActions: { sha: env.GITHUB_SHA, branch: env.GH_BRANCH || env.GITHUB_REF, defaultBranch: env.GITHUB_BASE_REF, remoteBranch: env.GITHUB_HEAD_REF, runAttempt: env.GITHUB_RUN_ATTEMPT }, gitlab: { sha: env.CI_COMMIT_SHA, branch: env.CI_COMMIT_REF_NAME, message: env.CI_COMMIT_MESSAGE, authorName: env.GITLAB_USER_NAME, authorEmail: env.GITLAB_USER_EMAIL, remoteOrigin: env.CI_REPOSITORY_URL, defaultBranch: env.CI_DEFAULT_BRANCH }, googleCloud: { sha: env.COMMIT_SHA, branch: env.BRANCH_NAME // message: ?? // authorName: ?? // authorEmail: ?? // remoteOrigin: ??? // defaultBranch: ?? }, jenkins: { sha: env.GIT_COMMIT, branch: env.GIT_BRANCH // message: ??? // authorName: ??? // authorEmail: ??? // remoteOrigin: ??? // defaultBranch: ??? }, // Only from forks? https://semaphoreci.com/docs/available-environment-variables.html semaphore: { sha: env.SEMAPHORE_GIT_SHA, branch: env.SEMAPHORE_GIT_BRANCH, // message: ??? // authorName: ??? // authorEmail: ??? remoteOrigin: env.SEMAPHORE_GIT_REPO_SLUG // defaultBranch: ??? }, shippable: { sha: env.COMMIT, branch: env.BRANCH, message: env.COMMIT_MESSAGE, authorName: env.COMMITTER // authorEmail: ??? // remoteOrigin: ??? // defaultBranch: ??? }, snap: null, teamcity: null, teamfoundation: { sha: env.BUILD_SOURCEVERSION, branch: env.BUILD_SOURCEBRANCHNAME, message: env.BUILD_SOURCEVERSIONMESSAGE, authorName: env.BUILD_SOURCEVERSIONAUTHOR }, travis: { sha: env.TRAVIS_PULL_REQUEST_SHA || env.TRAVIS_COMMIT, // for PRs, TRAVIS_BRANCH is the base branch being merged into branch: env.TRAVIS_PULL_REQUEST_BRANCH || env.TRAVIS_BRANCH, // authorName: ??? // authorEmail: ??? message: env.TRAVIS_COMMIT_MESSAGE // remoteOrigin: ??? // defaultBranch: ??? }, wercker: null, netlify: { sha: env.COMMIT_REF, branch: env.BRANCH, remoteOrigin: env.REPOSITORY_URL }, layerci: { sha: env.GIT_COMMIT, branch: env.LAYERCI_BRANCH, message: env.GIT_COMMIT_TITLE } }; }; var _get = (fn) => { const providerName = getCiProvider(); if (!providerName) return {}; return import_lodash7.default.chain(fn()).get(providerName).value(); }; function checkForCiBuildFromCi(ciProvider) { if (ciProvider && detectableCiBuildIdProviders().includes(ciProvider)) return true; throw new ValidationError( `Could not determine CI build ID from the environment. Please provide a unique CI build ID using the --ci-build-id CLI flag or 'ciBuildId' parameter for 'run' method.` ); } function detectableCiBuildIdProviders() { return import_lodash7.default.chain(_providerCiParams()).omitBy(import_lodash7.default.isNull).keys().value(); } function getCiProvider() { return _detectProviderName() || null; } function getCiParams() { return _get(_providerCiParams); } function getCommitParams() { return _get(_providerCommitParams); } function getCI(ciBuildId) { const params = getCiParams(); const provider = getCiProvider(); if (!ciBuildId) checkForCiBuildFromCi(provider); debug8("detected CI provider: %s", provider); debug8("detected CI params: %O", params); return { params, provider }; } // lib/ciProvider/merge.ts var import_debug9 = __toESM(require("debug")); var import_lodash8 = __toESM(require("lodash")); var debug9 = (0, import_debug9.default)("currents:ci"); function getCommitDefaults(existingInfo) { debug9("git commit existing info"); debug9(existingInfo); const commitParamsObj = getCommitParams(); debug9("commit info from provider environment variables: %O", commitParamsObj); const combined = import_lodash8.default.transform( existingInfo, (memo, value, key) => { return memo[key] = import_lodash8.default.defaultTo( value || (commitParamsObj ? commitParamsObj[key] : null), null ); } ); debug9("combined git and environment variables from provider"); debug9(combined); return combined; } // lib/coverage/index.ts var import_promises = __toESM(require("fs/promises")); var import_path3 = require("path"); var getCoverageFilePath = async (coverageFile = "./.nyc_output/out.json") => { const path4 = (0, import_path3.join)(process.cwd(), coverageFile); try { await import_promises.default.access(path4); return { path: path4, error: false }; } catch (error2) { return { path: path4, error: error2 }; } }; // lib/cypress/cypress.ts var import_cypress = __toESM(require("cypress")); var import_debug10 = __toESM(require("debug")); var import_lodash9 = __toESM(require("lodash")); // lib/lang.ts var import_bluebird = __toESM(require("bluebird")); import_bluebird.default.Promise.config({ cancellation: true }); var BPromise = import_bluebird.default.Promise; var safe = (fn, ifFaled, ifSucceed) => async (...args) => { try { const r = await fn(...args); ifSucceed(); return r; } catch (e) { return ifFaled(e); } }; // lib/cypress/cypress.ts var debug10 = (0, import_debug10.default)("currents:cypress"); function runBareCypress(params = {}) { const p = { ...params, ciBuildId: void 0, tag: void 0, parallel: void 0, record: false, group: void 0, spec: import_lodash9.default.flatten(params.spec).join(",") }; debug10("Running bare Cypress with params %o", p); return import_cypress.default.run(p); } async function runSpecFile({ spec }, cypressRunOptions) { const runAPIOptions = getCypressRunAPIParams(cypressRunOptions); const options = { ...runAPIOptions, config: { ...runAPIOptions.config, trashAssetsBeforeRuns: false }, env: { ...runAPIOptions.env, currents_ws: getWSSPort() }, spec }; debug10("running cypress with options %o", options); let result = await import_cypress.default.run(options); let retries = 0; const currentsConfig = await getCurrentsConfig(); while (currentsConfig.retry && retries < (currentsConfig.retry.hardFailureMaxRetries ?? 0) && result.status === "failed") { warn("Cypress runner failed with message: %s", result.message); warn( "[retry %d/%d] Retrying the following spec files because of retry config: %s", retries + 1, currentsConfig.retry.hardFailureMaxRetries, spec.split(",").map((i) => ` - ${i}`).join("") ); result = await import_cypress.default.run(options); retries++; } if (currentsConfig.retry && retries > 0) { warn( "Exhausted max retries: %d/%d", retries, currentsConfig.retry.hardFailureMaxRetries ); } if (result.status === "failed") { warn('Cypress runner failed with message: "%s"', result.message); warn( "The following spec files will be marked as failed: %s", spec.split(",").map((i) => ` - ${i}`).join("") ); } debug10("cypress run result %o", result); return result; } var runSpecFileSafe = (spec, cypressRunOptions) => safe( runSpecFile, (error2) => { const message = `Cypress runnner crashed with an error: ${error2.message} ${error2.stack}}`; debug10("cypress run exception %o", error2); warn('Cypress runner crashed: "%s"', message); warn( "The following spec files will be marked as failed: %s", spec.spec.split(",").map((i) => ` - ${i}`).join("") ); return { status: "failed", failures: 1, message }; }, () => { } )(spec, cypressRunOptions); // lib/debug/index.ts var import_debug11 = __toESM(require("debug")); var import_ts_pattern3 = require("ts-pattern"); function activateDebug(mode) { (0, import_ts_pattern3.match)(mode).with(import_ts_pattern3.P.instanceOf(Array), (i) => i.forEach(setDebugMode)).with(true, () => setDebugMode("all" /* All */)).with( import_ts_pattern3.P.union( "all" /* All */, "currents" /* Currents */, "cypress" /* Cypress */, "commit-info" /* CommitInfo */ ), (i) => setDebugMode(i) ).otherwise(() => setDebugMode("none" /* None */)); } function setDebugMode(mode) { if (mode === "none" /* None */) { return; } const tokens = new Set(process.env.DEBUG ? process.env.DEBUG.split(",") : []); (0, import_ts_pattern3.match)(mode).with("all" /* All */, () => { tokens.add("commit-info" /* CommitInfo */); tokens.add("currents:*" /* Currents */); tokens.add("cypress:*" /* Cypress */); }).with("currents" /* Currents */, () => tokens.add("currents:*" /* Currents */)).with("cypress" /* Cypress */, () => tokens.add("cypress:*" /* Cypress */)).with("commit-info" /* CommitInfo */, () => tokens.add("commit-info" /* CommitInfo */)).otherwise(() => { }); import_deb